Object.eq is ready for discussion

# Mark S. Miller (15 years ago)

strawman:egal

I have previously taken the position on this list that we should not add a third equality construct to JavaScript. However, it is relevant to several other strawmen that are likely to advance -- hasCode, Maps and Sets. Also, its absence repeatedly bites me. I often accidentally code === when I mean Object.eq because it's so hard to remember when ==='s brokenness matters. Nevertheless, I am still ambivalent about adding it as standard equipment. Opinions?

It is also on the agenda for the upcoming meeting.

# Maciej Stachowiak (15 years ago)

On Sep 5, 2010, at 7:40 AM, Mark S. Miller wrote:

strawman:egal

I have previously taken the position on this list that we should not add a third equality construct to JavaScript. However, it is relevant to several other strawmen that are likely to advance -- hasCode, Maps and Sets. Also, its absence repeatedly bites me. I often accidentally code === when I mean Object.eq because it's so hard to remember when ==='s brokenness matters. Nevertheless, I am still ambivalent about adding it as standard equipment. Opinions?

I think it's nearly mandatory, as the equivalence relation paired with Object.hashcode. A hash function is only meaningful in the context of an equivalence relation.

Other possibilities:

  • Make Object.hashcode pair with === or == instead of Object.eq: formally impossible, because neither is actually an equivalence relation. Less formally, possible at the cost of making it impossible to use NaN as a hash key, or distinguish 0 from -0 as hash keys.

  • Make Object.hashcode correspond to an equivalence relation that is described but not provided as a predefined function - now actually using hashcode becomes needlessly complicated and error prone.

It might even be desirable to name Object.hashcode something that makes the relationship to eq clear - Object.eqHash? On the other hand, it seems somewhat unlikely that other hash/equivalence pairs will be introduced to the standard, so maybe it doesn't matter.

, Maciej

# Brendan Eich (15 years ago)

On Sep 5, 2010, at 8:28 AM, Maciej Stachowiak wrote:

Other possibilities:

  • Make Object.hashcode pair with === or == instead of Object.eq: formally impossible, because neither is actually an equivalence relation. Less formally, possible at the cost of making it impossible to use NaN as a hash key, or distinguish 0 from -0 as hash keys.

=== is an ER ignoring NaN (0 and -0 are in the same equivalence class, but whether this is a bug or a feature depends on imponderables; arguably -0 is a bug outside of numerical applications).

  • Make Object.hashcode correspond to an equivalence relation that is described but not provided as a predefined function - now actually using hashcode becomes needlessly complicated and error prone.

This was the consensus (not a strong one) last time we discussed.

It might even be desirable to name Object.hashcode something that makes the relationship to eq clear - Object.eqHash? On the other hand, it seems somewhat unlikely that other hash/equivalence pairs will be introduced to the standard, so maybe it doesn't matter.

The "eq" name is freakishly short, which might up the odds of it not colliding with existing user-level extensions to Object (egal might work as well in that regard), but we already heard from people objecting to Object.keys vs. Object.getOwnPropertyNames.

The strawman has a note where I suggested matching "hashcode" with "identity" as the method name. If nothing else, the name length and lack of hackerly abbreviation recommend it. Comments?

# Sam Ruby (15 years ago)

On Sun, Sep 5, 2010 at 3:28 PM, Brendan Eich <brendan at mozilla.com> wrote:

The "eq" name is freakishly short, which might up the odds of it not colliding with existing user-level extensions to Object

api.jquery.com/eq

  • Sam Ruby
# Maciej Stachowiak (15 years ago)

On Sep 5, 2010, at 12:28 PM, Brendan Eich wrote:

On Sep 5, 2010, at 8:28 AM, Maciej Stachowiak wrote:

Other possibilities:

  • Make Object.hashcode pair with === or == instead of Object.eq: formally impossible, because neither is actually an equivalence relation. Less formally, possible at the cost of making it impossible to use NaN as a hash key, or distinguish 0 from -0 as hash keys.

=== is an ER ignoring NaN (0 and -0 are in the same equivalence class, but whether this is a bug or a feature depends on imponderables; arguably -0 is a bug outside of numerical applications).

