Translation of pattern matching

Maurizio Cimadamore maurizio.cimadamore at
Fri Aug 4 20:19:32 UTC 2017

Maybe I'm missing something - but I think there is a disconnect between 
this code and what the DtorHandle really looks like (described here 
[1]). More specifically, operations like 'component' do not give you 
access to bindings, they return method handles which can be used to 
access the binding that is stored on some opaque carrier (Brian please 
correct me if wrong).

[1] -

On 04/08/17 12:49, Remi Forax wrote:
> Ok, i do not understand the translation of pattern matching to bytecode,
> it seems that something is missing.
> Here is the example of translation that Brian uses in its talk last Wednesday,
> static final DtorHandle p1 = ... LDC dtor for NegNode(NegNode(var n)) ...
> static final DtorHandle p2 = ... LDC dtor for NegNode(var n) ...
> static final DtorHandle p3 = ... LDC dtor for AddNode(IntNode(0), var right) ...
> Node simplify(Node n) {
>      int selector = indy[ bsm=Switchomatic, args=[p1, p2, p3 ... ] ](n)
>      return switch(selector) {
>          case 0 -> n;
>          case 1 -> let int n=p1.component(0) in simplify(n);
>          case 2 -> let int n=p2.component(0) in simplify(new NegNode(simplify(n)));
>          case 3 -> let right=p3.component(0) in simplify(right);
>          ...
>      };
> }
> I do not see how the exploded values (stored in the carrier object) can be stored inside the DtorHandle, (making them mutable BTW) can work.
> Perhaps, there is a need for an uber-carrier object, which is mutable (or not if the return of invokedynamic is conceptually a pair (selector+uber-carrier)),
> to store the the carrier object as a field so the switch (the one just after indy i the translation) can access to the carrier object.
> Like the carrier object, the uber-carrier has to be created at runtime in order to avoid the same binary compatible issue discuss by Brian about the carrier object.
> The other solution is that all carrier type of the DtorHandle as to be the same type (like the ArgumentList object proposed by John), in that case, the return value of an indy is a pair selector+argumentList (
> The ArgumentList being a kind of dynamically sized tuple)
> I've solved the problem by disallowing the action part of a pattern matching being able to do side effects on local variables, so all the actions can be pass as boostrap arguments of the indy the same way the LambdaMetaFactory works (an action is a static method seen as a constant MethodHandle, with the difference that the captured value do not need to be bound, they can be passed as argument of indy). This is something that can be done for the pattern matching that uses the expression switch but i doubt it's possible to explain to people that you can not do side effects if they use the classical switch syntax.
> Anyway, it may mean that it should exist two translation strategies, one for the classical switch and one for the expression switch.
> Rémi

More information about the amber-dev mailing list