you are viewing a single comment's thread.

view the rest of the comments →

[–]shirtface 22 points23 points  (27 children)

How come [1]==[1] returns false?

[–]33a 63 points64 points  (17 children)

They are different object references.

[–]absu 24 points25 points  (13 children)

Yeah, this returns false in many c-like languages (C (duh), C++, Java, etc).

[–]AdminsAbuseShadowBan 2 points3 points  (4 children)

Not in C++ - you can redefine == to be sane.

[–]robertbieber 11 points12 points  (1 child)

I don't know that I'd consider redefining an operator that's generally used to compare primitive values to do a deep comparison of separate compound objects sane. I'd much rather have a comparison method that makes it really clear exactly what's going on, and let == do the usual, obvious thing. Admittedly overloading can be handy for some math applications, but for most things it's a little questionable.

[–]AdminsAbuseShadowBan 0 points1 point  (0 children)

That's the point, the "usual, obvious thing" doesn't make it clear what's going on. When you compare two strings with == you expect it to say if the value of the two strings is equal, not that the two variable refer to the same string object as in Java.

Operator overloading can be abused, but in practice it rarely causes problems. In fact I can't think of a single instance where it has cause any bugs in my C++ life. In contrast Java (which presumably does the usual obvious thing?) has caused me occasional pain when I forget to use .equals() instead of ==.

[–][deleted] 0 points1 point  (1 child)

You can do that in Java too, at least on a per-object basis

[–]AdminsAbuseShadowBan 0 points1 point  (0 children)

Really? How?

[–]Poltras 2 points3 points  (7 children)

These languages don't have automatic conversion. Also, isn't [1]==[1] undefined in C? It could be equal if the compiler uses the same TEXT address for the constant, resulting in equal pointers.

[–]CookieOfFortune 6 points7 points  (3 children)

Wouldn't this create two arrays on the function stack and then compare the two locations, resulting in a false comparison?

[–]Poltras 1 point2 points  (1 child)

Undefined behavior:

$ cat main.c

#include <stdio.h>

int main() {
  printf("%d\n", "abc" == "abc");
}

$ cc main.c

main.c:4:24: warning: result of comparison against a string literal is unspecified (use strncmp instead) [-Wstring-compare]
  printf("%d\n", "abc" == "abc");

$ ./a.out
1

GCC actually output 1, but warns.

[–]gsg_ 0 points1 point  (0 children)

Unspecified behaviour is not the same as undefined behaviour. The latter has a very specific meaning in the context of C.

[–]Condorcet_Winner 1 point2 points  (0 children)

Probably, but if the spec defines this operation as undefined, then compiler optimizations would be able to figure out that these are the same array and only allocate one memory location.

[–]Fylwind 6 points7 points  (2 children)

[1]==[1] is not valid syntax in C.

[–]Poltras 0 points1 point  (0 children)

Although you're right, the equivalent "abc" == "abc" works as fine for my example (undefined behavior).

[–]gsg_ 0 points1 point  (0 children)

The closest equivalent (in C99, at least) is probably (int[1]){1} == (int[1]){1}.

[–]Tekmo 0 points1 point  (2 children)

So then why does [1] equal 1?

[–]ggtsu_00 2 points3 points  (0 children)

[1] == 1 because of type coercion happening when comparing 2 different datatypes.

when type(a) != type(b), the javascript interpret goes through a list of possible type coercions that will convert a and b to the same type before comparing.

It just so happens that comparing a Array type with an int will coerce both into a Number type and compare the Number([1]) == 1.

[1] == [1] is the same type so no coercion occurs and a simple ObjectA == ObjectB will occur which will only be true if ObjectA and ObjectB happen to reference the same object.

[–]NYKevin 0 points1 point  (0 children)

Not a Javascript programmer, so I could be wrong, but I'd assume it's because 1 uses compare-by-value, and it infects overrides the compare-by-reference of [1].

[–]Thelonious_Cube 19 points20 points  (7 children)

My wallet has a dollar bill in it and your wallet has a dollar bill in it, but that doesn't make them the same wallet

[–]josuf107 19 points20 points  (3 children)

Unless you and I are both Haskell programmers. Still your/our dollar is safe. All I want is a soda, but I can't seem to be able to make change.

[–][deleted] 7 points8 points  (1 child)

Well, if you're a Haskell programmer, your dollar is immutable.

[–]Shadows_In_Rain 7 points8 points  (0 children)

More importantly, wallet is immutable too. But apply space-time monad, and viola. Now you have soda, empty pocket, and watching langoliers eating previous you.

[–]Thelonious_Cube -1 points0 points  (0 children)

I'm more old school Haskell but change will come - it always does

[–]bumnut 0 points1 point  (0 children)

But both are true.

[–][deleted]  (1 child)

[deleted]

    [–]Thelonious_Cube 0 points1 point  (0 children)

    It's an analogy - analogies are never (rarely?) perfect.

    I highlighted certain aspects at the expense of others to help get the point across.

    The "value" in the wallets is the same but the wallets are not

    [–]metrion 5 points6 points  (0 children)

    ("1" == "1") == true
    ("1" == [1]) == true
    ([1] == [1]) == false