Re: length property value for functions with parameter enhancements
Just want to clarify that neither jQuery nor its selector engine Sizzle have any occurrences of function arity checking via the function length property. Both codebases have occurrences of arguments.length checking Rick On Mon, Aug 29, 2011 at 9:20 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: It looks like that in a number of these cases, what is being tested is the number of declared arguments to the jquery Sizzle function which is a module function for its selector engine. Very early versions of Sizzle seem to have had 3 formals ( https://github.com/jquery/sizzle/commit/51ba623126501dd9381040bbdcbabe12cc9056db#diff-0 ) but it fairly soon evolved to take 4 formals ( https://github.com/jquery/sizzle/blob/8b061ee512c50910d4e8e0247084446d03e90aa3/sizzle.js). I haven't found the code that does the actual test but this seems like the most likely reason to make such a test of that function. Presumably that sort of version testings is s plausible use case for a function's length although it isn't clear that it is any better than just putting a version tag property on such a function. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Thu, Sep 1, 2011 at 11:38 AM, Rick Waldron waldron.r...@gmail.comwrote: Just want to clarify that neither jQuery nor its selector engine Sizzle have any occurrences of function arity checking via the function length property. Both codebases have occurrences of arguments.length checking FTR this kind of arity checking is pretty common in the node.js world: https://github.com/kriszyp/promised-io/blob/master/promise.js#L619 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Sep 1, 2011, at 8:55 AM, Dean Landolt wrote: On Thu, Sep 1, 2011 at 11:38 AM, Rick Waldron waldron.r...@gmail.com wrote: Just want to clarify that neither jQuery nor its selector engine Sizzle have any occurrences of function arity checking via the function length property. Both codebases have occurrences of arguments.length checking FTR this kind of arity checking is pretty common in the node.js world: https://github.com/kriszyp/promised-io/blob/master/promise.js#L619 To clarify, it is indeed function arity checking that node.js is performing. In this case, it is assuming (maybe requiring is closer to fact) that all async functions take a callback as their last argument. and using that fact to generate wrapper functions that replace the callback function. This pattern would break under the proposal we are discussing if somebody tried to define an async function with default value or rest parameters. However, it would also break today if somebody tried to define an async function that solely used its arguments object to access arguments and neglected to declare any formal parameters. Presumably in either case node.js should tell its users not to use such parameter patterns in defining async functions. Regardless of whether or not we counted optional value parameters in determining the value of a function's length property this node.js pattern would be problematic if callers actually made use of the ability to optionally include/exclude default value arguments. So, it's not clear that this use case helps us much in design our length value algorithm. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
2011/8/30 Brendan Eich bren...@mozilla.com On Aug 30, 2011, at 2:16 PM, David Bruant wrote: Actually that's what current function proxies do by default (no .prototype unless otherwise specified). My suggestion is to put a .prototype by default with keeping the option to opt-out (same with .length, etc.) Right, of course function proxies have to trap in order to emulate .prototype and other properties. Indeed, that was our intent: fproxy.prototype and fproxy.length are determined by the handler via the get trap. This should work fine for fproxy.prototype (and it is actually consulted when evaluating |obj instanceof fproxy|.) For fproxy.length, the handler object can only return the call trap's length if it has a reference to the call trap, which as David points out, in the general case it does not. OTOH, typically a function proxy will wrap some other target function f, in which case the handler would simply return f.length, so I don't know whether this issue is such a big deal. If one wraps an existing function f using the default ForwardingHandler like so: var fproxy = Proxy.createFunction(new ForwardingHandler(f), f); Then fproxy.prototype, .length, .arguments, and .caller will all work as expected. So the default ForwardingHandler is in a sense already the convenient library that Andreas alluded to. I do notice that .prototype and .length are non-configurable properties, so that ups the ante for proxies being able to emulate non-configurable properties (more about that later). Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
Le 31/08/2011 13:24, Tom Van Cutsem a écrit : 2011/8/30 Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com On Aug 30, 2011, at 2:16 PM, David Bruant wrote: Actually that's what current function proxies do by default (no .prototype unless otherwise specified). My suggestion is to put a .prototype by default with keeping the option to opt-out (same with .length, etc.) Right, of course function proxies have to trap in order to emulate .prototype and other properties. Indeed, that was our intent: fproxy.prototype and fproxy.length are determined by the handler via the get trap. This should work fine for fproxy.prototype (and it is actually consulted when evaluating |obj instanceof fproxy|.) For fproxy.length, the handler object can only return the call trap's length if it has a reference to the call trap, which as David points out, in the general case it does not. OTOH, typically a function proxy will wrap some other target function f, in which case the handler would simply return f.length, so I don't know whether this issue is such a big deal. True. Still, a handler needs an access to the callTrap in order to retrieve its length in the general case. And with the current API, it may be impossible for an already created handler (not one created through a factory) to access to the callTrap, making impossible to access its .length and .prototype I agree that the typical case is to wrap, but is it a sufficient reason for people not wrapping to not be able to properly emulate function.length? If one wraps an existing function f using the default ForwardingHandler like so: var fproxy = Proxy.createFunction(new ForwardingHandler(f), f); Alternatively, i suggested earlier this summer [1] to put callTrap and constructTrap as part of the handler. This which would solve the problem of a handler having access to the callTrap (this.call from any other trap) and would also solve the question what if handler.call.length !== handler.construct.length? which would be left to the author discretion. David [1] https://mail.mozilla.org/pipermail/es-discuss/2011-August/016247.html ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
I coded up a hypothetical Proxy.createConstructor function that creates a function proxy initialized according to ES5.1 section 13.2: https://gist.github.com/1183514 Given the ease with which this can be expressed, I'm not sure it merits dedicated support, unless I overlooked something. Cheers, Tom 2011/8/31 Tom Van Cutsem tomvc...@gmail.com 2011/8/30 Brendan Eich bren...@mozilla.com On Aug 30, 2011, at 2:16 PM, David Bruant wrote: Actually that's what current function proxies do by default (no .prototype unless otherwise specified). My suggestion is to put a .prototype by default with keeping the option to opt-out (same with .length, etc.) Right, of course function proxies have to trap in order to emulate .prototype and other properties. Indeed, that was our intent: fproxy.prototype and fproxy.length are determined by the handler via the get trap. This should work fine for fproxy.prototype (and it is actually consulted when evaluating |obj instanceof fproxy|.) For fproxy.length, the handler object can only return the call trap's length if it has a reference to the call trap, which as David points out, in the general case it does not. OTOH, typically a function proxy will wrap some other target function f, in which case the handler would simply return f.length, so I don't know whether this issue is such a big deal. If one wraps an existing function f using the default ForwardingHandler like so: var fproxy = Proxy.createFunction(new ForwardingHandler(f), f); Then fproxy.prototype, .length, .arguments, and .caller will all work as expected. So the default ForwardingHandler is in a sense already the convenient library that Andreas alluded to. I do notice that .prototype and .length are non-configurable properties, so that ups the ante for proxies being able to emulate non-configurable properties (more about that later). Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
On 31 August 2011 15:21, Tom Van Cutsem tomvc...@gmail.com wrote: I coded up a hypothetical Proxy.createConstructor function that creates a function proxy initialized according to ES5.1 section 13.2: https://gist.github.com/1183514 Nit: invoking callTrap.call assumes that callTrap has an actual call method. But you want to work this for call traps that are themselves proxies and don't necessarily have that (or don't we?). So you need to do Function.prototype.apply.call(callTrap, instance, arguments) (assuming nobody messed with that either, of course). This turns up quite frequently, in fact. With proxies, it is really error-prone that all these functions have been made available as methods on {Object,Function}.prototype, instead of being separate. Morally, these methods used to be part of the implicit contracts of object and function types that everybody relies on. But proxies break those contracts! At least for functions, this is really a problem IMO (for plain objects, the contract was already invalidated by allowing Object.create(null)). /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
2011/8/29 Allen Wirfs-Brock al...@wirfs-brock.com I think 15.3.4.5 should be generalize so that the computation of the length property isn't predicted by [[Class]]=='Function' but instead should just use the the numeric value of the target's length property, if it exists. If the target does not have a length property or if its value is not a number then the bound function would get a length value of 0. That seems reasonable. I guess it implies that callable host objects that hitherto had a length of 0 might now have a different length, but for function proxies it seems like the right thing to do. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
Le 29/08/2011 16:43, Tom Van Cutsem a écrit : (changed subject to fork off discussion on function proxies) 2011/8/29 Allen Wirfs-Brock al...@wirfs-brock.com mailto:al...@wirfs-brock.com On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. I see two options here: a) either query the function proxy for its length property via its get trap, and convert the result using ToInteger, introducing a new error case if the conversion fails. b) or determine length based on the function proxy's call trap (which is presumably a non-proxy function. If it is a function proxy itself, recurse) The spec currently uses the wording: Let L be the length property of Target ... (ES5.1 section 15.3.4.5) If that is not equivalent to Let L be the result of calling the [[Get]] internal method of Target with argument length, then option b) seems better. There is no mention of function proxy lengths in harmony:proxies_semantics [1] nor in harmony:proxies and i'd like to discuss this. - var f = Proxy.createFunction(functionHandler, function(){}, function(){}) var l = f.length; // ? - Currently, nothing is really said about how is handled f.length, f.prototype and such. So, it seems to be left to the proxy author. In order to facilitate the author work, it could be possible to have an ES5.1-13.2-like function proxy constructor especially when it comes to steps 15, 17, 18 (i'm in doubt with steps 5 and 19). Step 15 would be a way for the engine to communicate with the handler to pass the [[Call]].length value. In order to initially set the length value, i think it would make sense to take [[Call]].length too (what if [[Call]].length !== [[Construct]].length?). Also, it would facilitate the way the handler has access to [[Call]].length when writing functionHandler.get and functionHandler.get{Own}PropertyDescriptor It could be left to the programmer the initiative to refuse the addition of the length property (if it's necessary to emulate an host object) (by returning false at the end of the defineProperty trap iirc) This would facilitate the author work when it comes to creating functions that look like functions without having to always include some initialization code for .length, .prototype and such. It will still be possible to opt-out of .length or .prototype if the author doesn't David [1] http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics [2] http://wiki.ecmascript.org/doku.php?id=strawman:fixed_properties ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
On 30 August 2011 18:41, David Bruant david.bru...@labri.fr wrote: This would facilitate the author work when it comes to creating functions that look like functions without having to always include some initialization code for .length, .prototype and such. It will still be possible to opt-out of .length or .prototype if the author doesn't I don't think it's worth introducing special cases in the semantics, especially not for something like length. Proxy authors already have to do a lot of similar work, e.g. to make all the standard Object.prototype and Function.prototype methods available on proxies. I think this problem is something that should be solved by the library, not the proxy API itself. Maybe we can find some nice building blocks for handlers that make available the basic functionality in a convenient and extensible way? Another interesting case btw (although outside the standard proper) is __proto__... /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
Le 30/08/2011 21:40, Brendan Eich a écrit : On Aug 30, 2011, at 11:00 AM, Andreas Rossberg wrote: On 30 August 2011 18:41, David Bruant david.bru...@labri.fr mailto:david.bru...@labri.fr wrote: This would facilitate the author work when it comes to creating functions that look like functions without having to always include some initialization code for .length, .prototype and such. It will still be possible to opt-out of .length or .prototype if the author doesn't I don't think it's worth introducing special cases in the semantics, especially not for something like length. Perhaps, but I think David has a stronger case for opting out of .prototype. Actually that's what current function proxies do by default (no .prototype unless otherwise specified). My suggestion is to put a .prototype by default with keeping the option to opt-out (same with .length, etc.) Indeed self-hosting some of the ES1-5 builtins requires doing so, somehow. Couldn't it be achived with bound functions (which do not have an own prototype property)? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
On Aug 30, 2011, at 2:16 PM, David Bruant wrote: Le 30/08/2011 21:40, Brendan Eich a écrit : On Aug 30, 2011, at 11:00 AM, Andreas Rossberg wrote: On 30 August 2011 18:41, David Bruant david.bru...@labri.fr wrote: This would facilitate the author work when it comes to creating functions that look like functions without having to always include some initialization code for .length, .prototype and such. It will still be possible to opt-out of .length or .prototype if the author doesn't I don't think it's worth introducing special cases in the semantics, especially not for something like length. Perhaps, but I think David has a stronger case for opting out of .prototype. Actually that's what current function proxies do by default (no .prototype unless otherwise specified). My suggestion is to put a .prototype by default with keeping the option to opt-out (same with .length, etc.) Right, of course function proxies have to trap in order to emulate .prototype and other properties. Indeed self-hosting some of the ES1-5 builtins requires doing so, somehow. Couldn't it be achived with bound functions (which do not have an own prototype property)? Built-ins do not bind |this|, though -- many are generic (IIRC these are the ones V8 self-hosts). Also, binding costs memory and cycles, it hurts a bit when creating these things. This can add up. /be___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On 29 August 2011 01:36, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. Ah, right, I was looking at the 5.0 spec 8-}. However, that is still not good enough for function proxies, because you have no guarantee that they define length at all, or make it a natural number. So we at least have to include additional error cases, and a solution for them. function bam(a,b,c=0,...d) {} //bam.length==2 BTW, is this legal? Makes sense. (And yes, I don't see why the latter shouldn't be legal.) Because the is a potential for misinterpreting the user intent on such a call. For bam('a','b',1,2,3) we surely have to interpret the argument/parameter mapping as: a='a',b='b',c=1,d=[2,3] but it is easy to imagine a programmer intending a='a',b='b',c=0,d=[1,2,3] Making it illegal to have a formal parameter list that has both optional and result parameters might result the likelihood of that confusion, Hm, that doesn't sound like a very JavaScripty argument :). If you buy into optional arguments at all, then I can certainly envision valid use cases for combining them with rest arguments. If there are no non-optional or non-rest formal parameters the length is 1. function bar1(a=0) {} //bar1.length=1 function baz1(a=0,b=1,c=2) {} //baz1.length=1 function bam1(...a) {} //bam1.length==1 I'm not so sure about this, it seems incoherent. Why not 0, especially for the first two? You mentioned builtins like Array above, but I would rather count them as the exception to the rule (especially given that the builtins don't seem entirely consistent wrt length anyway). In my proposal, I am decided to make a clear distinction between truly empty formal parameter lists and those with only various forms of optional formal parameters by only giving a 0 length to the empty formals case. That's a debatable decision but it seems desirable to distinguish the two cases and the built-ins is the only precedent that we have to follow. I guess I don't see what is special about empty argument lists. Why would you want to make a clearer distinction between the argument lists () and (a=0), than between (x) and (x, a=0)? You seem to be introducing a discontinuity. FWIW, one could also argue for setting length to +infinity for functions with only rest parameters. :) But there is no precedent for that and surely infinity is not the typical number of arguments. Yeah, I wasn't being serious. I'm not sure if there is any real use case for the length property of ECMAScript functions. Does anybody know of one? Regardless, I do think we can get rid of it. Do not, I suppose? (Unfortunately, as I was wondering the same.) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Function proxy length (Was: length property value for functions with parameter enhancements)
(changed subject to fork off discussion on function proxies) 2011/8/29 Allen Wirfs-Brock al...@wirfs-brock.com On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. I see two options here: a) either query the function proxy for its length property via its get trap, and convert the result using ToInteger, introducing a new error case if the conversion fails. b) or determine length based on the function proxy's call trap (which is presumably a non-proxy function. If it is a function proxy itself, recurse) The spec currently uses the wording: Let L be the length property of Target ... (ES5.1 section 15.3.4.5) If that is not equivalent to Let L be the result of calling the [[Get]] internal method of Target with argument length, then option b) seems better. There is precedent for using the call trap as a substitute for the function proxy: Function.prototype.toString.call(aFunctionProxy) will also use the call trap's toString representation rather than trapping the handler. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
On Mon, Aug 29, 2011 at 7:43 AM, Tom Van Cutsem tomvc...@gmail.com wrote: (changed subject to fork off discussion on function proxies) 2011/8/29 Allen Wirfs-Brock al...@wirfs-brock.com On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. I see two options here: a) either query the function proxy for its length property via its get trap, and convert the result using ToInteger, introducing a new error case if the conversion fails. b) or determine length based on the function proxy's call trap (which is presumably a non-proxy function. If it is a function proxy itself, recurse) The spec currently uses the wording: Let L be the length property of Target ... (ES5.1 section 15.3.4.5) If that is not equivalent to Let L be the result of calling the [[Get]] internal method of Target with argument length, then option b) seems better. There is precedent for using the call trap as a substitute for the function proxy: Function.prototype.toString.call(aFunctionProxy) will also use the call trap's toString representation rather than trapping the handler. I don't have any strong preference regarding #a vs #b. However, I don't think Function.prototype.toString.call(aFunctionProxy) is a relevant precedent. For .length, we have the choice of #a or #b. For ...toString.call, what other option could there be besides the choice we made? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Function proxy length (Was: length property value for functions with parameter enhancements)
On Aug 29, 2011, at 7:43 AM, Tom Van Cutsem wrote: (changed subject to fork off discussion on function proxies) 2011/8/29 Allen Wirfs-Brock al...@wirfs-brock.com On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. I see two options here: a) either query the function proxy for its length property via its get trap, and convert the result using ToInteger, introducing a new error case if the conversion fails. b) or determine length based on the function proxy's call trap (which is presumably a non-proxy function. If it is a function proxy itself, recurse) The spec currently uses the wording: Let L be the length property of Target ... (ES5.1 section 15.3.4.5) If that is not equivalent to Let L be the result of calling the [[Get]] internal method of Target with argument length, then option b) seems better. It should be considered to be a [[Get]] (and should be restarted as such). A deeper question is whether or not function proxy objects are ES5 [[Class]]=='Function' objects (regardless of how this is actually expressed in the ES6 spec.) For ES5, the distinction between objects that are callable and more specific objects where [[Class]]=='Function' was that [[Class]]=='Function' implies all of the invariants from sections 13.2 and 15.3 and their subsections while isCallable only means that the object supports [[Call]]. For example, such object always have a immutable 'length' property whose value is a number but host objects that are callable might not have such a property. Hence the test in 15.3.4.5 step 15. Because of their nature, it would seem unreasonable to assume that function proxy objects conform to all of the 13.2 and 15.3 invariants. That means that according to 15.3.4.5 a bound function that targets a function proxy would have a length of 0. That doesn't seem quite right either. I think 15.3.4.5 should be generalize so that the computation of the length property isn't predicted by [[Class]]=='Function' but instead should just use the the numeric value of the target's length property, if it exists. If the target does not have a length property or if its value is not a number then the bound function would get a length value of 0. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Aug 29, 2011, at 2:32 AM, Andreas Rossberg wrote: On 29 August 2011 01:36, Allen Wirfs-Brock al...@wirfs-brock.com wrote: On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. Ah, right, I was looking at the 5.0 spec 8-}. However, that is still not good enough for function proxies, because you have no guarantee that they define length at all, or make it a natural number. So we at least have to include additional error cases, and a solution for them. those cases probably fall under step 16 of 15.3.4.5 but we'll have to be more explicit about that. function bam(a,b,c=0,...d) {} //bam.length==2 BTW, is this legal? Makes sense. (And yes, I don't see why the latter shouldn't be legal.) Because the is a potential for misinterpreting the user intent on such a call. For bam('a','b',1,2,3) we surely have to interpret the argument/parameter mapping as: a='a',b='b',c=1,d=[2,3] but it is easy to imagine a programmer intending a='a',b='b',c=0,d=[1,2,3] Making it illegal to have a formal parameter list that has both optional and result parameters might result the likelihood of that confusion, Hm, that doesn't sound like a very JavaScripty argument :). If you buy into optional arguments at all, then I can certainly envision valid use cases for combining them with rest arguments. Which is the source of the potential confusion because all of the optional parameters get populated with values before the rest argument gets any values. ... In my proposal, I am decided to make a clear distinction between truly empty formal parameter lists and those with only various forms of optional formal parameters by only giving a 0 length to the empty formals case. That's a debatable decision but it seems desirable to distinguish the two cases and the built-ins is the only precedent that we have to follow. I guess I don't see what is special about empty argument lists. Why would you want to make a clearer distinction between the argument lists () and (a=0), than between (x) and (x, a=0)? You seem to be introducing a discontinuity. Given, that I have yet to think of a reasonable use case for function length properties, all of these rationalizations a pretty conceptual. However, () seems like a clear statement that no arguments are required or expected while (a=0) says that an argument does have some meaning. This seems like a worthwhile distinction to make even though 1 may not be the typical number of arguments. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Aug 28, 2011, at 4:36 PM, Allen Wirfs-Brock wrote: On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: On 27 August 2011 00:34, Allen Wirfs-Brock al...@wirfs-brock.com wrote: If the formal parameter list includes any non-optional, non-rest formal parameters, the length is the total number of non-optional/non-rest formal parameters. For example: function bar(a,b,c) {} //bar.length=3 function baz(a,b,c=0) {} //baz.length=2 function bam(a,b,c=0,...d) {} //bam.length==2 BTW, is this legal? Makes sense. (And yes, I don't see why the latter shouldn't be legal.) Because the is a potential for misinterpreting the user intent on such a call. For bam('a','b',1,2,3) we surely have to interpret the argument/parameter mapping as: a='a',b='b',c=1,d=[2,3] but it is easy to imagine a programmer intending a='a',b='b',c=0,d=[1,2,3] Making it illegal to have a formal parameter list that has both optional and result parameters might result the likelihood of that confusion, That's too restrictive. There are lots of ways to go wrong in JS, we don't try to put programmers in a five-point harness. Python: def foo(a,b,c=1,*d): ... print(a, b, c, d) ... foo(0,1,2,3,4) 0 1 2 (3, 4) foo(0,1,2,3) 0 1 2 (3,) foo(0,1,2) 0 1 2 () foo(0,1) 0 1 1 () (Python reflects rest params [splats] as tuples not lists.) Ruby is of course pretty similar: def foo(a,b,c=1,*d) print a, b, c, d, \n end foo(0,1,2,3,4) foo(0,1,2,3) foo(0,1,2) foo(0,1) ^D 01234 0123 012 011 (My Ruby REPL skills are sad -- ugly run-together stdout follows the TTY EOF ^D above.) If there are no non-optional or non-rest formal parameters the length is 1. function bar1(a=0) {} //bar1.length=1 function baz1(a=0,b=1,c=2) {} //baz1.length=1 function bam1(...a) {} //bam1.length==1 I'm not so sure about this, it seems incoherent. Why not 0, especially for the first two? You mentioned builtins like Array above, but I would rather count them as the exception to the rule (especially given that the builtins don't seem entirely consistent wrt length anyway). In my proposal, I am decided to make a clear distinction between truly empty formal parameter lists and those with only various forms of optional formal parameters by only giving a 0 length to the empty formals case. That's a debatable decision but it seems desirable to distinguish the two cases and the built-ins is the only precedent that we have to follow. You make a distinction but create an ambiguity between function foo(a=0)... // length 1 function bar(a=0,b=1) // length 1 That seems no more consistent (and less coherent as Andreas put it). If trailing optional parameters do not contribute to length, then we have a consistent single rule for length. That it does not match all built-ins is sad history, not to be rewritten lightly but not to overdetermine the future. I'm not sure if there is any real use case for the length property of ECMAScript functions. Does anybody know of one? Regardless, I do think we can get rid of it. Working on instrumentation to find uses on the web. More in a bit, /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Aug 29, 2011, at 11:29 AM, Allen Wirfs-Brock wrote: Hm, that doesn't sound like a very JavaScripty argument :). If you buy into optional arguments at all, then I can certainly envision valid use cases for combining them with rest arguments. Which is the source of the potential confusion because all of the optional parameters get populated with values before the rest argument gets any values. There's no confusion, IMHO. The order is left to right -- this matters for parameter default values in and of themselves. The precedent in nearby languages is strong. I am pretty opposed to making this an error case. It cannot of course be a case where right-to-left evaluation happens in any form (rest parameter eats actuals, leaving none in the middle for default parameters). I guess I don't see what is special about empty argument lists. Why would you want to make a clearer distinction between the argument lists () and (a=0), than between (x) and (x, a=0)? You seem to be introducing a discontinuity. Given, that I have yet to think of a reasonable use case for function length properties, all of these rationalizations a pretty conceptual. However, () seems like a clear statement that no arguments are required or expected while (a=0) says that an argument does have some meaning. This seems like a worthwhile distinction to make even though 1 may not be the typical number of arguments. You can't use one integer-valued property to convey two meanings. F.length is either minimum non-default/rest parameters, or a count of non-rest parameters. I don't see a sane alternative. The count of non-rest parameters is not that interesting, since it is one fewer than the full count of all parameters (modulo destructuring, where it must count each actual position, not all the names of destructured-to formals). That leaves F.length counting only non-default/rest params. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Aug 29, 2011, at 1:36 PM, Brendan Eich wrote: You can't use one integer-valued property to convey two meanings. F.length is either minimum non-default/rest parameters, or a count of non-rest parameters. I don't see a sane alternative. The count of non-rest parameters is not that interesting, since it is one fewer than the full count of all parameters (modulo destructuring, where it must count each actual position, not all the names of destructured-to formals). That leaves F.length counting only non-default/rest params. I can think of two more plausible ones: 1) the number of parameter positions specified in the formal parameter list include (I'm avoiding talking about names because of destructing): function (a,b=1,...c) {} //length==3 function (...c) {} // length=1 2) the number of parameter positions (including the rest parameter if specified) that precede the first default-value parameter (or the end of the list if there are no default-value parameters): function (a,b,c) {} //length==3 function (a,b,...c) {} //length==3 function (...c) {} // length=1 function (a=1,b=2) {} //length==0 function (a,b=1) {} //length==1 function (a,b=1,...c) {} //length==1 1) is the simplest rule and in the absence of a clear use case is probably as good as any other 2) Treats rest as meaning usually at least one (unless following a default-value parameter) which seems to be the way open-ended parameter lists were interpreted in assigning length to most such Chapter 15 functions. I think that this rule would yield the most matches with the specified lengths of chapter 15 functions when their signatures are rewritten using default-value and rest parameter notation. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
Here's a log with complete decompilation including the function whose .length was accessed. file:line length function /be funlen.log Description: Binary data ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
It looks like that in a number of these cases, what is being tested is the number of declared arguments to the jquery Sizzle function which is a module function for its selector engine. Very early versions of Sizzle seem to have had 3 formals (https://github.com/jquery/sizzle/commit/51ba623126501dd9381040bbdcbabe12cc9056db#diff-0 ) but it fairly soon evolved to take 4 formals (https://github.com/jquery/sizzle/blob/8b061ee512c50910d4e8e0247084446d03e90aa3/sizzle.js ). I haven't found the code that does the actual test but this seems like the most likely reason to make such a test of that function. Presumably that sort of version testings is s plausible use case for a function's length although it isn't clear that it is any better than just putting a version tag property on such a function. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On Aug 27, 2011, at 6:12 AM, Andreas Rossberg wrote: On 27 August 2011 00:34, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Something we need to define for ES.next is how to compute the length property value for functions whose formal parameter list includes optional and/or rest parameters. True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? The ES5.1 spec. defines how how bind determines the length for the function it creates based upon the length property of the target function. I would expect the same rules would apply when the target is a function proxy. This is probably something the proxy proposal has to resolve eventually, but it's worth keeping in mind for the broader picture. So, what is a length determination algorithm that recognizes optional/rest arguments and is consistent with the stated intent of length and (as much as possible)existing section 15 definitions. Here is one proposal: The length is 0 only if the formal parameter list is empty. For example: function foo() {}; //foo.length==1 You meant ==0 here, right? right If the formal parameter list includes any non-optional, non-rest formal parameters, the length is the total number of non-optional/non-rest formal parameters. For example: function bar(a,b,c) {} //bar.length=3 function baz(a,b,c=0) {} //baz.length=2 function bam(a,b,c=0,...d) {} //bam.length==2 BTW, is this legal? Makes sense. (And yes, I don't see why the latter shouldn't be legal.) Because the is a potential for misinterpreting the user intent on such a call. For bam('a','b',1,2,3) we surely have to interpret the argument/parameter mapping as: a='a',b='b',c=1,d=[2,3] but it is easy to imagine a programmer intending a='a',b='b',c=0,d=[1,2,3] Making it illegal to have a formal parameter list that has both optional and result parameters might result the likelihood of that confusion, If there are no non-optional or non-rest formal parameters the length is 1. function bar1(a=0) {} //bar1.length=1 function baz1(a=0,b=1,c=2) {} //baz1.length=1 function bam1(...a) {} //bam1.length==1 I'm not so sure about this, it seems incoherent. Why not 0, especially for the first two? You mentioned builtins like Array above, but I would rather count them as the exception to the rule (especially given that the builtins don't seem entirely consistent wrt length anyway). In my proposal, I am decided to make a clear distinction between truly empty formal parameter lists and those with only various forms of optional formal parameters by only giving a 0 length to the empty formals case. That's a debatable decision but it seems desirable to distinguish the two cases and the built-ins is the only precedent that we have to follow. FWIW, one could also argue for setting length to +infinity for functions with only rest parameters. :) But there is no precedent for that and surely infinity is not the typical number of arguments. I'm not sure if there is any real use case for the length property of ECMAScript functions. Does anybody know of one? Regardless, I do think we can get rid of it. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: length property value for functions with parameter enhancements
On 27 August 2011 00:34, Allen Wirfs-Brock al...@wirfs-brock.com wrote: Something we need to define for ES.next is how to compute the length property value for functions whose formal parameter list includes optional and/or rest parameters. True, and actually, there are more issues with length function proxies. I don't have my notes with me right now, but for example, it is not clear at all what length Function.prototype.bind should set when called on a function proxy. 0? 1? Should it try to get the length property from the proxy and subtract N? What if length is not defined on the proxy, or not a (natural) number? This is probably something the proxy proposal has to resolve eventually, but it's worth keeping in mind for the broader picture. So, what is a length determination algorithm that recognizes optional/rest arguments and is consistent with the stated intent of length and (as much as possible)existing section 15 definitions. Here is one proposal: The length is 0 only if the formal parameter list is empty. For example: function foo() {}; //foo.length==1 You meant ==0 here, right? If the formal parameter list includes any non-optional, non-rest formal parameters, the length is the total number of non-optional/non-rest formal parameters. For example: function bar(a,b,c) {} //bar.length=3 function baz(a,b,c=0) {} //baz.length=2 function bam(a,b,c=0,...d) {} //bam.length==2 BTW, is this legal? Makes sense. (And yes, I don't see why the latter shouldn't be legal.) If there are no non-optional or non-rest formal parameters the length is 1. function bar1(a=0) {} //bar1.length=1 function baz1(a=0,b=1,c=2) {} //baz1.length=1 function bam1(...a) {} //bam1.length==1 I'm not so sure about this, it seems incoherent. Why not 0, especially for the first two? You mentioned builtins like Array above, but I would rather count them as the exception to the rule (especially given that the builtins don't seem entirely consistent wrt length anyway). FWIW, one could also argue for setting length to +infinity for functions with only rest parameters. :) /Andreas ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss