----- Original Message ----- > From: "Brian Goetz" <brian.go...@oracle.com> > To: "daniel smith" <daniel.sm...@oracle.com>, "Dan Heidinga" > <heidi...@redhat.com> > Cc: "valhalla-spec-experts" <valhalla-spec-expe...@openjdk.java.net> > Sent: Vendredi 10 Septembre 2021 20:25:50 > Subject: Re: Factory methods & the language model
>> I'm not particularly interested in settling on a bikeshed color, but am >> interested in the general mood for pursuing this direction at all. (And not >> necessarily right away, just—is this a direction we think we'll be going?) >> >> A few observations/questions: >> >> - 'new Foo()' traditionally guarantees fresh instance creation for identity >> classes. Primitive classes relax this, since of course there is no unique >> identity to talk about. Would we be happy with a language that relaxes this >> further, such that 'new Foo()' can return an arbitrary Foo instance (or maybe >> even null)? Or would we want to pursue a different, factory-specific >> invocation >> syntax? (And if so, should primitive classes use it too?) > > Let me offer some context from Amber that might be helpful, regarding > whether we might want "factory" to be a language feature. > [...] > > Example 2 -- "with" expressions / reconstructors. A number of > interesting features come out of the pairing of constructors and > deconstruction patterns with the same (or compatible) argument lists, > such as `with` expressions (`point with { x = 3 }`). Handling this > involves doing multiple overload selection operations, first to find a > deconstructor that yields the right bindings, and then to find a > compatible constructor that accepts the resulting exploded state. > > Among the many problems of doing this (including the fact that parameter > names are not required to be stable or meaningful), we also have the > problem of "what if the class doesn't have a constructor, but a > factory." This would require the language to have a notion of factory > method (e.g., `factory newPoint(int x, int y)`) so the compiler could > try to match up a compatible factory with the deconstructor. I think there is a way to not introduce a weird with expression syntax by piggybacking on the fact that a record is a weird tuple. A record in Java is not just a tuple, i.e. a vector of values, but because all components are named also a compact key/value set. The "with" expression is a case where we want to see a record as key/value set more than as a vector of values. If we have a syntax to construct a record as a key/value set, this syntax can be slightly extended to express a "with" expression. By example, if we have a syntax like Point p = Point { x: 3, y: 4 }; Then the syntax for the with expression will be to something like Point p2 = Point { x: 7, p }; I can hear you saying that i'm trying to trick you to add a new syntax for creating a record which is bigger that just the "with" expression. And that's partially true. I believe that the "key/value set" syntax for a record is something we should introduce in Amber anyway because it's a declarative syntax, the same way a Stream is, making the code easier to read. And people want a syntax like this so badly that they are up to writing a full builder pattern in their code just for being able to see the name of the parameters when creating complex objects. regards, Rémi