Volunteers needed: Function.prototype.bind() in ES3.1 pseudo-code

Richard Cornford Richard at litotes.demon.co.uk
Fri Sep 19 19:36:31 PDT 2008


Mark S. Miller wrote:
<snip> 
> So what we need now is a spec for Function.prototype.bind()
> in the peculiar pseudo-code style -- combining the worst of
> COBOL and assembly language -- used in the rest of the spec.
> Unfortunately, I won't have time between now and then. Would
> anyone care to contribute some text? Please?

Something like:

---------------------------------------------------------------

Function.prototype.bind (thisArg [, arg1 [,arg2... ]])

The bind method takes one or more arguments, thisArg and
(optionally) arg1, arg2 etc, and returns a new function object.

The following steps are taken:

1. Let T be ToObject(thisArg).
2. Let F be the this object.
3. If IsCallable(F) is false, throw a TypeError exception.
4. Let A be a new (possibly empty) internal list of all of the
   argument values provided after thisArg (arg1, arg2 etc), in
   order.
5. Create a new function object that has no [[Construct]] method,
   a [[Call]] method that, when executed, performs the "Algorithm
   for the [[Call]] methods of functions returned from the bind
   method" and has the values T, F and A internally associated
   with it.
6. Return Result(5).


Algorithm for the [[Call]] methods of functions returned from the
bind method.

When executed with zero or more arguments a function returned by
the original Function.prototype.bind method uses the values of T,
F and A that were associated with it at its creation and the
following steps are taken:

1. Let Args be a new internal list containing the same values as
   the list A in the same order.
2. Add all of the values in the arguments list provided to the
   call to this function to the end of the list Args, in the order
   they appear in that arguments list (see 11.2.4).
3. Invoke the [[Call]] method of F providing T as the this value
   and providing Args as the arguments values.
4. Return Result(3).

---------------------------------------------------------------

In step 1 of the fist algorithm the call to ToObject will result
in a TypeError if thisArg is null or undefined. There seems no
point in explicitly checking for null or undefined values unless
the intention is to default the - this - value to the global
object, which would probably not be a good idea in a new method
even if - call - and - apply - do that. However, this will be
inconsistent with current JS library bind methods as because
they use - call - or - apply - they would default the - this -
value to the global object (though calling existing bind
functions with null or undefined as the intended - this - value
is likely to be indicative of a mistake having been made rather
than a deliberate action).

Precedents for letting a call to ToObject throw a TypeError
instead of checking and explicitly throwing a TypeError if a
value is null or undefined can be found in, for example, the
algorithm for Property Accessor (11.2.1). 

Using ToObject will result in other primitive values being
converted into String, Number or Boolean objects, but that
is consistent with - call - and - apply -, and as existing
JS library versions must employ - call - or - apply - it
must then be consistent with their expected behaviour.

In step 5, although the association of the T, F and A values
could be explicitly stated as being through the [[Scope]] of
the new function the required behaviour does not depend on the
method used to achieve the association, and as the [[Scope]]
of the returned function cannot be observed there seems
little point in saying anything about what value it may have.

Step 5 also requires that no [[Construct]] method be
provided for the returned function. This will result in a
TypeError being thrown if the function is used with the - new -
operator. That seems like a good idea, as it makes no sense to
use the - new - operator with the functions returned from
Function.prototype.bind.

In the second algorithm the wording of step 3, the invoking of
the [[Call]] method of the original - this - function, is based
on step 7 in the [[Construct]] algorithm (13.2.2) and step 8 in
the function call algorithm (11.2.3). This wording avoids any
questions of what would happen if the original - this -
function's "call" or "apply" properties were modified at runtime
(or the "call" property of Function,prototype.apply or the
"apply" property of Function.prototype call). 



If you are trying to get the ES 3.1 spec into a more workable
state it must be worth looking at the references to
"SourceElement : FunctionDeclaration" in section 14 as currently
"FunctionDeclaration" has been deleted from "SourceElement" and
moved under "Statement". As of the 1st September draft there are
no equivalent statements about the handling of
"Statement : FunctionDeclaration" (would they be in section 12
or 14?). (And why retain "SourceElement" at all, as all
SourceElements are now Statements?)

Richard Cornford.


More information about the Es-discuss mailing list