Translation of pattern matching
Remi Forax
forax at univ-mlv.fr
Sat Aug 5 01:55:16 UTC 2017
Thanks Maurizio,
so there is no need to an uber carrier, because you compose the carrier (as far as I understand).
You still need a way to pass the carrier from indy to the switch.
I think I will test the ArgumentList translation to see how it goes, did I mention that prototyping things with mjolnir was easier :)
Remi
On August 4, 2017 1:19:32 PM PDT, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
>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] -
>http://cr.openjdk.java.net/~briangoetz/amber/pattern-match-translation.html
>
>http://cr.openjdk.java.net/~briangoetz/amber/pattern-match-translation.html
>
>
>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
>>
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
More information about the amber-dev
mailing list