Mutable `length` for functions?

Brendan Eich brendan at mozilla.com
Tue Feb 26 11:22:03 PST 2013


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?

/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
>


More information about the es-discuss mailing list