suggestion: mapping symbolic infix ops to binary functions

Claus Reinke claus.reinke at talk21.com
Mon Jul 23 02:08:37 PDT 2012


> We've already been looking at value types, proxies, and objects for a 
> while. The latest, 
> http://wiki.ecmascript.org/doku.php?id=strawman:value_objects, does 
> not expose user-defined operators, to separate concerns and limit 
> scope, but user operators are doable.

I know, but previous strawmen tended to focus on overloading the 
existing operators, not on user operators. At the same time, new
infix operators keep getting proposed.

As far as I can tell, the issues are complementary:
1 how to define new operators
2 how to overload existing operators

Functional style wants 1, object-oriented style wants 2. But no
matter which of the two is used as basis, both points are needed.

Also, the 3rd example in sample.js shows that there isn't always 
an object to hang the operator on, which is why I introduce a 
separate object for operators.

> Just for the record, not to say experiments aren't helpful: we 
> aren't going to use mangled names starting with dot, or clump 
> user-defined operators at left-associative low precedence. 
> Those are anti-goals, really.

Of course - hence the TODO list at the top of 

    https://gist.github.com/3157251#file_infix.js

I just want to gauge interest before investing more time/work -
it is a sketch, not a blueprint, and I listed the missing features. 

I posted the sketch because, even in its impoverished form, it 
allows for useful experimentation (many of the infix op proposals 
posted here could be prototyped, as could the overloading 
resolution algorithm you explained). Not having to hack any
lexers/parser themselves might encourage people to experiment. 
Smalltalk's infix 'ops' have equal precedence, left associative, 
don't they?

The dot prefix was introduced to limit the impact on the lexer/
tokenizer, and it also helps to avoid getting in conflict with 
the many symbolic syntax proposals on es-discuss (eg, I couldn't 
remember whether '#' was used for one of the short function
proposals or one of the object/class literal ones, or which other
symbols are taken for which active/deferred/rejected strawmen). 
It makes user operators immediately distinguishable from 
language operators.

> The dispatch mechanism for dyadic operators is equivalent to 
> multimethods, but cacheable in modern JITs, and modular in the sense 
> that double-dispatch is not. This was proposed by Christian Plesner 
> Hansen here in 2009:
> 
> https://mail.mozilla.org/pipermail/es-discuss/2009-June/009603.html
> 
> From the patch for bug 749786:
> .. operator overloading resolution algorithm ..

Interesting, but see 1 below for an issue with this.
 
>    To support operator overloading in-language, we need only 
>    provide an API similar to the one Christian proposed:
> ..
>     Function.defineOperator('+', addPointAndNumber, Point, Number);

Thanks, that is exactly the part I'm interested in:

1. how would this work for 'obj .? prop' (select 'prop' if 'obj' is 
    defined, return 'undefined' otherwise)?

    Function.defineOperator('.?', (obj,prop)=>obj[prop], Object, String);
    Function.defineOperator('.?', _=>undefined, undefined, String);

    It seems the dispatcher needs adjustment for cases like this,
    as there may be no left operand object on which to store the
    LOP_PLUS type list. Or am I missing something about value
    objects?

2. how would associativity/precedence be specified?

    associativity can simply be some string, similar to the Prolog 
        or Haskell variations (xfy/yfx or infixl/infixr)

    precedence is traditionally done by numbers (Prolog,Haskell)
        but absolute numbering tends to be awkward, so relative
        precedence ('.?' same as '.', '*' before '+') would be better

    Since the multimethod-style API spreads out operator
    definitions over pairs of types, one would probably need
    a separate API call:

     Function.declareOperator('.?',{associate:'left',precedence:'.'});
 
> I plan to prototype the Function.defineOperator API too, after first 
> writing it up as a strawman and discussing it with TC39ers.

Looking forward to the API strawman. It would be preferable
to sort this out once and for all, before adding any more infix
operators to the language spec.

Perhaps my infix.js could help to prototype API alternatives,
and towards a polyfill for older JS implementations?

Claus
 


More information about the es-discuss mailing list