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