First draft of the spec for the Function class. Please comment. --larsTitle: The class "Function"
The class Function
NAME: "The class 'Function'" FILE: spec/library/Function.html CATEGORY: Pre-defined classes SOURCES: REFERENCES [1], [2], [3], [5] SPEC AUTHOR: Lars DRAFT STATUS: DRAFT 1 - 2008-03-10 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: ? OPEN ISSUES * ES3 restrictions on argArray having to be an Array or an arguments object in Function.prototype.apply have been removed here. NOTES * The annotation '/*: function*/' below looks like that because the reference implementation does not yet accept plain 'function' as a type annotation to mean 'anything callable' (ticket #153). * The use of 'Private' instead of 'private' 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
Functionis a dynamic, non-final, direct subclass ofObject(see class Object).All objects defined by
functiondefinitions or expressions in ECMAScript are instances of the classFunction.Not all objects that can be called as functions are instances of subclasses of the
Functionclass, however. Any object that has ameta::invokemethod can be called as a function.NOTE Host functions may also not be instances of
Functionor its subclasses, but must to some extent behave as if they are (see Host objects). However, host functions need not providemeta::invokemethods to be callable. The typefunction, defined elsewhere, matches invokable host functions even if they do not have ameta::invokemethod.Synopsis
The class
Functionprovides the following interface:dynamic class Function extends Object { public function Function(...args) static meta function invoke(...args) static public function apply(fn /*: function*/, thisArg: Object=null, argArray: Object=null) static public function bind(method /*: function*/, thisObj: Object=null, ...args) static public function call(fn /*: function*/, 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=null, ...args) intrinsic function call(thisObj: Object=null, ...args) public const length = public var prototype = }The
Functionprototype 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
Functionclass objectnew Function (p1, p2, , pn, body)
Description
When the
Functionconstructor is called with some arguments as part of anew_expression_, it creates a newFunctioninstance 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
Functionconstructor returns a newFunctioninstance.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
initializeFunctioninitializes the function objectthisfrom the list of parameters and the body, as specified in section translation:FunctionExpression. The global object is passed in as the scope parameter.A
prototypeobject 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
Functionclass object is called as a function it creates and initialises a newFunctionobject. Thus the function callFunction( )is equivalent to the object creation _expression_new Function( )with the same arguments.Returns
The
Functionclass object called as a function returns a newFunctioninstance.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
applymethod takes arguments fn, thisArg, and argArray and invokes fn in the standard manner, passing thisArg as the value forthisand the members of argArray as the individual argument values.Returns
The
applymethod returns the value returned by fn.Implementation
static public function apply(fn /*: function*/, thisArg: Object=null, argArray: Object=null) { if (thisArg === null) thisArg = global; if (argArray === null) argArray = []; return magic::apply(fn, thisArg, argArray); }NOTE The magic
applyfunction 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
bindmethod takes arguments fn, thisArg, and optionally some args.Returns
The
bindmethod returns aFunctionobject that accepts some arguments moreargs and which calls fn with thisArg as thethisobject and the values of args and moreargs as actual arguments.Implementation
static public function bind(method /*: function*/, thisObj: Object=null, ...args) helper::bind(method, thisObj, args); static helper function bind(method, thisObj, args) function (...moreargs) method.apply(thisObj, args.concat(moreargs));call ( fn, thisArg= , ...args )
Description
The static
callmethod takes arguments fn and thisArg and optionally some args and invokes fn in the standard manner, passing thisArg as the value forthisand the members of args as the individual argument values.Returns
The
callmethod returns the value returned by fn.Implementation
static public function call(fn /*: function*/, thisObj: Object=null, ...args) Function.apply(fn, thisObj, args);Methods on Function instances
meta::invoke ( )
Description
The meta method
invokeis specialized to the individualFunctionobject. When called, it evaluates the executable code for the function.The meta method
invokeis typically called by the ECMAScript implementation as part of the function invocation and object construction protocols. When a function or method is invoked, theinvokemethod of the function or method object provides the code to run. When a function is used to construct a new object, theinvokemethod provides the code for the constructor function.The signature of the meta method
invokeis determined when theFunctioninstance is created, and is determined by the text that defines the function being created.NOTE The meta method
invokeisfinal; therefore subclasses can add properties and methods but can't override the function calling behavior.FIXME (Ticket #173.) While it is necessary that the
invokemethod is completely magic inFunctioninstances, it's not clear it needs to be magic for instances of subclasses ofFunction, because these can be treated like other objects that haveinvokemethods (and which already work just fine in the reference implementation). Therefore it should not befinal.Returns
The meta method
invokereturns the value produces by the firstreturnstatement that is evaluated during the evaluation of the executable code for the function represented by thisFunctionobject.Implementation
The implementation of the meta function
invokeis implementation-dependent.intrinsic::toString ( )
Description
The intrinsic
toStringmethod 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
toStringmethod returns a string.Implementation
override intrinsic function toString() : string Private::toString();The private function
toStringis implementation-dependent.intrinsic::apply ( thisObj= , args= )
Description
The intrinsic
applymethod calls the staticapplymethod with the value ofthisas the first argument.Returns
The intrinsic
applymethod returns the result of the staticapplymethod.Implementation
intrinsic function apply(thisArg: Object=null, argArray: Object=null) Function.apply(this, thisArg, argArray);intrinsic::bind ( thisObj= , ...args)
Description
The intrinsic
bindmethod calls the staticbindmethod with the value ofthisas the first argument.Returns
The intrinsic
bindmethod returns the result of the staticbindmethod.Implementation
intrinsic function bind(thisObj: Object=null, ...args) Function.helper::bind(this, thisObj, args);intrinsic::call ( thisObj= , ...args)
Description
The intrinsic
callmethod calls the staticapplymethod with the value ofthisas the first argument.Returns
The intrinsic
callmethod returns the result of the staticcallmethod.Implementation
intrinsic function call(thisObj: Object=null, ...args) Function.apply(this, thisObj, args);Value properties of
Functioninstanceslength
The value of the constant
lengthproperty is the number of non-rest arguments accepted by the function.The value of the
lengthproperty 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
prototypeproperty is a freshObjectinstance.The value of the
prototypeproperty is used to initialise the internal[[Prototype]]property of a newly created object before theFunctioninstance is invoked as a constructor for that newly created object.Invoking the
Functionprototype objectWhen the
Functionprototype object is invoked it accepts any arguments and returns undefined:prototype meta function invoke(...args) undefined;Methods on the
Functionprototype objectThe methods on the
Functionprototype 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: function, */ thisArg=undefined, argArray=undefined) Function.apply(this, thisArg === undefined ? null : thisArg, argArray === undefined ? null : argArray); prototype function bind(/*this: function, */ thisObj=undefined, ...args) Function.helper::bind(this, thisObj === undefined ? null : thisObj, args); prototype function call(/*this: function, */ thisObj=undefined, ...args) Function.apply(this, thisObj === undefined ? null : thisObj, args);Value properties on the
Functionprototype objectlength
The initial value of the
lengthprototype 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
