[External] : Re: Proposal: java.lang.runtime.Carrier

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Mar 4 00:39:00 UTC 2022


> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Jim Laskey" <james.laskey at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Sent: Thursday, March 3, 2022 7:59:01 PM
> Subject: Re: [External] : Re: Proposal: java.lang.runtime.Carrier

>>>> For the pattern matching,
>>>> we also need a 'with' method, that return a method handle that takes a carrier
>>>> and a value and return a new carrier with the component value updated.

>>> It is not clear to me why we "need" this. Rather than jumping right to "Here is
>>> the solution", can you instead try to shine some light on the problem you are
>>> trying to solve?
>> When you have nested record patterns, each of these patterns contribute to
>> introduce bindings, so when executing the code of the pattern matching, the
>> code that match a nested pattern needs to add values into the carrier object.
>> Given that the Carrier API is non mutable, we need the equivalent of a
>> functional setter, a wither.

> I don't think we need to do this.

> Recall what nested patterns means: if R(T t) is a record, and Q is a pattern
> that is not total, then

> x matches R(Q)

> means

> x matches R(T t) && t matches Q

> So if we have

> record R(S s) { }
> record S(int a, int b) { }

> then

> case R(S(var a, var b))

> operates by matching the target to R, deconstructing with the R deconstructor,
> which yields a carrier of shape (S). Then we further match the first component
> of this carrier to the S deconstructor, which yields a carrier of shape (II).
> No mutation needed.

> Note that this unrolling can happen in one of two ways:

> - The compiler just unrolls it doing plain vanilla compiler stuff
> - A pattern runtime has a nesting combinator that takes a pattern description
> for an outer and an inner pattern, which when evaluated with R and S, yields a
> carrier of shape (R;S;II), the compiler evaluates this nesting combinator with
> condy, and uses that to do the match.

> Either way, we don't need to mutate or replace carriers.
You want the same carrier for the whole pattern matching: 
- if you have a logical OR between patterns (not something in the current Java spec but Python, C# or clojure core.match have it so we may want to add an OR in the future) 
- if different cases starts with the same prefix of patterns, so you don't have to re-execute the de-constructors/pattern methods of the prefix several times 

It's like when you create a value type, you start with the default value with all the field initialized with their default value, and each time there is a new binding, you do the equivalent of a withfield. 

Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20220304/4e0413b4/attachment.htm>


More information about the amber-spec-experts mailing list