==, equals and ===

22 views
Skip to first unread message

Nick Howard

unread,
Feb 17, 2015, 12:02:18 PM2/17/15
to mi...@googlegroups.com
I'm working on a patch for making == an alias for the equals method for objects, and making ===/!== the reference equality operator. Since this is a pretty major change I was wondering if the list has any questions / thoughts.

More details:

== will be implemented with a macro that includes a null check and an equals call.

Different handling of primitives isn't something I've done yet, but what I was thinking was that == could remain coercive, while making === not. So, if you try to === a float and an int, it would be a compilation error.

As a practical matter, most usages of == shouldn't have to change--Java defines equals as defaulting to reference equality, so for classes without equals definitions the expressions should be equivalent. For other cases, it'll widen the states where the expression is true, which could cause problems if the code makes assumptions about it.

If the == expression is inside an equals method definition, and it's comparing against self, for now, it'll be transformed into a === call, and the compiler will output a warning. This is to prevent currently working code from failing to compile in the short term, while things are still being shaken out. I think later, we could make that an error.

Future related work:

* defining '==' as a method should create an equals method
* creating default equals methods for mirah created classes based on fields.

--

Steve Hannah

unread,
Feb 17, 2015, 12:16:32 PM2/17/15
to mi...@googlegroups.com
I saw your tweets on this last night.  My first reaction was "uh oh, here we go down the dark '==' rabbit hole towards Javascript".  But after thinking about it some more, I like this change.  Most of the time, when I'm using '==' in Java, I either mean it to do equals(), or I would be fine if it did equals.   E.g. str == "foo" is much nicer to code than "foo".equals(str).

--
You received this message because you are subscribed to the Google Groups "The Mirah Programming Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mirah+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Steve Hannah
Web Lite Solutions Corp.

Ryan Brown

unread,
Feb 17, 2015, 1:45:54 PM2/17/15
to mi...@googlegroups.com
Isn't === generally more accepting than == in ruby? Maybe we should use === for .equals()? That way we also won't break anything. But then again .equals() is probably what is usually mean, so maybe it is better to use as the default? I'm not sure.

Nick Howard

unread,
Feb 17, 2015, 1:47:55 PM2/17/15
to mi...@googlegroups.com
That's my thinking behind this change. In Ruby, == has the same meaning for numbers, instances of classes--everything. It's a method call, and is used for comparing values. In Java == is either a way to compare values of primitive numbers or a way to compare the identity of references. I think those are subtly different concepts and should look different.

I think the == / equals difference is one of the tricky things to learn as a new comer to Java, and I don't want people learning Mirah to have to run into it if it's avoidable.

Nick Howard

unread,
Feb 17, 2015, 1:50:21 PM2/17/15
to mi...@googlegroups.com
Ryan,

=== is special in Ruby. It is the "whatever this should do when an argument to 'when' in a case expression". I think it's ok for Mirah to not think of === that way. My impression is that most Rubyists don't take advantage of that particular hook.

I'd like to have a hook like that when we implement case expressions, but I don't think it has to be the same one as Ruby's.

Raum Dellamorte

unread,
Feb 17, 2015, 9:20:32 PM2/17/15
to mi...@googlegroups.com
As I recall, ruby === works like Java == such that
a = Foo.new(1)
b
= a
c
= Foo.new(1)
a
=== b # => true
a
=== c # => false
a
== c  # => true



Reversing them for Mirah would avoid legacy code breakage such that
a = Foo.new(1)
b
= a
c
= Foo.new(1)
a
== b  # => true
a
== c  # => false
a
=== c # => true



Think about someone converting Java to Mirah and having to change all the == to === when it should be left as is for the same functionality.  foo === bar is still more convenient than foo.equals(bar).  Much less dangerous a proposal to just mirror (reverse) that behaviour of ruby in Mirah :)

Nick Howard

unread,
Feb 17, 2015, 11:11:32 PM2/17/15
to mi...@googlegroups.com

Actually, Ruby's behavior for === is pretty unusual. It isn't equality per se, instead it's the method that's invoked on arguments to when's in case expressions. I.e., Class's === does a kind_of? check, and regex's calls match.

    case foo
    when Foo then puts "a Foo"
    when /[a-z]*/ then puts "lower case"
    else puts "misc"
    end

While I really want a good case syntax for Mirah, I think it's going to have to work differently from Ruby's, and I want that to be clear by changing the name of the callback for it.

In Java code I've read, == is sometimes, perhaps even frequently misused, particularly with strings. Maybe I've been reading too much java written by people use to languages where == compares values :-).

Also the first statement in most equals implementations tends to be checking for reference equality and the default implementation only checks for it. Because of that, I think the effect will be fairly small.

The cases that aren't covered are these:
- when you want to fail the check when the identity is different, but the value is the same.
- When you are checking references against self in an equals definition.

My thought is that the first case is relatively infrequent, and for the second, I'm adding a warning, and falling back to the old behavior at least for next release.

--

J. Scott Kasten

unread,
Feb 18, 2015, 7:40:19 AM2/18/15
to mi...@googlegroups.com
Hi guys,

I'm jumping in perhaps a bit late, but had a couple of thoughts worth pondering in the debate.

First off, who exactly are Mirah's users? I've heard some noises that Mirah isn't Ruby. But I have to say it's not Java either. In the end, it is it's own thing, which is what makes me ask the first question. Who is Mirah for? In my case, I was drawn to Mirah because it goes places Ruby doesn't - namely the Dalvik VM, and may perform better in some use cases where Ruby is known to have issues. What is the value proposition for Java people? To port Ruby code to their platform? I'm not clear on that one. We have to be clear on this point to make good steering decisions based on fundamental value propositions.

Second, there is another take on this whole == vs === thing. As programmers will, much of this argument is based on some low level technical pulling something apart kind of analysis. I would like to offer a higher level philosophical thought.

From 50,000 feet, the primary difference between == and === in Ruby is that == compares things of the same type, or between types for which there are strict promotion rules. I.E. fixnum vs Bignum.. Float vs double. Maybe Int vs Float in some cases. The === operator allows for meaningful comparisons between different, but related types. I.E. string vs Regex. Int vs Range, etc...

Just my 2 cents.

Cheers,

-S-
--
Sent from my Android device.
Reply all
Reply to author
Forward
0 new messages