That is what I meant by their failure to be an equivalence relation. If you ignore that issue, then you'll be able to put an arbitrary number of different 'NaN'-keyed values in a hashtable based on hashcode, but will never be able to retrieve or remove any of them. Possibly obscure, but seems like a bad consequence if it does happen.

  • Make Object.hashcode correspond to an equivalence relation that is described but not provided as a predefined function - now actually using hashcode becomes needlessly complicated and error prone.

This was the consensus (not a strong one) last time we discussed.

It seems like this would significantly increase the odds of data structures built using Object.hashcode and ===, which would result in brokenness. You could get separate entries for '0' and '-0' (since they would hash differently) but later rehashing could cause lookup to find the wrong one. I think the responsible thing to do is to actually expose the equivalence relation that matches hashcode, instead of hoping that everyone bothers to handcode it.

It might even be desirable to name Object.hashcode something that makes the relationship to eq clear - Object.eqHash? On the other hand, it seems somewhat unlikely that other hash/equivalence pairs will be introduced to the standard, so maybe it doesn't matter.

The "eq" name is freakishly short, which might up the odds of it not colliding with existing user-level extensions to Object (egal might work as well in that regard), but we already heard from people objecting to Object.keys vs. Object.getOwnPropertyNames.

The strawman has a note where I suggested matching "hashcode" with "identity" as the method name. If nothing else, the name length and lack of hackerly abbreviation recommend it. Comments?

I would expect a function named "identity" to be a function of one argument that returns it unmodified, rather than a two-argument predicate that implements an equivalence relation. "eq" seems like an ok name. "egal" will probably seem more mysterious than "eq".

, Maciej

# Maciej Stachowiak (15 years ago)

On Sep 5, 2010, at 1:08 PM, Sam Ruby wrote:

On Sun, Sep 5, 2010 at 3:28 PM, Brendan Eich <brendan at mozilla.com> wrote:

The "eq" name is freakishly short, which might up the odds of it not colliding with existing user-level extensions to Object

api.jquery.com/eq

I don't think this would be a conflict, since that eq method is on jQuery objects, not on the Object global constructor like the proposed 'Object.eq'.

, Maciej

# Jürg Lehni (15 years ago)

I would propose to name it Object.equals() as opposed to the unnecessary short eq(), which does not seem right next to unnecessarily verbose function names such as Object.getOwnPropertyDescriptor()

Juerg

# Maciej Stachowiak (15 years ago)

On Sep 5, 2010, at 5:49 PM, Jürg Lehni wrote:

I would propose to name it Object.equals() as opposed to the unnecessary short eq(), which does not seem right next to unnecessarily verbose function names such as Object.getOwnPropertyDescriptor()

"equals" or "equal" would be ok by me. eq is in line with Lisp tradition where the most discriminating equality operator is callsed "eq" or "eq?", but most JavaScripters would likely fail to catch the reference.

, Maciej

# Brendan Eich (15 years ago)

On Sep 5, 2010, at 5:33 PM, Maciej Stachowiak wrote:

On Sep 5, 2010, at 1:08 PM, Sam Ruby wrote:

On Sun, Sep 5, 2010 at 3:28 PM, Brendan Eich <brendan at mozilla.com> wrote:

The "eq" name is freakishly short, which might up the odds of it not colliding with existing user-level extensions to Object

api.jquery.com/eq

I don't think this would be a conflict, since that eq method is on jQuery objects, not on the Object global constructor like the proposed 'Object.eq'.

Still, it's another use of 'eq', which could be confusing.

I'm not sure what the best name is, but I'm pretty sure it is longer.

# Jeff Walden (15 years ago)

On 09/05/2010 08:31 PM, Maciej Stachowiak wrote:

The strawman has a note where I suggested matching "hashcode" with "identity" as the method name. If nothing else, the name length and lack of hackerly abbreviation recommend it. Comments?

I would expect a function named "identity" to be a function of one argument that returns it unmodified, rather than a two-argument predicate that implements an equivalence relation. "eq" seems like an ok name. "egal" will probably seem more mysterious than "eq".

Object.identical seems to imply the right things, certainly better than Object.identity. To the extent I want to get involved in this paint job, I think this is the best shade I've considered.

