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
Function
is a dynamic, non-final, direct subclass ofObject
(see class Object).All objects defined by
function
definitions or expressions in ECMAScript are instances of the classFunction
.Not all objects that can be called as functions are instances of subclasses of the
Function
class, however. Any object that has ameta::invoke
method can be called as a function.NOTE Host functions may also not be instances of
Function
or its subclasses, but must to some extent behave as if they are (see Host objects). However, host functions need not providemeta::invoke
methods to be callable. The typefunction
, defined elsewhere, matches invokable host functions even if they do not have ameta::invoke
method.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 /*: 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
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 objectnew Function (p1, p2, , pn, body)
Description
When the
Function
constructor is called with some arguments as part of anew
_expression_, it creates a newFunction
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 newFunction
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 objectthis
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 newFunction
object. Thus the function callFunction( )
is equivalent to the object creation _expression_new Function( )
with the same arguments.Returns
The
Function
class object called as a function returns a newFunction
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 forthis
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 /*: 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
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 aFunction
object that accepts some arguments moreargs and which calls fn with thisArg as thethis
object 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
call
method takes arguments fn and thisArg and optionally some args and invokes fn in the standard manner, passing thisArg as the value forthis
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 /*: function*/, thisObj: Object=null, ...args) Function.apply(fn, thisObj, args);Methods on Function instances
meta::invoke ( )
Description
The meta method
invoke
is specialized to the individualFunction
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, theinvoke
method of the function or method object provides the code to run. When a function is used to construct a new object, theinvoke
method provides the code for the constructor function.The signature of the meta method
invoke
is determined when theFunction
instance is created, and is determined by the text that defines the function being created.NOTE The meta method
invoke
isfinal
; 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 inFunction
instances, it's not clear it needs to be magic for instances of subclasses ofFunction
, because these can be treated like other objects that haveinvoke
methods (and which already work just fine in the reference implementation). Therefore it should not befinal
.Returns
The meta method
invoke
returns the value produces by the firstreturn
statement that is evaluated during the evaluation of the executable code for the function represented by thisFunction
object.Implementation
The implementation of the meta function
invoke
is implementation-dependent.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 staticapply
method with the value ofthis
as the first argument.Returns
The intrinsic
apply
method returns the result of the staticapply
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 staticbind
method with the value ofthis
as the first argument.Returns
The intrinsic
bind
method returns the result of the staticbind
method.Implementation
intrinsic function bind(thisObj: Object=null, ...args) Function.helper::bind(this, thisObj, args);intrinsic::call ( thisObj= , ...args)
Description
The intrinsic
call
method calls the staticapply
method with the value ofthis
as the first argument.Returns
The intrinsic
call
method returns the result of the staticcall
method.Implementation
intrinsic function call(thisObj: Object=null, ...args) Function.apply(this, thisObj, args);Value properties of
Function
instanceslength
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 freshObject
instance.The value of the
prototype
property is used to initialise the internal[[Prototype]]
property of a newly created object before theFunction
instance is invoked as a constructor for that newly created object.Invoking the
Function
prototype objectWhen the
Function
prototype object is invoked it accepts any arguments and returns undefined:prototype meta function invoke(...args) undefined;Methods on the
Function
prototype objectThe 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: 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
Function
prototype objectlength
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 Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss