Deconstructors a bit unintuitive?

Brian Goetz brian.goetz at oracle.com
Thu Sep 22 14:28:25 UTC 2022



On 9/22/2022 9:37 AM, John Hendrikx wrote:
> I was reading 
> https://github.com/openjdk/amber-docs/blob/master/eg-drafts/deconstruction-patterns-records-and-classes.md and 
> wished to give some feedback.

I appreciate the feedback, but I'm going to ask you hold it for a few 
reasons:

  - This feature isn't really even really under discussion yet - the 
document shown was merely an illustrative sketch, and no substantive 
discussion has been had yet;
  - Your concerns are mostly with the illustrative example syntax shown 
in that document, which should not be taken as a serious proposal.  (One 
of the trouble with such documents is that you have to show *something*, 
but then people will immediately assume "so this is the final syntax" 
and commence arguing.)
  - The syntax concerns of deconstructors are coupled to more complex 
forms of pattern declaration, whose considerations and requirements may 
not yet be obvious and are not considered in that document.

Basically, that document was attempting to illustrate the dualities 
between constructors and deconstructors, and didn't want to try to do 
more, but of course it is hard to visualize these things without a code 
sketch, and hard to treat such code sketches for what they are.

I'll try to speak a bit to your general conceptual issues, bearing in 
mind the constraints of the above.

> I find the (possible) approach presented for deconstructors a bit 
> counter intuitive, where parameters are treated as outputs for 
> deconstructors. I think that an approach where it more closely matches 
> the standard pattern of "<output> <function> <input>" would be more 
> intuitive.

To some degree, declaring patterns is going to be uncomfortable somehow 
no matter what we do.  Its not obvious from the examples in the 
document, which were focused on a different aspect, but in generality 
patterns can have full argument lists of *both* input parameters and 
output bindings.  They simply will not fit cleanly in the "N in, one 
out" model of methods.  So there is going to be something 
counterintuitive somewhere, and the solution is likely to involve some 
degree of extending our mental model about executable members.

> The current approach instead looks very much like parameters that are 
> passed by reference (pointers to those parameters) but without any 
> indication (like "&" or "ref"), aside from the deconstructor keyword, 
> that this is the case:
>
>       public deconstructor Point(int x, int y) { x = this.x; y= this.y; }
>
> I find this quite jarring; overwriting (what looks like) a parameter 
> with a new value never affected anything beyond the scope of the 
> function. I realize that changing objects has effects beyond the 
> function scope, but this was never the case for the parameter 
> variables themselves.

Your point is correct that the *position* of the binding list in the 
declaration is unnecessarily confusing, because it is where you would 
expect the parameters to be.  As it turns out, there are other reasons 
why this particular positioning has issues, but I'm not going to repeat 
the mistake by showing a more recent sketch, so we'll just have to wait 
for a "serious" proposal before continuing the discussion.

> I suppose this has been considered and discussed before, and 
> introducing something as generic as multiple return values in order to 
> support deconstructors in this way may be a bridge too far, but 
> perhaps my feelings on this topic may still contribute something to 
> this feature.

The "multiple return" interpretation is indeed one that springs easily 
to mind as a first thought, but it turns out to run out of gas before it 
gets where it needs to go.  (See "Isn't this just multiple return" in 
https://github.com/openjdk/amber-docs/blob/master/site/design-notes/patterns/pattern-match-object-model.md 
for one of the multiple reasons why I don't want to go in this direction.)

The issues outlined in that section illustrate where this approach runs 
out of gas: it would only work with unconditional patterns. 
Deconstructors are unconditional, but it is a short hop to patterns that 
are the dual of, say, `Optional.of(v)`, and then treating destructuring 
as merely "invoking a multiple return method" falls apart because it has 
no way to express the conditionality.  And having a separate syntax for 
"invoking" conditional and unconditional patterns carries its own problems.

Which brings us to my initial statement, which is that patterns are 
going to require extending our mental models about executable members.  
It is probably better to discuss what that model is first.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20220922/9e8bc3f7/attachment.htm>


More information about the amber-dev mailing list