Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editorial: use "is 0" instead of "is zero" for consistency #1086

Merged
merged 1 commit into from
Dec 14, 2020

Conversation

ljharb
Copy link
Member

@ljharb ljharb commented Jan 29, 2018

Discovered here.

The spec seems to use is 0 most often for comparing to zero, specifically with the results of a ToLength call, which can not return anything <= 0 besides positive zero.

An equally valid and consistent alternative would be replacing all the is 0 instances with is zero, if we'd find that clearer.

@annevk
Copy link
Member

annevk commented Jan 30, 2018

I suggest 0, but please record the resolution in tc39/proposal-bigint#10.

@leobalter
Copy link
Member

LGTM. I like this change for a better consistency and the well observed change on the literalSegments check for String.raw.

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 30, 2018

Note that if _x_ is a Number value, writing _x_ is 0 or _x_ is zero is somewhat ill-defined, because Number doesn't have a (single) zero value, it has *+0* and *-0*. I think it generally means _x_ is *+0* or *-0*, but it might be better to say so explicitly.

Of course, if _x_ were a "mathematical value", then comparison with 0 would be well-defined. However:
(a) distinguishing the two possibilities is currently non-trivial, and
(b) it's still an open question whether the second possibility exists (tc39/proposal-bigint#10).

@leobalter
Copy link
Member

leobalter commented Jan 30, 2018

@jmdyck I think 0 should be fine:

5.2.5 Mathematical Operations
...
If a mathematical operation or function is applied to a floating-point number, it should be understood as being applied to the exact mathematical value represented by that floating-point number; such a floating-point number must be finite, and if it is +0 or -0 then the corresponding mathematical value is simply 0.

6.1.6 The Number Type
...
Note that all the positive and negative integers whose magnitude is no greater than 253 are representable in the Number type (indeed, the integer 0 has two representations, +0 and -0).

If the specs requires strict comparisons to positive or negative zero, this is and should be always explicit. The 0 refers to any, and if needs to produce or cast any value, +0 should be used to avoid ambiguity.

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 30, 2018

@leobalter: Relying on the Mathematical Operations clause to resolve this question requires you to say that "is" is a mathematical operation, which is a stretch just on its own, but also inconsistent with the spec's many non-mathematical uses of "is".

@ljharb
Copy link
Member Author

ljharb commented Jan 30, 2018

I’m content with anything that’s unambiguous and consistent. Would “is zero” remove the potential interpretation that it’s only comparing to +0?

@bterlson
Copy link
Member

Am I alone in thinking we should avoid depending on "mathematical values" if at all possible (in part because the long-standing question about whether/how they exist) and just go with explicit +/- 0? Or, define a term like "the value zero" which is just +0 and -0?

@ljharb
Copy link
Member Author

ljharb commented Jan 31, 2018

That sounds fine too - I could also replace all these cases with SameValue(blah, 0), or is positive or negative zero.

@jridgewell
Copy link
Member

jridgewell commented Jan 31, 2018

just go with explicit +/- 0

"is ±0", "is not ±0"? 👍

http://www.fileformat.info/info/unicode/char/b1/index.htm

@bterlson
Copy link
Member

I like PLUS-MINUS SIGN, yeah, good call.

@ljharb
Copy link
Member Author

ljharb commented Jan 31, 2018

Great, I'll update all of these to match that.

@ljharb
Copy link
Member Author

ljharb commented Jan 31, 2018

hmm, that doesn't really work for the conceptual places like when they're talking about string length. Would using SameValueZero maybe be more explicit?

@domenic
Copy link
Member

domenic commented Jan 31, 2018

