Array patterns (and varargs patterns)

John Rose john.r.rose at oracle.com
Sat Sep 10 00:34:40 UTC 2022


On 9 Sep 2022, at 9:09, forax at univ-mlv.fr wrote:

> ----- Original Message -----
> Here we want to extract the value into bindings/variables, that is not
> what the varargs does, the varargs  takes a bunch of value on stack 
> and put them into an array.
> Here we want the opposite operation of a varargs, the spread (or 
> splat) operator that takes the argument from an array (or a collection 
> ?) and put them on the stack.

You are right that Brian’s proposal is not at its heart varargs, it is 
*array patterns* just as *array construction* are not equivalent to 
varargs, just a precursor to varargs.

I think we need to get array patterns right first.  Then we can move to 
whatever a fuller conception of varargs might look like “in the dual 
mirror”.

In Brian’s architecture of patterns, every aggregator is matched as 
cleanly as possible with its dual pattern (which reverses data flows).

There are actually two array construction expressions in Java today.  
(We could extend them with more varargs-flavored features to do 
slice/splat/spread/splice/whatever, but we don’t have them today!)  
The older expression takes a length and produces an uninitialized array. 
The slightly-less-old expression takes an initializer list *and refuses 
to take a length* and produces an initialized array, correctly sized.

The most conservative application of Brian’s design principles would 
create, I think, *two distinct array patterns*, one for each kind of 
expression.

Can the two patterns be merged?  Yeah, maybe, but at the cost of 
disturbing the correspondence with array aggregation.

And it may be that some of of the tricky questions about varargs go away 
if we restrict ourselves to just the two kinds of basic patterns that 
derive directly from today’s array creation expressions.

Remember, patterns compose.  If you have that rare need for both length 
and contents, use two patterns combined on the same array.  There’s 
always a way to do that.

If you want *some of the content* of an array to match a pattern, use a 
don’t care pattern.  If you want length-polymorphism and element 
subpatterns (a match of one pattern to many lengths, with elements 
sprinkled around somehow) then we are beyond the bounds of today’s 
exercise, aren’t we?

>
> If we have the pattern method Arrays.of()
>
> static <T> pattern (T...) of(T[] array) {  // here it's a varargs
>   ...
> }
>
> and we call it using a named pattern
>   switch(array) {
>     case Arrays.of(/* insert a syntax here */) -> ...
>
> the syntax should extract some/all values of the array into one or 
> several bindings.

We’ll get there.  Just not quite yet.  One step at a time.

I think it would be really neat to be able to “slice out” 
multi-element chunks of an array and bind them to pattern variables.  
Lisp folks have been enjoying this sort of thing basically forever.  And 
*ignoring a range of elements* in a pattern is exactly equivalent to 
slicing them out and binding them to a don’t-care pattern, right?

Confronted with such a feature, having thought about Brian’s 
principles, I think I would at the same time expect that there would be 
a dual array *construction* expression which would do the 
*mirror-opposite*.  That is, it would “splice in” multi-element 
chunks, into a newly created array.  The Lisp folks sometimes use the 
same notation for both splicing and slicing.  (I’m thinking of 
backquote-comma-atsign, with and without some kind of pattern-bind.)

Under Brian’s design principles, which I whole-heartedly agree with, I 
guess a slogan for array patterns might be:  No slicing without 
splicing!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20220909/cc239af2/attachment.htm>


More information about the amber-spec-observers mailing list