Finalizing in JDK 16 - Pattern matching for instanceof
John Rose
john.r.rose at oracle.com
Wed Sep 23 19:14:03 UTC 2020
On Aug 26, 2020, at 8:00 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
>
> …I now think that we have done the same with binding variables.
Good catch; thank you!
> Here are two motivating examples:
>
> (a) Pattern assignment…
> (b) Reconstruction. We have analogized that a `with` expression:
>
> x with { B }
>
> is like the block expression:
>
> { X(VARS) = x; B /* mutates vars */; yield new X(VARS) }
>
> except that mutating the variables would not be allowed.
I am convinced that (under broad presuppositions) reconstruction
expressions *should* allow mutation to their internal bindings.
The reason for this is to allow locally imperative code to update
the immutable state of an object that contains the state, so as to
produce an object that contains the updated state. This is a key
use case for refactoring loops using a[i++] and i.next() into idioms
that use inline objects, specifically cursors, for managing iteration.
for (var c = Arrays.cursor(a, start, end); c.hasNext(); c = c __With { index++; }) …
for (var c = myList.cursor(); c.hasNext(); c = c.afterNext()) …
Internally, c.afterNext() uses a self-reconstructor with some sort of
index++ just like the old iterator does:
public MyListCursor afterNext() {
return this __With { i++; };
}
Please see for more details:
http://cr.openjdk.java.net/~jrose/values/iterator-vs-cursor.html
— John
P.S. Once you buy into this set of use cases, numerous sugary improvements
to “__With” become apparent by analogy with things like lambda bodies and
object constructors and compound assignment operators. I’ll leave that as an
exercise for the EG.
P.P.S. Both cursors and iterators could support a very nifty new loop
idiom using “non-static” patterns:
for (var i = myContainer.iterator(); i.nextIs(var e); ) {
… do something with e …
}
where Iterator has a new default method like this:
interface Iterator<T> { …
default __Pattern nextIs() __Outputs(T element) {
if (!hasNext()) __Fail; // aka `break;` or `return false;`
element = next();
// implicit `return;` aka __Match aka __Match(element)
}
More information about the amber-spec-experts
mailing list