@bterlson you are not alone, but the general problem is pretty endemic in the spec right now (see tc39/proposal-bigint#10 as mentioned by @jmdyck upthread). But yeah, if you think it's reasonable to make a piecemeal fix for these cases instead of waiting on the big-ol'-refactor that I'm sure @littledan will be contributing any day now, that seems like a good move.

@bterlson
Copy link
Member

@ljharb for string length, I think +0 is the only possibility.

@domenic yep, agreed it's a problem; being explicit should make any subsequent fixes easier too :)

@ljharb
Copy link
Member Author

ljharb commented Jan 31, 2018

@bterlson cool, i'll use is +0 or is ±0 based on where the variance is possible. Update coming shortly.

@allenwb
Copy link
Member

allenwb commented Jan 31, 2018

Isn't this all a matter of context? If you compare an ECMAScript value to "zero" you must be dealing with ECMAScript number values not mathematical values. If you are comparing a value that was computed using a mathematical formula then you are comparing to a mathematical 0. The context is usually pretty clear.

If you are testing a mathematical value to see if it is mathematically equal to 0 you should use the mathematical = operator and the numeral 0.

If you are testing an ECMAScript Number value x to see if it is a number value you should say: "if x is 0" meaning x is either the number value +0 or the number value -0; "if x is +0" meaning x is the number value +0 but not the number value -0; or, "if x is -0" meaning x is the number value -0 but not the number value +0. I think these meanings should be pretty obvious but if you want to explicitly explain them somewhere the 5th paragraph of Number Type seem like a fine place.

Never use "is zero" in an algorithm or formula. It may be appropriate in some prose paragraphs that aren't explicitly talking about either number values or mathematical values. I checked the current draft. There appears to be 7 occurrences of "is zero" in an algorithm (or algorithm-like table). They all appear to be very old text that was never updated. They should all be fixed.

I think that using ±0 in place of 0 would just be adding noise to the specification.

@allenwb
Copy link
Member

allenwb commented Feb 1, 2018

From ECMA/TC39/97/24, Notes from the 2/14/1997 ECMAScript 1st Edition Drafting Working Group Meeting:

In several places the document uses zero with saying whether positive zero, negative zero or both are intended. It would be useful to do a scan through the doc looking specifically for these cases.

97-024.PDF

@ljharb
Copy link
Member Author

ljharb commented Feb 1, 2018

That suggests that a 0, without a +, -, or something akin to ±, is something that should be changed to be unambiguous.

@allenwb
Copy link
Member

allenwb commented Feb 1, 2018

@ljharb Actually, don't think a comment about a 1997 draft suggests anything about the current specification. The specification and its conventions have changed drastically in the last 21 years...

However, I did think it highly assuming, in the context of this thread, that I ran into it this afternoon. Had to share the fun.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 1, 2018

If you compare an ECMAScript value to "zero" you must be dealing with ECMAScript number values not mathematical values. If you are comparing a value that was computed using a mathematical formula then you are comparing to a mathematical 0. The context is usually pretty clear.

There are a lot of contexts where it isn't clear, i.e. where a numeric quantity is neither the result of a mathematical formula nor obviously an ES language value. E.g., consider Let _x_ be followed by any of:

- 0
- the smallest nonnegative integer such that ...
- the code unit ...
- the 8-bit value represented by the two hexadecimal digits ...
- the integer represented by the four hexadecimal digits ...
- the Element Size value in Table 56 for ...
- the number of arguments passed to this function call
- the code point value of ...
- the length of _y_
- the number of bytes in _y_
- the number of characters contained in _y_
- the number of leading zero bits in the 32-bit binary representation of _y_
- the number of left-capturing parentheses in _y_
- (in general:) the number of [things] in [collection]

With any of these, it's unclear whether _x_ is a Number value or a mathematical value.

Moreover, even when a quantity is defined with a mathematical formula, and so should be a mathematical value, it's not so clear. Consider the example given by @littledan in tc39/proposal-bigint#10: Array.prototype.indexOf has the step Let _k_ be _len_ + _n_. which implies that _k_ is a mathematical value, and yet it's later passed to ToString, which only operates on ES language values. So maybe _k_ is a mathematical value that's implicitly coerced to a Number value as necessary, or maybe it's actually a Number all along. It's unclear.

@allenwb
Copy link
Member

allenwb commented Feb 1, 2018

@jmdyck
But is there any possibility of confusion about the meaning, in context>

consider Let x be followed by any of:

  • 0

doesn't explicitly say be "Let x be -0" so clearly this is either an implicit +0 number value or a mathematical unsigned 0 value. If it isn't clear from context needs to be clarified. I haven't look at all such uses but in my sampling I haven't seen any needing to clarification.

  • the smallest nonnegative integer such that ...

https://tc39.github.io/ecma262/#sec-abstract-relational-comparison
https://tc39.github.io/ecma262/#sec-decode
Clear in context that these both deal with the bit encoding of Unicode code units and that -0 is not in the domain of discourse

Even without additional context, it is clear that in the following fragments the values could never be -0

  • the code unit ...
  • the 8-bit value represented by the two hexadecimal digits ...
  • the integer represented by the four hexadecimal digits ...
  • the Element Size value in Table 56 for ...
  • the number of arguments passed to this function call
  • the code point value of ...
  • the length of y
  • the number of bytes in y
  • the number of characters contained in y
  • the number of leading zero bits in the 32-bit binary representation of y
  • the number of left-capturing parentheses in y
  • (in general:) the number of [things] in [collection]

Turning all occurrences of "0" into either "±0", "+0", or "-0" going to force consideration of the possibility of signed 0 into many places within the specification where the concept of signed 0 is not at all relevant. Seems to me that it would only make things less clear then they already are.

@domenic
Copy link
Member

domenic commented Feb 1, 2018

It's interesting that you find all of those clear from context, Allen. I don't find it clear at all.

Edit: I guess you are talking about +0 vs. -0, but I was talking about mathematical number value vs. ES number value, which is @jmdyck's point.

@allenwb
Copy link
Member

allenwb commented Feb 1, 2018

Which ones are unclear to you? Don't see how counting integer values or bit values could possibly involve a IEEE 768 -0 value (or an Infinity or a NaN)

@anba
Copy link
Contributor

anba commented Feb 1, 2018

Consider the example given by @littledan in tc39/proposal-bigint#10: Array.prototype.indexOf has the step Let k be len + n. which implies that k is a mathematical value, and yet it's later passed to ToString, which only operates on ES language values. So maybe k is a mathematical value that's implicitly coerced to a Number value as necessary, or maybe it's actually a Number all along. It's unclear.

I've always treated mathematical values and Number values as interchangeable, as long as the specific value is well-defined for both types. And this seems to be the case for theArray.prototype.indexOf example, because ToString is never called with a value which cannot be exactly represented by a Number value (because of the loop condition k < len).

Well, if we want to be super correct, more problematic is len + n, because n can be -Infinity, and mathematical values don't include infinities.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 1, 2018

I haven't look at all such uses but in my sampling I haven't seen any needing to clarification.

I count 80 occurrences of Let _foo_ be [numeral]. There are lots where I can't tell from context whether it's a Number value or a mathematical value, mainly because the spec doesn't say which contexts require/allow which, or if/where implicit coercions happen. (E.g., if the algorithm uses _foo_ to index a List, does that tell you what _foo_ is? It's unclear.)

