Draft 2 of the spec for the Function class. Changelog near the beginning; several small changes only.
--larsTitle: The class "Function"
The class Function
NAME: "The class 'Function'"
FILE: spec/library/Function.html
CATEGORY: Pre-defined classes (E262-3 Chapter 15)
SOURCES: REFERENCES [1], [2], [3], [5]
SPEC AUTHOR: Lars
DRAFT STATUS: DRAFT 2 - 2008-03-14
REVIEWED AGAINST ES3: YES
REVIEWED AGAINST ERRATA: YES
REVIEWED AGAINST BASE DOC: YES
REVIEWED AGAINST PROPOSALS: YES
REVIEWED AGAINST CODE: YES
REVIEWED AGAINST TICKETS: YES
IMPLEMENTATION STATUS: ES4RI
TEST CASE STATUS: ?
CHANGES SINCE DRAFT 1 (2008-03-10)
* The 'thisObj' parameter to 'bind' is no longer optional, it must
be an object (not null).
* Removed the "Implementation" section for the 'meta::invoke' method
(it added nothing).
* Replaced note about host functions being "anything" with a
paragraph about the type 'Callable'.
OPEN ISSUES
* ES3 restrictions on argArray having to be an Array or an arguments
object in Function.prototype.apply have been removed here.
* Is it reasonable to allow the thisObj parameter to bind to be null
(so that it defaults to the global object of the bind function)?
NOTES
* The use of 'Private' instead of 'private' below is a workaround
for a bug in the reference implementation (#368).
REFERENCES
[1] ECMAScript 3rd Edition specification section 15.3
[2] http://wiki.ecmascript.org/doku.php?id=proposals:static_generics
[2] http://bugs.ecmascript.org/ticket/172
[4] http://bugs.ecmascript.org/ticket/173
[5] http://bugs.ecmascript.org/ticket/174
The class Function is a dynamic, non-final, direct subclass of
Object (see class Object).
All objects defined by function definitions or expressions in
ECMAScript are instances of the class Function.
Not all objects that can be called as functions are instances of
subclasses of the Function class, however. Any object that has a
meta::invoke property can be called as a function.
The structural type Callable (see type:Callable)
matches every object that has a meta::invoke property.
Synopsis
The class Function provides the following interface:
dynamic class Function extends Object
{
public function Function(...args)
static meta function invoke(...args)
static public function apply(fn: Callable, thisArg: Object=null, argArray: Object=null)
static public function bind(method: Callable, thisObj: Object, ...args)
static public function call(fn: Callable, thisObj: Object=null, ...args)
static public const length = 1
meta final function invoke(
)
override intrinsic function toString() : string
intrinsic function apply(thisArg: Object=null, argArray: Object=null)
intrinsic function bind(thisObj: Object, ...args)
intrinsic function call(thisObj: Object=null, ...args)
public const length =
public var prototype =
}
The Function prototype object provides these direct properties:
meta::invoke: function ()
length: 0
toString: function ()
apply: function(thisArg, argArray)
bind: function(thisArg, ...args)
call: function(thisArg, ...args)
Methods on the Function class object
new Function (p1, p2, , pn, body)
Description
When the Function constructor is called with some arguments
as part of a new _expression_, it creates a new Function
instance whose parameter list is given by the concatenation of the
pi arguments separated by "," and whose executable code
is given by the body argument.
There may be no pi arguments, and body is optional too, defaulting to the empty string.
If the first character of the comma-separated concatenation of the pi is a left parenthesis then the list of parameters must be parseable as a FormalParameterListopt enclosed in parentheses and optionally followed by a colon and a return type.
Otherwise, the list of parameters must be parsable as a FormalParameterListopt.
If the list of parameters is not parseable as outlined in the previous two paragraphs, or if the body is not parsable as a FunctionBody, then a SyntaxError exception is thrown (see the grammar in section ECMAScript grammar).
Regardless of the form of the parameter list, it may include type annotations, default parameter values, and rest arguments.
Returns
The Function constructor returns a new Function instance.
Implementation
public function Function(...args)
helper::createFunction(args);
helper function createFunction(args) {
let parameters = "";
let body = "";
if (args.length > 0) {
body = args[args.length-1];
args.length = args.length-1;
parameters = args.join(",");
}
body = string(body);
magic::initializeFunction(this, __ES4__::global, parameters, body);
}
The magic function initializeFunction initializes the function
object this from the list of parameters and the body, as specified
in section translation:FunctionExpression. The global
object is passed in as the scope parameter.
A prototype object is automatically created for every function,
to provide for the possibility that the function will be used as a
constructor.
NOTE It is permissible but not necessary to have one argument for each formal parameter to be specified. For example, all three of the following expressions produce the same result:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
Function (p1, p2, , pn, body)
Description
When the Function class object is called as a function it
creates and initialises a new Function object. Thus the function
call Function(
) is equivalent to the object creation
_expression_ new Function(
) with the same arguments.
Returns
The Function class object called as a function returns a
new Function instance.
Implementation
meta static function invoke(...args)
new Function(...args);
FIXME Ticket #357: That particular definition makes use of the prefix "spread" operator, which has not yet been formally accepted into the language.
apply ( fn, thisArg= , argArray= )
Description
The static apply method takes arguments fn,
thisArg, and argArray and invokes fn in the standard
manner, passing thisArg as the value for this and the members
of argArray as the individual argument values.
Returns
The apply method returns the value returned by fn.
Implementation
static public function apply(fn: Callable, thisArg: Object=null, argArray: Object=null) {
if (thisArg === null)
thisArg = global;
if (argArray === null)
argArray = [];
return magic::apply(fn, thisArg, argArray);
}
NOTE The magic apply function performs the actual invocation (see
magic::apply). This code will eventually change to
use the prefix "spread" operator.
bind ( fn, thisArg= , ...args )
Description
The static bind method takes arguments fn, thisArg,
and optionally some args.
Returns
The bind method returns a Function object that accepts
some arguments moreargs and which calls fn with thisArg as
the this object and the values of args and moreargs as
actual arguments.
Implementation
static public function bind(method: Callable, thisObj: Object, ...args)
helper::bind(method, thisObj, args);
static helper function bind(method, thisObj, args) {
if (thisObj === null)
throw new TypeError();
return function (...moreargs)
method.apply(thisObj, args.concat(moreargs));
}
call ( fn, thisArg= , ...args )
Description
The static call method takes arguments fn and
thisArg and optionally some args and invokes fn in the
standard manner, passing thisArg as the value for this and the
members of args as the individual argument values.
Returns
The call method returns the value returned by fn.
Implementation
static public function call(fn: Callable, thisObj: Object=null, ...args)
Function.apply(fn, thisObj, args);
Methods on Function instances
meta::invoke ( )
Description
The meta method invoke is specialized to the individual
Function object. When called, it evaluates the executable code
for the function.
The meta method invoke is typically called by the ECMAScript
implementation as part of the function invocation and object
construction protocols. When a function or method is invoked, the
invoke method of the function or method object provides the code
to run. When a function is used to construct a new object, the
invoke method provides the code for the constructor function.
The signature of the meta method invoke is determined when the
Function instance is created, and is determined by the text that
defines the function being created.
NOTE The meta method invoke is final; therefore subclasses
can add properties and methods but can't override the function calling
behavior.
FIXME (Ticket #173.) While it is necessary that the invoke
method is completely magic in Function instances, it's not clear
that it needs to be magic for instances of subclasses of Function,
because these can be treated like other objects that have invoke
methods (and which already work just fine in the reference
implementation). Therefore it should not be final.
Returns
The meta method invoke returns the value produces by the
first return statement that is evaluated during the evaluation of
the executable code for the function represented by this Function
object.
intrinsic::toString ( )
Description
The intrinsic toString method converts the executable code
of the function to a string representation. This representation has
the syntax of a FunctionDeclaration or FunctionExpression.
Note in particular that the use and placement of white space, line
terminators, and semicolons within the representation string is
implementation-dependent.
COMPATIBILITY NOTE ES3 required the syntax to be that of a FunctionDeclaration only, but that made it impossible to produce a string representation for functions created from unnamed function expressions.
Returns
The intrinsic toString method returns a string.
Implementation
override intrinsic function toString() : string
Private::toString();
The private function toString is implementation-dependent.
intrinsic::apply ( thisObj= , args= )
Description
The intrinsic apply method calls the static apply method
with the value of this as the first argument.
Returns
The intrinsic apply method returns the result of the static
apply method.
Implementation
intrinsic function apply(thisArg: Object=null, argArray: Object=null)
Function.apply(this, thisArg, argArray);
intrinsic::bind ( thisObj= , ...args)
Description
The intrinsic bind method calls the static bind method
with the value of this as the first argument.
Returns
The intrinsic bind method returns the result of the static
bind method.
Implementation
intrinsic function bind(thisObj: Object, ...args)
Function.helper::bind(this, thisObj, args);
intrinsic::call ( thisObj= , ...args)
Description
The intrinsic call method calls the static apply method
with the value of this as the first argument.
Returns
The intrinsic call method returns the result of the static
call method.
Implementation
intrinsic function call(thisObj: Object=null, ...args)
Function.apply(this, thisObj, args);
Value properties of Function instances
length
The value of the constant length property is the number of
non-rest arguments accepted by the function.
The value of the length property is an integer that indicates
the "typical" number of arguments expected by the function. However,
the language permits the function to be invoked with some other number
of arguments. The behaviour of a function when invoked on a number of
arguments other than the number specified by its length property
depends on the function.
prototype
The initial value of the prototype property is a fresh
Object instance.
The value of the prototype property is used to initialise the
internal [[Prototype]] property of a newly created object before the
Function instance is invoked as a constructor for that newly
created object.
Invoking the Function prototype object
When the Function prototype object is invoked it accepts any
arguments and returns undefined:
prototype meta function invoke(...args)
undefined;
Methods on the Function prototype object
The methods on the Function prototype object perform simple
type adjustments and then perform the same actions as their intrinsic
counterparts:
prototype function toString(this: Function)
this.Private::toString();
prototype function apply(this: Callable, thisArg=undefined, argArray=undefined)
Function.apply(this,
thisArg === undefined ? null : thisArg,
argArray === undefined ? null : argArray);
prototype function bind(this: Callable, thisObj, ...args)
Function.helper::bind(this, thisObj, args);
prototype function call(this: Callable, thisObj=undefined, ...args)
Function.apply(this,
thisObj === undefined ? null : thisObj,
args);
Value properties on the Function prototype object
length
The initial value of the length prototype property is 0.
Implementation
prototype var length : uint = 0;
COMPATIBILITY NOTE The "length" property of the prototype is not obviously required by the 3rd Edition of this Standard, but MSIE, Firefox, Opera, and Safari all provide it.
_______________________________________________ Es4-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es4-discuss
