anonymous records as an implementation for tuples in Java
Red IO
redio.development at gmail.com
Wed Dec 11 16:59:33 UTC 2024
As tuples can be implemented entirely as synthetic sugar I don't see the
problem. Simply desugar all denotations of the tuple type to a structurally
named type similar to arrays. Then create 1 record definition for each used
type. (which I guess is at some point done for arrays)
Example:
(String, int) foo() {
return ("hi", 42);
}
void bar((String, int) tup) {
System.out.println(tup.0 + tup.1);
}
var x = foo();
bar(x);
Becomes:
public record $Tjava_lang_String-int(String e0, int e1) extends Tuple {}
$Tjava_lang_String-int foo() {
return new $Tjava_lang_String-int("hi", 42);
}
void bar($Tjava_lang_String-int tup) {
System.out.println(tup.e0() + tup.e1()) ;
}
var x = foo();
bar(x);
This is completely possible with preprocessing alone. Syntax, descriptor
format and named vs unnamed elements are details not worth the initial
discussion.
I think tuples are great and require no fundamentally new features to
become part of the language.
Great regards
RedIODev
On Wed, Dec 11, 2024, 17:23 Brian Goetz <brian.goetz at oracle.com> wrote:
> Yes, this is one of those ideas that sounds good for the first few
> minutes. (C# has explored something similar with what they call "anonymous
> classes", which turned out to be mostly disappointing.)
>
> The problem is _linkage_. It's easy to write out the creation expression:
>
> var tuple = (int id: 10, String name: "foo")
>
> So now: what's the type of `tuple`? What can I assign it to? How do I
> extract the members? How do I write a method that accepts a tuple of (int
> id, String name)? What if someone passes it a tuple of (int x, String s)?
> What does equals and hashCode do on these things? These things have many
> potential answers, but none of them are very satisfying.
>
> If you're going to create a tuple, presumably someone wants to consume it,
> store it somewhere, extract its components. C#'s answer was that you can
> only do so _within a compilation unit_ (effectively, within the same class)
> because there was no guarantee that one classes { x: 1, y: 2 } was
> interoperable with another.
>
> Linkage in Java is nominal; when you call a method `m("foo")`, the caller
> and declaration have to agree on the types, and the method descriptor (in
> this case, `(Ljava/lang;String;)V`) is recorded in the classfile. if you
> want to be able to pass a tuple to a method, we have to record something,
> and that means either inventing a whole new structural type system to
> ensure that tuples of the wrong type don't get exchanged, or erasing
> everything to some "Tuple" class (in which case you lose names and likely
> types of components.)
>
> DISCLAIMER: this is not meant to be a canonical explanation of why we
> can't have it. It is literally the first 30 seconds of stuff off the top
> of my head about why this is more complicated, from the perspective of how
> the language holds together, than it looks.
>
> Essentially, this doesn't really give you the expressive power people want
> from tuples; what it gives you is a convenient syntactic shorthand for
> packing the elements into a blob. Which makes it a fairly weak feature,
> and one where, once we had it, people would immediately see its weaknesses
> and then want more. So it is not any kind of shortcut; it is mostly
> convincing ourselves that concise creation syntax is the only important
> thing we get from tuples. But I don't think that's a good idea.
>
> I would put this problem in the same bucket as "collection literals" --
> optimized syntactic forms for common structural shapes such as lists. This
> is on our radar but there are a number of higher-priority things ahead of
> it, so we won't be talking about it for a while.
>
>
>
>
> On 12/11/2024 10:58 AM, david Grajales wrote:
>
> I've noticed that the topic of tuples in Java has come up recently, and I
> wanted to take this opportunity to show an idea regarding the use of *"anonymous"
> records* as a potential implementation for tuples.
>
> The idea would be to create *ad-hoc records* on the fly for short lived
> methods, which don’t have a formal name but are defined by their
> components. For example, imagine something like this:
>
> var tuple = (int id: 10, String name: "name");
>
> This would allow us to create simple, unnamed records with specified
> fields for quick, on-the-fly usage. Accessing values from the tuple could
> then work like this:
>
> var myTupleId = tuple.id()
>
> for passing them as arguments to methods it could be something like this.
>
> void foo(Tuple<Integer, String> tuple){}
>
> The idea is that, as records are just classes with special constraints to
> force invariants, tuples could be records with special constraints, for
> example as they would be meant to be created on the fly for pin point
> needs, they should not have validation in the constructor or overriding of
> getters, but they would still get automatic equals(), hashCode(), and
> toString() methods.
>
>
> I don't know how problematic or bad this approach would be if there were
> plans to ever introduce construct tuples to Java.
>
> best regards.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241211/46b5ea4c/attachment-0001.htm>
More information about the amber-dev
mailing list