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
length
mutable on functions?Writing to
length
could be a useful functionality for library code. For instance, implementing something likebind
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 onFunction.prototype
, so an ES6 library has no need to implement it. I'm only using bind as an example to establish?precedent?that writablelength
could be useful in implementing function wrappers. ?Consider as a more necessary example implementing anuncurryThis
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: Athis
argument,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
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. Writablelength
would help a lot.