Mutable `length` for functions?
An alternative to a writable length property, is to make it configurable and nonwritable. It would prevent the issue of accidental assignments to the length property that used be ignored in non-strict mode (they'll still be ignored), but it would allow to modify its value using Object.defineProperty.
-Claude
Claude Pache wrote:
An alternative to a writable 'length' property, is to make it configurable and nonwritable. It would prevent the issue of accidental assignments to the 'length' property that used be ignored in non-strict mode (they'll still be ignored), but it would allow to modify its value using Object.defineProperty.
That's not half-bad.
I used to tell Allen I saw no purpose in non-writable but configurable, but against the backdrop of JS history, I see it.
Mark, does this cause SES problems?
[+google-caja-discuss]
I don't see any problems for SES. cc'ing google-caja-discuss in case someone there spots something I missed. Anyone?
Assuming there are no problems, I like this for all the reasons stated.
On Feb 26, 2013, at 11:22 AM, Brendan Eich wrote:
Claude Pache wrote:
An alternative to a writable 'length' property, is to make it configurable and nonwritable. It would prevent the issue of accidental assignments to the 'length' property that used be ignored in non-strict mode (they'll still be ignored), but it would allow to modify its value using Object.defineProperty.
That's not half-bad.
I used to tell Allen I saw no purpose in non-writable but configurable, but against the backdrop of JS history, I see it.
Like I've said before, I play the long game. Eventually you usually come around :-)
I think non-writable/configurable properties a very nice balance point between those developer who value the mutable/hackable/patchable nature of JS and those who desire to minimize JS foot-guns. If you know what you are doing you can modify them using Object.defineProperty but a naive assignment will fail (noisily in strict mode).
If we start to appreciate this distinction, there are probably a few other ES6 properties that this would make sense for. The "constructor" property on prototype objects created by class definitions is one that immediately comes to mind.
Allen Wirfs-Brock wrote:
Like I've said before, I play the long game. Eventually you usually come around:-)
Except when you're off target :-P.
But good long-game on this one -- well played!
Would it be possible to make / what are the thoughts on making
lengthmutable on functions?Writing to
lengthcould be a useful functionality for library code. For instance, implementing something likebindcorrectly requires the arity of the bound function to be the same as the original function minus the number of preloaded arguments.Simplified example:
var slice = Function.prototype.call.bind(Array.prototype.slice); function bind(f, thisArg, ...args) { function bound() { return f.apply(thisArg, args.concat(slice(arguments))); } var L = f.length - args.length; bound.length = L > 0 ? L : 0; return bound; }Of course,
bindis already onFunction.prototype, so an ES6 library has no need to implement it. I'm only using bind as an example to establish?precedent?that writablelengthcould be useful in implementing function wrappers. ?Consider as a more necessary example implementing anuncurryThisfunction.var uncurryThis = Function.prototype.bind.bind(Function.prototype.call); function foo(a, b, c) { /* ... */ } var uFoo = uncurryThis(foo); console.log( foo.length, // => 3 uFoo.length // => 1 );This is problematic because we lose information about the arity of the
uFoofunction which actually takes 4 arguments now: Athisargument,a,b, andc. ?A simple solution would be to write an uncurryThis which corrects the arity:var bind = Function.prototype.call.bind(Function.prototype.bind), callMethod = Function.prototype.call; function uncurryThis(fn) { var F = bind(callMethod, fn); // Correct arity. F.length = fn.length + 1; return F; } function foo(a, b, c) { /* ... */ } var uFoo = uncurryThis(foo); console.log( foo.length, // => 3 uFoo.length // => 4 );Currently I have resorted to an
evalbased solution for creating wrapper functions which are defined with the correct number of arguments when a certain arity is desired. Obviously this is not ideal. Writablelengthwould help a lot.Would it be possible to make / what are the thoughts on making `length` mutable on functions? Writing to `length` could be a useful functionality for library code. For instance, implementing something like `bind` correctly requires the arity of the bound function to be the same as the original function minus the number of preloaded arguments. Simplified example: var slice = Function.prototype.call.bind(Array.prototype.slice); function bind(f, thisArg, ...args) { function bound() { return f.apply(thisArg, args.concat(slice(arguments))); } var L = f.length - args.length; bound.length = L > 0 ? L : 0; return bound; } Of course, `bind` is already on Function.prototype, so an ES6 library has no need to implement it. I'm only using bind as an example to establish precedent that writable `length` could be useful in implementing function wrappers. Consider as a more necessary example implementing an `uncurryThis` function. var uncurryThis = Function.prototype.bind.bind(Function.prototype.call); function foo(a, b, c) { /* ... */ } var uFoo = uncurryThis(foo); console.log( foo.length, // => 3 uFoo.length // => 1 ); This is problematic because we lose information about the arity of the `uFoo` function which actually takes 4 arguments now: A `this` argument, `a`, `b`, and `c`. A simple solution would be to write an uncurryThis which corrects the arity: var bind = Function.prototype.call.bind(Function.prototype.bind), callMethod = Function.prototype.call; function uncurryThis(fn) { var F = bind(callMethod, fn); // Correct arity. F.length = fn.length + 1; return F; } function foo(a, b, c) { /* ... */ } var uFoo = uncurryThis(foo); console.log( foo.length, // => 3 uFoo.length // => 4 ); Currently I have resorted to an `eval` based solution for creating wrapper functions which are defined with the correct number of arguments when a certain arity is desired. Obviously this is not ideal. Writable `length` would help a lot. Thoughts? Nathan