An 'in' operator for Ruby
rubyhacker.com
rubyhacker.com
https://github.com/rails/rails/blob/d61baee52adcd1baebe15f10...
You're welcome to try and merge that into Ruby core itself. That said, "I like whitespace" isn't a good reason to add a new operator over a method. Ruby is object oriented, meaning you are calling methods on objects.
if x.in? my_set # very ugly
With that said, I personally don't agree with the post.I wouldn't call the method "in?" but maybe "element_of?" or "member_of?" but besides that, I don't see the need for an operator.
What I love about ruby is its focus on making programming delightful rather than adhering to weird ass rules like 'Ruby is object oriented, meaning you are calling methods on objects.' that people pretend are laws of physics when really you can break them anytime you want, unlike laws of physics.
Similar to the way you can write
def foo
"bar"
end
instead of class Kernel
def foo
"bar"
end
endGenerally speaking, Ruby eschews syntax that invokes a protocol behind the scenes for a consistent 1:1 mapping between method syntax and the methods they invoke.
I was taught to never trust the ordering returned by iterating over keys of hashmaps because it can be a source of bugs as you move between architectures or interpreters. If you need a guaranteed ordering, keep (and pay for) the appropriate auxiliary data structure.
Has this lesson become obsolete? Perhaps "computers are fast" so now Ruby can afford to use ordered hashmaps everywhere. On the other hand, I know Go chose to randomize iteration order of keys on purpose so developers cannot rely on them.
I guess there are two approaches to solving the problem of people using your data structures the wrong way.
Edit: wrong link
> When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next. Since Go 1 the runtime randomizes map iteration order, as programmers relied on the stable iteration order of the previous implementation.
The implementation of a ruby hash is now as a doubly linked list [0]. This has inevitably caused a slight performance hit, but the benefits far outweigh the cost IMO.
[0] https://www.igvita.com/2009/02/04/ruby-19-internals-ordered-...
Having said that, I don't agree that it needs to be an operator over a method. I agree that it would be prettier, but methods provide additional benefits like being easy to override or pass as arguments to other methods (like :respond_to?). If you're ok with a method, you can easily monkey patch ruby to support an `in` (or `in?`) method yourself.
> But we also -- perhaps more often? -- ask questions like "Is this item part of this group?" We are asking a question about the item.
Here we are actually asking the group a question about itself. An item would not know a group's contents.
But people love operators, that's why Ruby already includes loads of them instead of giving them identifier names and requiring you to call them with a dot. You have x+y instead of x.plus y, x==y instead of x.equals? y, x<y instead of x.less_than? y, most people write x..y instead of Range.new(x,y), etc. I don't think most Ruby programmers or the language designers agree with you about not wanting operators.
> if ! (item in collection) # ok
Riiiiiiiight. No more language suggestions from you, thanks ;)
> if item not in collection
reads quite nicely. I don't see what the problem is there? Anyway, I don't think his one gripe with this is enough reason to throw the rest of his argument out.
its easier to miss a ! than a 'not' at a quick glance
Obviously is the best choice
he should have suggested
if not item in collection
which should then work out of the box anyways
[I completely agree with the need for the 'in' operator]
if x.in? my_set # very ugly
I guess we disagree there. This is arguably more readable than most languages with `in?` being still just a method.Perhaps another way of doing this is calling the method .within?
I personally wouldn't be in favor of it.
Addition: Arguing that "Ruby isn't English" and then stating conformity to mathematical notation as a benefit seems hypocritical. Programming languages (besides APL, maybe) do not use strict mathematical notation, and we shouldn't want them to.
And as he points out, 'in' is already a keyword anyway - so if it makes a more readable way of doing things, then why not?
I do disagree with the author on one point: 'not in' should also be a valid operator, representing '∉'.
But I don't use Ruby; I mostly use Python, which has these operators.
I can't think of any modern programming language that isn't unicode aware even though for the standard library methods, there are very good reasons not to use them (I know, Perl 6 does but even in this case there are ASCII fallbacks).
You should also have very good reasons to put methods on the root class of your class hierarchy.
Making it easy for people to type them, on the other hand...
That's a problem of the code editors people are using. ;-)
I'm often surprised with how dysfunctional editors people are programming.
For example if all editors would show tabs and spaces (or whitespace in general) in a reasonable way, we wouldn't have had that much pointless discussion about the correct indentation whitespace character.
An immediate example that comes to mind is Python's use of None, rather than null (like in Java/JavaScript). I remember speaking in Dutch about Java in college was always slightly awkward, because it was easy to confuse "null" with 0 (or "nul"). I wonder if Guido (being Dutch) called the Python void type "None" on purpose, to avoid awkwardness when speaking about it in Dutch.
x not in y
and instead propose: !(x in y)
Seems like a zero-sum addition to the language to me.To cite an alternatice, in Tcl, `in` is an operator and its negation is `ni`. A cute pun and echo of Monty Python that I'm disappointed Python didn't follow :).
As to the "what else resembles this"? I would turn it around and ask what else could resemble this. I'm not sure the conclusion would be that "not in" is a good thing, but not sure of the reverse, either:
if x not = 3
looks weird, but I think I could grow to like it.Really '!=' is just an attempt at rendering '≠' using only ASCII characters. They're a bit like digraphs and trigraphs in C/C++, except everyone is used to them.
I wonder if Unicode is ubiquitous enough now that you could write a language where the real maths operators were used instead. What would that look like?
I'm currently using the Monoid font (https://larsenwork.com/monoid/), which uses ligatures to achieve the visual effect of things like the not equals symbol, while the underlying code remains the same. It's a pretty nice work-around for current languages.
Ruby has a place for this sort of thing and they'll answer you.
Matz: I am neutral for this proposal.
... ...
Matz: This proposal is only for cosmetics. I don't want a new operator that does not introduce something new.
[I personally disagree and think the 'in' operator should be added]
The fact that the Ruby method is called include? and not includes? is annoying though.
because it's Japanese https://www.new-bamboo.co.uk/blog/2010/12/17/learning-japane...
https://en.wikipedia.org/wiki/AppleScript
It doesn't work out very well in practice. Inevitably the syntax diverges, and then it's pretty confusing for the novice user: why do some sentences work but most don't?
To be clear, 10...100 includes 10, but not 100. So, it includes one bound: the one mentioned first, the lower bound.
(10...100).to_a
=> [10, 11, 12, 13, ... 98, 99] [1] pry(main)> 10..100
=> 10..100
[2] pry(main)> (10..100).class
=> Range
[3] pry(main)> (10..100).to_a
=> [10, 11, 12, 13, 14, ..., 99, 100]