Crystal: Remove #length/#size/#count alias on Array etc

Created on 4 Sep 2015  Â·  16Comments  Â·  Source: crystal-lang/crystal

We seem to agree that we want to remove aliases, there are still some - most prominently Array#size and Array#length as well as #count. There is a discussion about removing the aliases:

I'm also thinking maybe we should only have size, count { ... } and count(obj) to remove all aliases (length would be gone, I think @jhass once suggested that size is better because it's shorter and easier to type). As always, I have to check this with @waj.

Imo #count is a bit different from size/length as it implicates that the collection is being traversed.

Use this issue to discuss whether or not to remove them please

Issue filed so it is not forgotten and relates to #1257 :)

Most helpful comment

Late to the party but would've strongly said +1 for length since size to me sounds like it could just as well be byte size and length is used in every single language I've programmed in...

.len() # Rust
.Length() # C#
.length # JavaScript
len(collection) # Python
length(list) # Elixir

Etc...

On the other hand in C, using sizeof is the byte size:

sizeof(array) / sizeof(array_type) // calculates length of array

I understand that Crystal wants to clean up some of the many ways to do thing available in Ruby, and that's probably a good thing... but I would still plead not to forgo the principle which is to me the most important design principle in the Ruby language itself - Principle of least surprise.

All 16 comments

I guess I wouldn't mind seeing length go, but if we let it go it should be radical, from all interfaces and even from all internal instance variable names.

Personally for some reason I like to use length for strings and size for collections. Happy to see either go still for the sake of the internal consistency of "no aliases" :)

I'd just keep:

  • size: because it's %w(size length count).min_by &.size :-P
  • count(object): to count occurrences of an object
  • count(&block): to count ocurrences of the elements that return true in the block

Like @jhass, I would remove count and length from everything. That means we'll only have Array#size, Hash#size, String#size and so on. Maybe it's also consistent in String because there's also String#bytesize.

Then Enumerable#size will traverse the collection to compute this value, but including classes can redefine this to provide better performance, like in the case of Array, Set, etc. There won't be an argless, non-block count method.

:+1: @asterite

+1 for size and naming consistency

Yeah I think it makes sense for to have #size and #count be different concepts, and to drop aliases.

+1 for #size, #count(obj) and #count(&block)

Best Regards,
Alexey Fedorov,
Sr Ruby, Clojure, Crystal, Golang Developer,
Microservices Backend Engineer,
+49 15757 486 476

2015-09-05 0:12 GMT+02:00 Will Leinweber [email protected]:

Yeah I think it makes sense for to have #size and #count be different
concepts, and to drop aliases.

—
Reply to this email directly or view it on GitHub
https://github.com/manastech/crystal/issues/1363#issuecomment-137866037.

I like using both size and count interchangeably, for different situations. Length could be ditched imo.

Late to the party but would've strongly said +1 for length since size to me sounds like it could just as well be byte size and length is used in every single language I've programmed in...

.len() # Rust
.Length() # C#
.length # JavaScript
len(collection) # Python
length(list) # Elixir

Etc...

On the other hand in C, using sizeof is the byte size:

sizeof(array) / sizeof(array_type) // calculates length of array

I understand that Crystal wants to clean up some of the many ways to do thing available in Ruby, and that's probably a good thing... but I would still plead not to forgo the principle which is to me the most important design principle in the Ruby language itself - Principle of least surprise.

@dbackeus good point, but note that there is #read vs #binread in Ruby. So there could be #size and #binsize if you want byte size.

Note that we have sizeof and there's String#bytesize

My point regarding Cs sizeof was just to show an example of how the word size tends to mean byte size rather than "number of elements" of something in other languages.

So the developer experience for people trying out Crystal might go something like:

  1. Try to get the number of elements of their first array by calling the ubiquitous length method
  2. Get a no method error
  3. Try to find the correct method using google or api docs
  4. Realise the correct method is size and then either think (if they have lots of experience with ruby) - "Oh they opted for the obscure size method from Ruby..." or (if they don't) be left wondering "Why would they call the method for getting number of elements size, which sounds like it would return the byte size of it?"

the obscure size method from Ruby

It's not obscure. 4 million uses of .size in ruby github projects vs. 3.4 million of .length.

In Ruby, String#size returns the character length of the string, just like in Crystal. Also, in Ruby there's String#bytesize and we have the same. I think I prefer this over filling the internet with these questions. Once you learn "Oh, it's just size" then you can start writing general algorithms like this one without having to worry about defining all those aliases in your collection types, nor wondering "why did she use count here?"). As a bonus, you get to type less and make less typos (I sometimes write lentgh or lenght but never make mistakes with size).

Finally, there's no sizeof in Ruby so that can't cause a confusion, plus sizeof only accepts types.

@asterite Just want to clearly put my point again since the counter arguments seem to miss it: I do think it's a good idea to have only one "number of items / characters" method, just trying to explain why length seems a better choice to me. Which is that it would follow principle of least surprise for majority of programmers (weather ruby programmers or not). In Ruby there is File.size which returns byte size of file so we don't have to use sizeof as an example of how the word size gets associated with byte size. That said I still respect your decision here to design for ease of typing rather than principle of least surprise / clarity of intent.

@will though it could very well be that more people use size than I expect (ex Smalltalk programmers for example, which is the only other programming language I found not using length)... I don't think that comparison makes sense since we don't know which of those method calls are actually done on strings/enumerables and which are called on other objects/classes (there are more size methods defined in stdlib than length methods, and who knows what happens in gems etc out there).

@dbackeus - even though I "voted" for ditching length, I must agree, that's kind of the "universal" method/accessor name in most languages I've crossed paths with. I've never misspelled length btw ;-)

Was this page helpful?
0 / 5 - 0 ratings