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: reword usage of rest arguments in built-in functions #1394

Open
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@devsnek
Copy link
Contributor

devsnek commented Jan 4, 2019

  • Specify that arguments covered by rest args aren't filled by undefined
  • Remove steps which duplicate the definitions of rest arguments in algorithm bodies
  • Remove most usage (ignoring the horror in Array and Date) of "(actual) number of (actual) arguments"
@@ -23106,7 +23106,7 @@ <h1>ECMAScript Standard Built-in Objects</h1>
<p>There are certain built-in objects available whenever an ECMAScript |Script| or |Module| begins execution. One, the global object, is part of the lexical environment of the executing program. Others are accessible as initial properties of the global object or indirectly as properties of accessible built-in objects.</p>
<p>Unless specified otherwise, a built-in object that is callable as a function is a built-in function object with the characteristics described in <emu-xref href="#sec-built-in-function-objects"></emu-xref>. Unless specified otherwise, the [[Extensible]] internal slot of a built-in object initially has the value *true*. Every built-in function object has a [[Realm]] internal slot whose value is the Realm Record of the realm for which the object was initially created.</p>
<p>Many built-in objects are functions: they can be invoked with arguments. Some of them furthermore are constructors: they are functions intended for use with the `new` operator. For each built-in function, this specification describes the arguments required by that function and the properties of that function object. For each built-in constructor, this specification furthermore describes properties of the prototype object of that constructor and properties of specific object instances returned by a `new` expression that invokes that constructor.</p>
<p>Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the *undefined* value. Such missing arguments are considered to be &ldquo;not present&rdquo; and may be identified in that manner by specification algorithms. In the description of a particular function, the terms &ldquo;`this` value&rdquo; and &ldquo;NewTarget&rdquo; have the meanings given in <emu-xref href="#sec-built-in-function-objects"></emu-xref>.</p>
<p>Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the *undefined* value. Such missing arguments, if not covered by rest arguments, are considered to be &ldquo;not present&rdquo; and may be identified in that manner by specification algorithms. In the description of a particular function, the terms &ldquo;`this` value&rdquo; and &ldquo;NewTarget&rdquo; have the meanings given in <emu-xref href="#sec-built-in-function-objects"></emu-xref>.</p>

This comment has been minimized.

@ljharb

ljharb Jan 4, 2019

Member

If you have a function with a signature of (a, b, ...c):

arguments.length a b c.length
0 not present not present 0
1 present not present 0
2 present present 0
3 present present 1

Given this table, it makes sense to me that c is always "present", even if it's empty by virtue of insufficient arguments being provided, so this change makes sense to me.

Show resolved Hide resolved spec.html
Show resolved Hide resolved spec.html
1. Let _nextCU_ be ? ToUint16(_next_).
1. Append _nextCU_ to the end of _elements_.
1. Increase _nextIndex_ by 1.
1. Return the String value whose code units are, in order, the elements in the List _elements_. If _length_ is 0, the empty string is returned.
1. Return the String value whose code units are, in order, the elements in the List _elements_. If the number of elements in _codeUnits_ is 0, the empty string is returned.

This comment has been minimized.

@ljharb

ljharb Jan 4, 2019

Member

can we use "If codeUnits is empty, the empty string is returned", and maybe split this step up into an if/then two-step?

This comment has been minimized.

@devsnek

devsnek Jan 4, 2019

Contributor

I don't think the second sentence here has any normative meaning. I'd be in favor of removing it.

This comment has been minimized.

@ljharb

ljharb Jan 4, 2019

Member

I think it's useful to keep an explicit mention of the empty string case.

This comment has been minimized.

@jmdyck

jmdyck Jan 4, 2019

Collaborator

You could make it a NOTE-step.

This comment was marked as resolved.

@ljharb

ljharb Jan 4, 2019

Member

A note seems like it’d apply to the whole algorithm, instead of just this step.

This comment has been minimized.

@jmdyck

jmdyck Jan 4, 2019

Collaborator

A NOTE-step applies just to the point in the algorithm at which it occurs. (Scan the spec for NOTE:.)