Object.equals is reasonable, although as I assume people read (=)== as (strictly) equals, reusing the "equals" name seems like a mistake to me, if potentially one of small import (or not, I don't have much faith in my ability to predict this future, so would play it safe and avoid the name).

Object.eq, put bluntly, is obthcure.

Object.egal would just be confusing for ECMAScript.

# Mark S. Miller (15 years ago)

On Mon, Sep 6, 2010 at 12:30 PM, Jeff Walden <jwalden+es at mit.edu<jwalden%2Bes at mit.edu>

wrote:

On 09/05/2010 08:31 PM, Maciej Stachowiak wrote:

The strawman has a note where I suggested matching "hashcode" with

"identity" as the method name. If nothing else, the name length and lack of hackerly abbreviation recommend it. Comments?

I would expect a function named "identity" to be a function of one argument that returns it unmodified, rather than a two-argument predicate that implements an equivalence relation. "eq" seems like an ok name. "egal" will probably seem more mysterious than "eq".

Object.identical seems to imply the right things,

I think Object.identical is great. It is short enough. For those perturbed by "freakishly short names"[*] it is long enough. It is even more clearly distinct from the existing equality constructs than any of "eq", "egal" or "equals". And most of all it is correct. Object.identical(x,y) implies that x and y are observably indistinguishable. An equally accurate choice would be "indistinguishable" but I don't like it. For one thing, Object.indistinguishable(x,y) is too long for a construct we should encourage.

[*] I do not understand this objection. So my second choice remains "Object.eq".

# Brendan Eich (15 years ago)

On Sep 6, 2010, at 9:51 AM, Mark S. Miller wrote:

For those perturbed by "freakishly short names"[*] it is long enough. It is even more clearly distinct from the existing equality constructs than any of "eq", "egal" or "equals". And most of all it is correct. Object.identical(x,y) implies that x and y are observably indistinguishable. An equally accurate choice would be "indistinguishable" but I don't like it. For one thing, Object.indistinguishable(x,y) is too long for a construct we should encourage.

[*] I do not understand this objection. So my second choice remains "Object.eq".

No offense, freakishly short was in relation to the other names in the standard. We don't find too many abbreviations after "eval", especially in ES5. As noted, we get some long names that are hard to shorten, and some shorties ("keys", notably) that are hard to lengthen even if they seem named according to a different naming philosophy.

Specifically, nouns such as "keys" and "values" make for short names, but most of the names in the standard library are verb-and-object-noun-phrase kinds of names.

"eq" is a fine name in a vacuum, but against the prevailing naming conventions, plural, it doesn't fit.

# Maciej Stachowiak (15 years ago)

On Sep 6, 2010, at 9:30 AM, Jeff Walden wrote:

On 09/05/2010 08:31 PM, Maciej Stachowiak wrote:

The strawman has a note where I suggested matching "hashcode" with "identity" as the method name. If nothing else, the name length and lack of hackerly abbreviation recommend it. Comments?

I would expect a function named "identity" to be a function of one argument that returns it unmodified, rather than a two-argument predicate that implements an equivalence relation. "eq" seems like an ok name. "egal" will probably seem more mysterious than "eq".

Object.identical seems to imply the right things, certainly better than Object.identity. To the extent I want to get involved in this paint job, I think this is the best shade I've considered.

Object.identical is a good name.

# Jürg Lehni (15 years ago)

I agree it's a good name, but how about Object.isIdentical? Wouldn't that follow existing naming conventions more closely?

Juerg

# Brendan Eich (15 years ago)

On Sep 6, 2010, at 4:01 PM, Jürg Lehni wrote:

I agree it's a good name, but how about Object.isIdentical? Wouldn't that follow existing naming conventions more closely?

It would following the verg-object-noun-phrase convention, but we have more than one convention.

Note how isNaN(x) and isFinite(x) are functions taking one parameter. Whereas Object.identical(a, b) tests whether two values are identical. Does "is" work still? Could we dodge the issue (as well as the implied preposition "to": isIdenticalTo) by using Jeff's "identical" suggestion?

A pure OOP (single receiver) naming convention as in Smalltalk might favor a isIdenticalTo: b (if it didn't use an operator symbol, as IIRC Smalltalk did: ==), but Object.identical is really a function (static method of Object, simply to avoid name pollution in any other object). Object.identical(a, b) seems better to me than any longer name involving "is" and/or "To".

For single-parameter tests, "is" or "has" followed by a NounPhrase is indeed the dominant naming convention. For a dyadic function to pair with Object.hashcode, Object.identical still seems best to me. The only other verb-free thought is to use the language in the ES5 spec (9.12) and call it Object.sameValue.

# Kevin Curtis (15 years ago)

With a module system it could be useful to have a module for the 'meta' functions - rather than putting more 'static class methods' on Object. (Especially with module import - keys, values, eq etc - would be nice to access these directly).

Though I appreciate that modules may be some way off - and the Object.eq function - as it's api - can be rolled out quite easily.

How about some interim method of getting access to 'native' modules: "use strict modules={meta, sys:Sys}" // destructuring notation from simple modules if (!meta) { ... workaround ... } if (meta.eq(x,y)) { ... do something ... }

# Jürg Lehni (15 years ago)

On 7 Sep 2010, at 02:01, Brendan Eich wrote:

It would following the verg-object-noun-phrase convention, but we have more than one convention.

Note how isNaN(x) and isFinite(x) are functions taking one parameter. Whereas Object.identical(a, b) tests whether two values are identical. Does "is" work still? Could we dodge the issue (as well as the implied preposition "to": isIdenticalTo) by using Jeff's "identical" suggestion?

Maybe one could argue that Object.isIdentical(a, b) is the generic version of non-existing a.isIdentical(b) ?

Juerg

# Maciej Stachowiak (15 years ago)

On Sep 6, 2010, at 6:01 PM, Brendan Eich wrote:

On Sep 6, 2010, at 4:01 PM, Jürg Lehni wrote:

I agree it's a good name, but how about Object.isIdentical? Wouldn't that follow existing naming conventions more closely?

It would following the verg-object-noun-phrase convention, but we have more than one convention.

Note how isNaN(x) and isFinite(x) are functions taking one parameter. Whereas Object.identical(a, b) tests whether two values are identical. Does "is" work still? Could we dodge the issue (as well as the implied preposition "to": isIdenticalTo) by using Jeff's "identical" suggestion?

A pure OOP (single receiver) naming convention as in Smalltalk might favor a isIdenticalTo: b (if it didn't use an operator symbol, as IIRC Smalltalk did: ==), but Object.identical is really a function (static method of Object, simply to avoid name pollution in any other object). Object.identical(a, b) seems better to me than any longer name involving "is" and/or "To".

For single-parameter tests, "is" or "has" followed by a NounPhrase is indeed the dominant naming convention. For a dyadic function to pair with Object.hashcode, Object.identical still seems best to me. The only other verb-free thought is to use the language in the ES5 spec (9.12) and call it Object.sameValue.

You could make it Object.areIdentical(a, b), but I don't think that reads very well.

, Maciej

# Jorge (15 years ago)

On 07/09/2010, at 11:39, Maciej Stachowiak wrote:

On Sep 6, 2010, at 6:01 PM, Brendan Eich wrote:

On Sep 6, 2010, at 4:01 PM, Jürg Lehni wrote:

I agree it's a good name, but how about Object.isIdentical? Wouldn't that follow existing naming conventions more closely?

It would following the verg-object-noun-phrase convention, but we have more than one convention.

Note how isNaN(x) and isFinite(x) are functions taking one parameter. Whereas Object.identical(a, b) tests whether two values are identical. Does "is" work still? Could we dodge the issue (as well as the implied preposition "to": isIdenticalTo) by using Jeff's "identical" suggestion?

A pure OOP (single receiver) naming convention as in Smalltalk might favor a isIdenticalTo: b (if it didn't use an operator symbol, as IIRC Smalltalk did: ==), but Object.identical is really a function (static method of Object, simply to avoid name pollution in any other object). Object.identical(a, b) seems better to me than any longer name involving "is" and/or "To".

For single-parameter tests, "is" or "has" followed by a NounPhrase is indeed the dominant naming convention. For a dyadic function to pair with Object.hashcode, Object.identical still seems best to me. The only other verb-free thought is to use the language in the ES5 spec (9.12) and call it Object.sameValue.

You could make it Object.areIdentical(a, b), but I don't think that reads very well.

Or even

Object"==="

:-))

(I like Object.eq(), it makes the code shorter. Or even Object.isEq())

# Asen Bozhilov (15 years ago)

Mark S. Miller:

strawman:egal [...] Opinions?

How about:

Object.compare(x, y);

I think this is enough meaningful and solve the problem with third party naming collisions. I would like to see `compare' method with more than two arguments. For example If I want to compare three objects for equalities, I should be write:

Object.identity(x, y) && Object.identity(y, z)

Isn't good idea for comparing N arguments for equality? The code above would be rewritten as:

Object.identity(x, y, z)

I really miss the point, why the language API should be care about naming collisions with third party libraries? If tomorrow someone in JQuery or Prototype team makes a decision for augmentation of `Object' constructor, is it really matter for the designers of the language API?

Thanks in advance for your valuable answers.

# Jürg Lehni (15 years ago)

I would expect compare() to return either -1, 0 or 1...

# Brendan Eich (15 years ago)

On Sep 7, 2010, at 2:10 AM, Jürg Lehni wrote:

On 7 Sep 2010, at 02:01, Brendan Eich wrote:

It would following the verg-object-noun-phrase convention, but we have more than one convention.

Note how isNaN(x) and isFinite(x) are functions taking one parameter. Whereas Object.identical(a, b) tests whether two values are identical. Does "is" work still? Could we dodge the issue (as well as the implied preposition "to": isIdenticalTo) by using Jeff's "identical" suggestion?

Maybe one could argue that Object.isIdentical(a, b) is the generic version of non-existing a.isIdentical(b) ?

Maybe. It's hard to worry since we won't have the latter (no Pythonic reflection of self-methods as class-methods with self uncurried).

Humpty-Dumpty naming still applies to a large extent, but usability and aesthetics need more than a committee, or a mailing list -- they need some inherent design, or strong precedent, if not the customary strong single designer (www.dreamsongs.com/Files/DesignedAsDesignerExpanded.pdf).

I'd be happy with Object.eq if not for the terseness compared to almost every other identifier in the standard library. But if the alternative is an overlong name, I'll go back to eq and stand there with Mark.

# Brendan Eich (15 years ago)

On Sep 7, 2010, at 2:39 AM, Maciej Stachowiak wrote:

On Sep 6, 2010, at 6:01 PM, Brendan Eich wrote:

For single-parameter tests, "is" or "has" followed by a NounPhrase is indeed the dominant naming convention. For a dyadic function to pair with Object.hashcode, Object.identical still seems best to me. The only other verb-free thought is to use the language in the ES5 spec (9.12) and call it Object.sameValue.

You could make it Object.areIdentical(a, b), but I don't think that reads very well.

I know, that was my point!

How about "sameValue"?

I see these suggestions on the thread so far, and in the original proposal:

  1. eq
  2. equal
  3. identical
  4. isIdentical
  5. sameValue
  6. compare

1 is concise to a fault, and based on LISP precedent. It is also favored by the current proposal's champion.

2 spells it out (I dropped the -s ending, it does not make sense for a function taking two arguments without reordering terms, and avoidable -s endings are usually problematic when programming).

3 is more precise (Breton hoped eq or equals would do some kind of deep compare).

4 adds "is" based on some JS (after Java, after Smalltalk general naming convention) precedent but otherwise is the same as 3.

5 is based on the ES5 spec, but perhaps lacks precision (deep compare? "Value" may connote that).

6 is too close to the cmp or <=> operator of other languages, which results in -1, 0, or 1.

Based on this summary, I favor [3, 1, 5] in that order. I reject [2, 4, 6] for the reasons given. My two cents, hope this helps.

# P T Withington (15 years ago)

On 2010-09-07, at 12:02, Brendan Eich wrote:

  1. identical

If I had a vote, +1

Is there someplace that concisely explains the cost of just fixing === so I could understand why that is not a choice?

# Ash Berlin (15 years ago)

On 7 Sep 2010, at 17:18, P T Withington wrote:

On 2010-09-07, at 12:02, Brendan Eich wrote:

  1. identical

If I had a vote, +1

Is there someplace that concisely explains the cost of just fixing === so I could understand why that is not a choice?

FWIW this sort of naming issue is a rabbit hole that CommonJS fell down when it came to method names for a unit test framework0. There was no real consensus, but we settled on equal meaning == and strictEqual meaning ===.

-ash

# Brendan Eich (15 years ago)

On Sep 7, 2010, at 9:18 AM, P T Withington wrote:

On 2010-09-07, at 12:02, Brendan Eich wrote:

  1. identical

If I had a vote, +1

Is there someplace that concisely explains the cost of just fixing === so I could understand why that is not a choice?

The cost is hard to know without trying to fix ===, but potentially, even at low likelihood of breakage. No browser vendor is particularly motivated to try doing this, but it could be spec'ed and then we all try it "next time".

I tried, in 1996 (shipping in 1997, Netscape 4 betas), to change == to act like === does now, in "JavaScript1.2". Developers had to opt in using <script language="JavaScript1.2">....</script>. In spite of the opt-in, this caused a lot of confusion due to code copying and dropped version specifiers.

In the end, Microsoft did not implement this part of JS1.2 (RegExps and other parts made their way into ES3), and IE ignored script language= version selection (also for script type=, contrary to RFC 4329). In Ecma TC39 TG1, we ended up standardizing ES1 in 1997 with new === and !== operators, and == and != retained as the sloppy old non-equivalence relations.

You could well argue that "fixing" === now, with better opt-in version selection machinery, would break less than my attempt then did, because it would entail fewer changes to go from === in ES5 to ===-as-Object.eq than what I tried in making == in JS1.2 mean what === means in ES1.

But there's more to consider now: the web is wider and deeper, with greater depths hidden behind paywalls and registration barriers. Numerically intensive code, often driving canvas rendering and using transcendental functions (so potentially sensitive to -0 vs 0), is more common than ever. And tools and teachers promote === over == but of course cannot really do anything about -0 === 0 or NaN !== NaN.

So I agree that it is worth discussing a change for === in Harmony, which requires opt in versioning, to mean what is proposed for Object.eq. But such a change still carries hard-to-quantify risk, which could impair migration efforts and (mostly) make TC39 swerve away from changing meaning in the Harmony version, instead playing it safe by adding a new API.

Thanks for bringing this up.

# Brendan Eich (15 years ago)

Oops, a word was lost by accident:

On Sep 7, 2010, at 9:41 AM, Brendan Eich wrote:

On Sep 7, 2010, at 9:18 AM, P T Withington wrote:

On 2010-09-07, at 12:02, Brendan Eich wrote:

  1. identical

If I had a vote, +1

Is there someplace that concisely explains the cost of just fixing === so I could understand why that is not a choice?

The cost is hard to know without trying to fix ===, but potentially

"high"

# Brendan Eich (15 years ago)

On Sep 7, 2010, at 9:34 AM, Ash Berlin wrote:

On 7 Sep 2010, at 17:18, P T Withington wrote:

On 2010-09-07, at 12:02, Brendan Eich wrote:

  1. identical

If I had a vote, +1

Is there someplace that concisely explains the cost of just fixing === so I could understand why that is not a choice?

FWIW this sort of naming issue is a rabbit hole that CommonJS fell down when it came to method names for a unit test framework[0]. There was no real consensus, but we settled on equal meaning == and strictEqual meaning ===.

Those are fine names, and it seems you came out of the rabbit hole (under the bikeshed ;-).

All naming discussions can rathole (let's say), but I hope we can conclude this thread with a clear winner, as it seems you guys ultimately did.

Also, you picked spec-like names for == and === but there is no SameValue or Object.eq, I take it (even though one can be written in JS). If you had such a thing, I wonder whether you wouldn't name it identical (not reallyStrictEqual or sameValue).

But I don't want to send you back down the hole to find out! This es-discuss hole will do.

# Tom Van Cutsem (15 years ago)

FWIW: Clojure (the "new Lisp") uses (identical? a b)

I don't know why Rich Hickey dropped 'eq?' and went with 'identical?', but I like it.

Cheers, Tom

2010/9/7 Brendan Eich <brendan at mozilla.com>