Function length

Russell Leggett russell.leggett at
Wed Jun 13 06:25:32 PDT 2012

On Wed, Jun 13, 2012 at 5:29 AM, Andreas Rossberg <rossberg at>wrote:

> On 12 June 2012 23:57, Russell Leggett <russell.leggett at> wrote:
> > This thread gave me an interesting idea on how to possibly attack pattern
> > matching in ES6 with no new syntax, and still leave room for more sugar
> > later. It actually comes from thinking about the original issue with
> > function.length and using it for arity-based dispatch. What if we just
> gave
> > a better method than length? What if we had something like
> > function.matches(args)? Where it would return true if all arguments were
> > bound, and no parameters resulted in an undefined binding.
> >     function add(a,b){
> >         return a + b;
> >     }
> >
> >     add.matches(1,2); // => true
> >     add.matches(1); // => false
> >     add.matches(1,2,3);  => false
> OK, I'll bite. I see lots of problems and unnecessary complexity here.
> If I understand this correctly, then it will require every function
> closure to include meta information for performing the associated
> pattern match. Or, when you actually want this to be optimised, the
> ability to generate (probably lazily) and attach pattern matching code
> to _every_ function closure. That seems pretty intrusive.

I'll respond a little out of order by saying that you believe patterns
independently implemented would be simple and efficient. If that is the
case (and I would think it was), then I don't really see how your argument
holds water. Let's just say we actually had patterns. I'll make an
imaginary syntax for them.

    let pattern = #({x,y});

If my example pattern could be done simply and efficiently, then why
couldn't the same be done for function arguments. The only meta-data you
would need to store is exactly the pattern that is in the function
parameters. The body of the function provides no additional data. You could
either eagerly generate the pattern, or simply keep the parameter pattern
ast in the most efficient form to generate it lazily.

The simple (and overwhelmingly most common case) would just be a list of
parameters with no rest and no destructuring. Matching against this would
reduce to a simple arity check.

> Also, the programmer would have to create a closure for every match
> arm you ever want to use (unless the compiler is "sufficiently clever"
> to recognise rather non-trivial patterns, which I doubt). That is
> likely to be pretty costly.

I guess to me this is just functional programming - its effectively a
callback for each pattern. The one which matches gets called. I don't see
why its so different than using forEach instead of a for loop. One is more
expressive and functional style, the other is more efficient.

> I'm also not sure how you envision
> actually binding variables during a match. Are you suggesting that one
> does something like:
>  if (f.matches(x, y)) f(x, y)

> Even if this is abstracted into some 'match' function, a match would
> redundantly decompose x, y for f twice.

That is true. Perhaps a builtin Object.match function could optimize?
Still, it does not seem overwhelmingly inefficient, just not as nice as
built in pattern matching.

> And just to be clear, this feature also reveals implementation details
> of a function that it shouldn't. For example, it allows you to observe
> cases where a function ignores some of its documented arguments, or
> some parts of its arguments. So it has all the bad properties of the
> 'isBound' function we discussed earlier.

I mostly disagree. The signature of a function is it's interface. Even Java
let's you reflectively ask about a method's signature. In reality, it is
almost no different than function.length in terms of revealing
implementation details. My major problem with isBound is that it required
looking at the body of the function, because |this| isn't something you'll
see in a parameter list.

However, as I said, I only *mostly* disagree. The same reason I initially
cringed at Irakli's function.length request because I worried how it would
be abused, I have some of the same worries here. It could make for some
pretty subtle code to change what arguments you send a callback based on
its signature – but unlike function.isBound which I think had fewer
appropriate use cases and looked at the method body, I think
function.matches has a much clearer use case and does not expose too much.
I especially like it in the case of using it with arrow functions, which
have no |this| and no access to an arguments object. I debated about
suggesting it only be available on arrow functions, but I think there are
some big downsides to that too.

> I'd say (despite being part of the pattern matching choir) that this
> is not the proper way to introduce a feature that, as a proper
> language construct, would be relatively simple, efficient, and
> independent of anything else.

I would much prefer to have it as a full, proper language construct, and I
would not have suggested function.matches if I thought it would be future
unfriendly to adding them. On the contrary, my hope is that this would be a
low footprint feature, but would provide the tool missing to allow for the
community to play with patterns. One of the great things about JavaScript
is its flexibility, and the community has really used that to create the
cowpaths we later pave. As a way of figuring out the best way to add full
patterns to the language, wouldn't it be helpful to give people this small
feature and see what the result is? The more pattern-like destructuring
becomes, the more people will want to use it for that purpose. This is the
hook needed to easily expose that. And even if pattern-matching becomes
first class, I think there will still be cases when functions-as-patterns
would still be useful.

- Russ
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list