<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>To add to what Brian and others have said on this thread,
annotation processors as first shipped in JDK 5.0 with apt and
later standardized through JSR 269 in Java SE 6 were intentionally
designed to *not* allow direct modification of ASTs to avoid
language fragmentation, etc.<br>
</p>
<p>However, it was acknowledged that at least some subset of the
ability to modify sources was useful so annotation processors
supported the ability to generate missing subclasses and
*superclasses* during processing. Those capabilities are
sufficient to implement a properties-like scheme, as sketched out
in this blog entry:</p>
<p>
<a class="moz-txt-link-freetext" href="https://web.archive.org/web/20100410203408/http://blogs.sun.com/darcy/entry/properties_via_annotation_processing">https://web.archive.org/web/20100410203408/http://blogs.sun.com/darcy/entry/properties_via_annotation_processing</a></p>
<p>and later productized in projects like:</p>
<p> <a class="moz-txt-link-freetext" href="http://immutables.github.io/immutable.html">http://immutables.github.io/immutable.html</a></p>
<p>HTH,<br>
</p>
<p>-Joe<br>
</p>
<div class="moz-cite-prefix">On 1/30/2023 6:36 AM, Brian Goetz
wrote:<br>
</div>
<blockquote type="cite" cite="mid:12ef0967-607d-d644-44ef-6d049d1696c1@oracle.com">
<font size="4"><font face="monospace">Annotations are exactly as
(not) powerful as they were designed to be. JSR 175 (<a class="moz-txt-link-freetext" href="https://www.jcp.org/en/jsr/detail?id=175" moz-do-not-send="true">https://www.jcp.org/en/jsr/detail?id=175</a>)
-- the effort that gave us annotations -- is called a
_metadata facility for the Java Language_, not a
_metaprogramming facility_. This choice was not made because
the leaders of that effort were ignorant about
metaprogramming; the goal was to leave interpretation of
annotations to things like service containers, test
frameworks, etc, because annotations are too weak a mechanism
for providing language semantics. <br>
<br>
As Ron pointed out, it is a very common mistake when imagining
possible language features to focus only on "if I had X, what
cool code could I write?", and ignore the "if everyone had X,
what would be the effect on readability, reliability, and
maintainability of the global codebase?" But understanding
the latter is where much of the challenge lies in responsibly
evolving a language. <br>
<br>
<br>
<br>
<br>
</font></font><br>
<div class="moz-cite-prefix">On 1/30/2023 5:26 AM, Red IO wrote:<br>
</div>
<blockquote type="cite" cite="mid:CABKyW1vzJ+xRyjPUx+ZMmqNBDBQhKn3Djxd8UvwA1c11eRaJrA@mail.gmail.com">
<div dir="auto">After exploring the world of annotation
processors trying to implement test versions of the features,
I discovered that annotation processors can't officially edit
the ast and Lombok uses undocumented hacks to achieve this.
This is a bit of a problem for implementing the test versions
that way. My question is why is this disallowed? It would be a
really powerful tool for compile time code execution/
generation.
<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, 20:19
Red IO <<a href="mailto:redio.development@gmail.com" moz-do-not-send="true" class="moz-txt-link-freetext">redio.development@gmail.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="auto">If the type information is an opt in feature
it would not violate that rule. Adding an erasing
parameter would still be a non breaking change. But if you
opt in to request the type information and write logic
depending on that information then this is a braking
change to the code anyway since the logic wouldn't work
with a raw type anyway. This could be another factor to
push away from utilizing raw types. It could be a keyword
you add to a parameterized thing to opt in (or implicitly
opt in by utilizing the extended type information) and in
the same act disable the raw version for it. Meaning that
it would be a compile error to use the parameterized
thing.
<div dir="auto"><br>
<div dir="auto">Another option and preserve raw
compatibility would be to exclude the hidden parameter
in a raw instance. The downside to this approach would
be that 2 signatures for every method/constructor that
would otherwise include the hidden parameter would be
required. Also for generic classes there would be 2
class layouts 1 with the hidden fields and 1 without.</div>
<div dir="auto"><br>
</div>
<div dir="auto">A completely different approach would be
a static map of object instances to parameter lists.
This would require 0 changes in the class itself. But
in case of many generic objects loaded the performance
of this approach is likely catastrophic. Should be
tested if proving viable though. Another challenge is
how a constructor would register the objects extended
type information without an extra parameter. Also this
would be difficult to implement for methods who are so
short lived that the type parameter registration would
likely take as long as the method itself needs to
complete.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Personally I would vote for braking with
raw types (first approach) it wouldn't harm existing
code (since opt in), would provide the simplest (and
probably fastest) version and the only downside would
be a harder and braking transition for api which still
use raw types and want to utilize the extended type
information (but as I already mentioned if an api
wants to opt in to extended type information on a
class; having raw instances of it would make
absolutely no sense anyway).</div>
<div dir="auto"><br>
</div>
<div dir="auto">Great regards </div>
<div dir="auto">RedIODev </div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Wed, Jan 25, 2023,
19:29 <<a href="mailto:forax@univ-mlv.fr" target="_blank" rel="noreferrer" moz-do-not-send="true" class="moz-txt-link-freetext">forax@univ-mlv.fr</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
<div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:#000000">
<div>[private]<br>
</div>
<div><br>
</div>
<hr id="m_-1440949958086341510m_-3287884457023709074zwchr">
<div>
<blockquote style="border-left:2px solid
#1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><b>From:
</b>"Red IO" <<a href="mailto:redio.development@gmail.com" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">redio.development@gmail.com</a>><br>
<b>To: </b>"Remi Forax" <<a href="mailto:forax@univ-mlv.fr" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">forax@univ-mlv.fr</a>><br>
<b>Cc: </b>"amber-dev" <<a href="mailto:amber-dev@openjdk.org" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amber-dev@openjdk.org</a>><br>
<b>Sent: </b>Wednesday, January 25, 2023
3:17:34 PM<br>
<b>Subject: </b>Re: Constructor Interfaces<br>
</blockquote>
</div>
<div>
<blockquote style="border-left:2px solid
#1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt">
<div dir="auto">I proposed an idea (to Valhalla)
to overcome type erasure that used the same
idea of desugering and a hidden argument that
carries the erased types class variable inside
the generic context, but it was rejected as a
to naive approach or something and they where
"already working on different solutions for
some time".</div>
</blockquote>
<div><br>
</div>
<div>What you have proposed is very similar to
what Kotlin does, pass supplementary type
arguments as parameter arguments/fields.<br>
</div>
<div>This does not work, the Java spec explicitly
says that adding type parameters, if there were
previously none, is a backward compatible change
but adding a supplementary parameter is not a
backward compatible change (especially not a
binary backward compatible change).<br>
</div>
<div><br>
</div>
<div>That why the current proposed design pass the
type arguments as a side channel not encoded in
the type descriptor, see<br>
</div>
<div> <a href="https://cr.openjdk.java.net/~jrose/values/parametric-vm.pdf" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://cr.openjdk.java.net/~jrose/values/parametric-vm.pdf</a><br>
</div>
<div><br>
</div>
<div>regards,<br>
</div>
<div>Rémi<br>
</div>
<div><br>
</div>
<blockquote style="border-left:2px solid
#1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt">
<div dir="auto">
<div dir="auto"><br>
</div>
<div dir="auto">Great regards RedIODev </div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Wed, Jan
25, 2023, 14:51 Remi Forax <<a href="mailto:forax@univ-mlv.fr" rel="noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">forax@univ-mlv.fr</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px
#ccc solid;padding-left:1ex">
<div>
<div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:#000000">
<div>We may need something like this for
Valhalla, when we will revisit how to
constraint the type arguments of
universal generics.<br>
</div>
<br>
<div>The kind of constraints you
describe on type parameters already
exist in C# or TypeScript and was more
recently introduced in Go, and there
is the type class of Haskell too.<br>
</div>
<br>
<div>regards,<br>
</div>
<div>Rémi<br>
</div>
<br>
<hr id="m_-1440949958086341510m_-3287884457023709074m_-4974614324344570563zwchr">
<div>
<blockquote style="border-left:2px
solid
#1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><b>From:
</b>"Red IO" <<a href="mailto:redio.development@gmail.com" rel="noreferrer noreferrer
noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">redio.development@gmail.com</a>><br>
<b>To: </b>"amber-dev" <<a href="mailto:amber-dev@openjdk.org" rel="noreferrer noreferrer
noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">amber-dev@openjdk.org</a>><br>
<b>Sent: </b>Wednesday, January 25,
2023 8:03:14 AM<br>
<b>Subject: </b>Constructor
Interfaces<br>
</blockquote>
</div>
<div>
<blockquote style="border-left:2px
solid
#1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt">
<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">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">@ConstructorInterface
//optional validation like
FunctionalInterfaces</div>
<div dir="auto">public interface
DefaultConstructible {</div>
<div dir="auto">new();</div>
<div dir="auto">new(char[] chars);</div>
<div dir="auto">}</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">public class
Box<E extends
DefaultConstructible> {</div>
<div dir="auto">public Box() {</div>
<div dir="auto">E newElement = new
E();</div>
<div dir="auto">}</div>
<div dir="auto">}</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">public static void
main(String[] args) {</div>
<div dir="auto">Box<String>
stringBox = new Box<>();
//compiles because String has
the required constructors.</div>
<div dir="auto">Box<java.sql.Date>
dateBox new Box<>();
error: java.sql.Data does not
satisfy the type bound
DefaultConstructible</div>
<div dir="auto">}</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">//both required by
the interface </div>
<div dir="auto">public Foo() {} </div>
<div dir="auto">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">//the requirement
for the required constructors is
passed down. </div>
<div dir="auto">public Bar() {} </div>
<div dir="auto">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">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">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">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">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>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
<br>
</blockquote>
</body>
</html>