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