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

Open
wants to merge 1 commit into
base: master
from

Conversation

@ljharb
Copy link
Member

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.

@ljharb ljharb requested review from bterlson and jridgewell Jan 29, 2018
@ljharb ljharb mentioned this pull request Jan 29, 2018
@annevk

This comment has been minimized.

Copy link
Member

annevk commented Jan 30, 2018

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

@leobalter

This comment has been minimized.

Copy link
Member

leobalter commented Jan 30, 2018

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

@jmdyck

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Member

bterlson commented Jan 31, 2018

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Member

bterlson commented Jan 31, 2018

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

@ljharb

This comment has been minimized.

Copy link
Member Author

ljharb commented Jan 31, 2018

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

@ljharb

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Member

bterlson commented Jan 31, 2018

@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

This comment has been minimized.

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.

@ljharb ljharb force-pushed the ljharb:is_zero branch from c18b758 to 895102e Jan 31, 2018
@allenwb

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Collaborator

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

This comment has been minimized.

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.

ljharb added a commit to ljharb/ecma262 that referenced this pull request Oct 4, 2019
@ljharb ljharb force-pushed the ljharb:is_zero branch from 8680f85 to 939ecca Oct 4, 2019
@ljharb

This comment has been minimized.

Copy link
Member Author

ljharb commented Oct 4, 2019

Now that BigInt has merged, I've rebased this. Rereview would be appreciated.

@ljharb ljharb requested review from leobalter, annevk and jmdyck and removed request for zenparsing and tc39/ecma262-editors Oct 4, 2019
Copy link
Collaborator

jmdyck left a comment

There's one more occurrence of "is zero", under Date.parse(_string_).
Should be "is ±0"?

spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
ljharb added a commit to ljharb/ecma262 that referenced this pull request Oct 7, 2019
@ljharb ljharb force-pushed the ljharb:is_zero branch from 939ecca to e4e37e9 Oct 7, 2019
spec.html Outdated Show resolved Hide resolved
@jmdyck

This comment has been minimized.

Copy link
Collaborator

jmdyck commented Oct 7, 2019

(Should have included this in my review:) All occurrences of +0 and ±0 introduced by this PR should probably be surrounded in asterisks.

(The ±0 case is debatable, since it is not a value per se, but a shorthand for two values. Up to you.)

ljharb added a commit to ljharb/ecma262 that referenced this pull request Oct 12, 2019
@ljharb ljharb force-pushed the ljharb:is_zero branch from e4e37e9 to cc59d53 Oct 12, 2019
@ljharb ljharb requested a review from jmdyck Oct 12, 2019
spec.html Show resolved Hide resolved
spec.html Outdated Show resolved Hide resolved
spec.html Show resolved Hide resolved
spec.html Show resolved Hide resolved
@ljharb ljharb requested a review from annevk Oct 16, 2019
ljharb added a commit to ljharb/ecma262 that referenced this pull request Oct 16, 2019
@ljharb ljharb force-pushed the ljharb:is_zero branch from cc59d53 to 5f84cd9 Oct 16, 2019
@ljharb ljharb requested a review from jmdyck Oct 16, 2019
@michaelficarra

This comment was marked as resolved.

Copy link
Member

michaelficarra commented Nov 8, 2019

@ljharb Can you rebase and resolve conflicts?

@michaelficarra

This comment was marked as resolved.

Copy link
Member

michaelficarra commented Nov 8, 2019

@ljharb It seems you've missed two uses of "zero" in 21.2.2.5.1 Runtime Semantics: RepeatMatcher that would be appropriate to change.

@ljharb ljharb force-pushed the ljharb:is_zero branch from 5f84cd9 to 654eae2 Nov 9, 2019
@ljharb ljharb requested review from syg, michaelficarra and bakkot Nov 9, 2019
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*.

This comment has been minimized.

Copy link
@bakkot

bakkot Nov 13, 2019

Contributor

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

This comment has been minimized.

Copy link
@jmdyck

jmdyck Nov 14, 2019

Collaborator

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".)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.