Even without additional context, it is clear that in the following fragments the values could never be -0

Knowing that a numeric value can't be -0 doesn't tell you whether it's a Number value or a mathematical value.

@michaelficarra

This comment has been minimized.

spec.html Outdated
1. Assert: _y_ is 0 or 1.
1. If _x_ is 1 and _y_ is 1, return 1.
1. Else, return 0.
1. Assert: _x_ is *0n* or *1n*.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm not sure about this change. BigIntBitwiseOp, the caller of these operations, deals with unsuffixed numbers.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, those should probably be changed as well (in this PR or not, I don't mind). (Presumably this PR didn't touch BigIntBitwiseOp because it doesn't have any occurrences of "is zero" or "is 0".)

Copy link
Collaborator

@jmdyck jmdyck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has been completely overtaken by the merge of PR #2007, and should probably just be closed.

@ljharb
Copy link
Member Author

ljharb commented Dec 12, 2020

There's still one occurrence left of "is zero" that should be an explicit number; I've rebased this PR with that one change intact.

@ljharb ljharb requested review from bakkot, jmdyck and a team December 12, 2020 07:37
spec.html Show resolved Hide resolved
Copy link
Contributor

@bakkot bakkot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WFM

@ljharb ljharb requested a review from jmdyck December 13, 2020 23:24
Copy link
Collaborator

@jmdyck jmdyck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No objection.

@ljharb ljharb added the ready to merge Editors believe this PR needs no further reviews, and is ready to land. label Dec 14, 2020
@ljharb ljharb merged commit 63ca907 into tc39:master Dec 14, 2020
@ljharb ljharb deleted the is_zero branch December 14, 2020 20:32
moneyglitxh

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editorial change ready to merge Editors believe this PR needs no further reviews, and is ready to land.
Projects
None yet
Development

Successfully merging this pull request may close these issues.