Mutable `length` for functions?

Allen Wirfs-Brock allen at wirfs-brock.com
Tue Feb 26 12:23:30 PST 2013


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








> 
> Mark, does this cause SES problems?
> 
> /be
>> 
>> —Claude
>> 
>> Le 25 févr. 2013 à 07:27, Nathan Wall<nathan.wall at live.com>  a écrit :
>> 
>>> 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 		 	   		
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>> 
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 



More information about the es-discuss mailing list