<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4"><font face="monospace">I think you may have
misunderstood. We don't use annotations to extend the language
in this way at all; if you want a new type system feature (such
as new kinds of bounds on type variables), you have to extend
the language honestly. My comments below were related not to
the annotation-mockup of the feature, but to the actual feature
itself. <br>
<br>
What you're doing is inventing an entirely new kind of
implements-interface relation, one which the usual inheritance
rule:<br>
<br>
T implements I S extends T<br>
----------------------------<br>
S implements I <br>
<br>
does not apply. <br>
<br>
That's not to say that it can't be done, but I think you're
dramatically underestimating what you're suggesting. <br>
<br>
I get it; what you really want to be saying is "gee, it would be
nice if we could express constraints on type variables that the
type being substituted provides static methods and/or
constructors". And it would be nice, but it's not a new
observation, and the answers are complicated.<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 1/25/2023 10:54 AM, Red IO wrote:<br>
</div>
<blockquote type="cite" cite="mid:CABKyW1t83c4GXA60QRuZY3S3KJ3PBT4AwOj4RGJY2LQq-qCKTQ@mail.gmail.com">
<div dir="auto">I'm not sure how big of a closing factor this
implementation would have. Since the whole implementation is
opaque to everyone but the compiler. If implemented that way it
would be vital to guard the information carrying field from the
user (against reflection for example). If done correctly this
would be so opaque that a full implementation change would be
possible. The sole requirement would be that you could use the
type variable the same way in the new implementation.
<div dir="auto">As I was exploring a possible implementation in
my last mail I realized that it (by design) is 90%
preprocessor. I think I will continue exploring it by trying
to implement it using an annotation processor and explore
potential problems while using it.</div>
<div dir="auto">Of cause the annotation processor will be ugly
to use and for development only. </div>
<div dir="auto"><br>
</div>
<div dir="auto">Great regards </div>
<div dir="auto">RedIODev </div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Wed, Jan 25, 2023, 16:11
Brian Goetz <<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div> <font size="4"><font face="monospace">This is a good
example of a "you can, but you probably shouldn't"
language feature. The power-to-weight ratio isn't
favorable; it is a lot of new machinery and concept to
move the ball forward a small amount. And as soon as
the ball is moved forward by that amount, we will
immediately be confronted by the next thing we can't do,
and the solutions are likely to be an increasingly
complex sequence of worse power-to-weight ratio ideas.
(Careful observers of Java history might note that this
phenomenon is especially evident in any proposal
surrounding annotations.)<br>
<br>
As Michael K pointed out, other languages have explored
more general, but more suitable, answers here; what
you're looking for is a witness to conformance to a type
class. (Our friends in C# have pursued something
similar through abstract statics; for various reasons,
that's less of a good match for Java than for C#.) This
is not a small ask; its significant new complexity, but
the power gained is much greater. If we were to choose
to invest in solving problems like this one, that would
likely be the path, but this is a big lift and we have
other big things on our plate right now. <br>
<br>
As a general note, while it is fun to imagine new
language features, language design needs to be a
holistic process. If we did a hundred "point" features
like this, what are the chances that the whole would
hold together? If we did this feature, what other
potential feature directions are we implicitly
foreclosing on? These are the questions we address
ourselves to when choosing what features to consider and
not. <br>
<br>
</font></font><br>
<div>On 1/25/2023 2:03 AM, Red IO wrote:<br>
</div>
<blockquote type="cite">
<div dir="auto">
<div dir="auto">Summary</div>
<div dir="auto">-------</div>
<div dir="auto"><br>
</div>
<div dir="auto">Enable a parameterized class to
constrain the parameterized type to be constructible
with a given list of parameters.</div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">Motivation</div>
<div dir="auto">----------</div>
<div dir="auto"><br>
</div>
<div dir="auto">It is possible since JDK 8 to get a
constructor (method) reference of an object. This
allowed for the creation of an unknown class with a
known constructor reference. But currently the only
way to obtain such reference is at call site like
this:</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span></div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>Box<String>
stringBox = new Box<>(String::new);</div>
<div dir="auto"><br>
</div>
<div dir="auto">It is inconvenient for the user to
supply the the reference themselves and can confuse
them as the type of the parameter is something like
Supplier<String> which doesn't require the pased
reference to be a constructor. </div>
<div dir="auto">It also clutters api's like "toArray"
which requires an IntFunction to be type safe. </div>
<div dir="auto"><br>
</div>
<div dir="auto">Description</div>
<div dir="auto">-----------</div>
<div dir="auto"><br>
</div>
<div dir="auto">ConstructorInterface</div>
<div dir="auto">A ConstructorInterface is a special kind
of interface similar to a FunctionalInterface. It also
has similar constraints. It only allows abstract
constructors and no other abstract methods. It can
declare multiple constructors though. The definition
of such interface would look similar to this:</div>
<div dir="auto"><br>
</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>@ConstructorInterface
//optional validation like FunctionalInterfaces</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
interface DefaultConstructible {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>new();</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>new(char[]
chars);</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>}</div>
<div dir="auto"><br>
</div>
<div dir="auto">A parameterized type could declare this
interface as a type bound for its parameter and
therefore enabling it to be constructed safely. Like
this:</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
class Box<E extends DefaultConstructible> {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
Box() {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>E
newElement = new E();</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>}</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>}</div>
<div dir="auto">The containing type is not forced to
implement the ContructorInterface explicitly. It is
implicitly implemented if the required constructor(s)
is(are) present.</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
static void main(String[] args) {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>Box<String>
stringBox = new Box<>(); //compiles because
String has the required constructors.</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>Box<java.sql.Date>
dateBox new Box<>(); error: java.sql.Data does
not satisfy the type bound DefaultConstructible</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>}</div>
<div dir="auto">The interface might not be implemented
by any class, since it doesn't follow the inheritance
rule that extending classes of those who implement it
also implement it. This requirement comes from the
fact that extending classes do not necessarily need to
have the same constructor signature and therefore
don't qualify the requirements for the interface.
Another option would be that extending classes of
classes that implement a constructor interface
explicitly are also required to supply the necessary
constructors.</div>
<div dir="auto"><br>
</div>
<div dir="auto">class Foo implements
DefaultConstructable {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>//both
required by the interface </div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
Foo() {} </div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
Foo(char[] chars) {} </div>
<div dir="auto">} </div>
<div dir="auto"><br>
</div>
<div dir="auto">class Bar extends Foo {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>//the
requirement for the required constructors is passed
down. </div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
Bar() {} </div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>public
Bar(char[] chars) {} </div>
<div dir="auto">} </div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">public static <T extends Foo> T
createT() {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>return new
T();</div>
<div dir="auto">} </div>
<div dir="auto"><br>
</div>
<div dir="auto">public <T extends Foo> T wrapper()
{</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>return
createT();</div>
<div dir="auto">} </div>
<div dir="auto">This would technically work but would
require a lot of static analysis to find the real type
of T to call its constructor. </div>
<div dir="auto">Restricting the use of "new T()" to type
parameters that specify a constructor interface
directly and only allow those to be resolved with a
concrete type rather than another type parameter. </div>
<div dir="auto"><br>
</div>
<div dir="auto">Alternatives</div>
<div dir="auto">------------</div>
<div dir="auto">An alternative would be to introduce new
syntax to restrict the ability of certain constructors
on a parameter type. Like c# does (but only for the
default constructor) :</div>
<div dir="auto">public static T foo<T>() where T:
new() {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>return
new T();</div>
<div dir="auto">} </div>
<div dir="auto">In java:</div>
<div dir="auto">public static <T extends new()> T
foo() {</div>
<div dir="auto"><span style="white-space:pre-wrap"> </span>return
new T();</div>
<div dir="auto">} </div>
<div dir="auto">The downside of this approach is
obviously the introduction of new syntax rather than
reusing the interface/inheritance syntax. </div>
<div dir="auto"><br>
</div>
<div dir="auto">Another alternative to this approach
could be to implement static abstract methods. This
would allow an interface to mandate a static Factory
Method. The downside of this approach is that it
requires the parameter class to actually implement the
interface and the concept of type erasure would need
to be addressed for static abstract methods to work.
In contrast the ConstructorInterface enables every
class that matches its contract to pass the type
bound.</div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">Risks and Assumptions</div>
<div dir="auto">---------------------</div>
<div dir="auto"><br>
</div>
<div dir="auto">As mentioned before the restriction the
interface is giving on a type bound is different to
normal interfaces, it restricts by its containing
abstract constructors not by the type itself. It also
makes use of the new operator on type variables. </div>
<div dir="auto"><br>
</div>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</blockquote>
<br>
</body>
</html>