1. Let _nextCP_ be ? ToNumber(_next_).
1. If SameValue(_nextCP_, ! ToInteger(_nextCP_)) is *false*, throw a *RangeError* exception.
1. If _nextCP_ &lt; 0 or _nextCP_ &gt; 0x10FFFF, throw a *RangeError* exception.
1. Append the elements of the UTF16Encoding of _nextCP_ to the end of _elements_.
1. Increase _nextIndex_ by 1.
1. Return the String value whose code units are, in order, the elements in the List _elements_. If _length_ is 0, the empty string is returned.
1. Return the String value whose code units are, in order, the elements in the List _elements_. If the number of elements in _codePoints_ is 0, the empty string is returned.

This comment has been minimized.

@ljharb

ljharb Jan 4, 2019

Member

ditto

@@ -32778,7 +32762,7 @@ <h1>Runtime Semantics: IterableToList ( _items_, _method_ )</h1>
<h1>%TypedArray%.of ( ..._items_ )</h1>
<p>When the `of` method is called with any number of arguments, the following steps are taken:</p>
<emu-alg>
1. Let _len_ be the actual number of arguments passed to this function.
1. Let _len_ be the number of elements in _items_.
1. Let _items_ be the List of arguments passed to this function.

This comment has been minimized.

@jmdyck

jmdyck Jan 4, 2019

Collaborator

You presumably want to delete the Let _items_ be ... step.

Suggested change Beta
1. Let _items_ be the List of arguments passed to this function.
Show resolved Hide resolved spec.html
@@ -23106,7 +23106,7 @@ <h1>ECMAScript Standard Built-in Objects</h1>
<p>There are certain built-in objects available whenever an ECMAScript |Script| or |Module| begins execution. One, the global object, is part of the lexical environment of the executing program. Others are accessible as initial properties of the global object or indirectly as properties of accessible built-in objects.</p>
<p>Unless specified otherwise, a built-in object that is callable as a function is a built-in function object with the characteristics described in <emu-xref href="#sec-built-in-function-objects"></emu-xref>. Unless specified otherwise, the [[Extensible]] internal slot of a built-in object initially has the value *true*. Every built-in function object has a [[Realm]] internal slot whose value is the Realm Record of the realm for which the object was initially created.</p>
<p>Many built-in objects are functions: they can be invoked with arguments. Some of them furthermore are constructors: they are functions intended for use with the `new` operator. For each built-in function, this specification describes the arguments required by that function and the properties of that function object. For each built-in constructor, this specification furthermore describes properties of the prototype object of that constructor and properties of specific object instances returned by a `new` expression that invokes that constructor.</p>
<p>Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the *undefined* value. Such missing arguments are considered to be &ldquo;not present&rdquo; and may be identified in that manner by specification algorithms. In the description of a particular function, the terms &ldquo;`this` value&rdquo; and &ldquo;NewTarget&rdquo; have the meanings given in <emu-xref href="#sec-built-in-function-objects"></emu-xref>.</p>
<p>Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the *undefined* value. Such missing arguments, if not covered by rest arguments, are considered to be &ldquo;not present&rdquo; and may be identified in that manner by specification algorithms. In the description of a particular function, the terms &ldquo;`this` value&rdquo; and &ldquo;NewTarget&rdquo; have the meanings given in <emu-xref href="#sec-built-in-function-objects"></emu-xref>.</p>

This comment has been minimized.

@jmdyck

jmdyck Jan 4, 2019

Collaborator

I don't think it suffices to simply insert "if not covered by rest arguments", because we haven't defined 'rest argument' (or parameter) in the context of a built-in function's signature, or what it means to be "covered by" one.

Also, I don't think you can delete specific steps like Let _sources_ be the List of argument values starting with the second argument without specifying the general mechanism instead.

So I think I'd like to see this paragraph expanded into a specification of the things that appear in built-ins' parameter lists (including square-brackets and ellipsis), and the way that parameters get their values for a given invocation (i.e., using values, if any, from the argumentsList of the [[Call]]). (This could possibly be a new clause under "Algorithm Conventions", or even something in 9.3.1, but I think it might make more sense here.)

@jmdyck

This comment has been minimized.

Copy link
Collaborator

jmdyck commented on f628e02 Jan 4, 2019

Similarly for String.fromCodePoint ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment