Fwd: [Records] Transparency and effects on collections

Brian Goetz brian.goetz at oracle.com
Mon Mar 16 20:24:04 UTC 2020

Received on the -comments list.

-------- Forwarded Message --------
Subject: 	[Records] Transparency and effects on collections
Date: 	Wed, 11 Mar 2020 07:45:32 -0700 (PDT)
From: 	Daniel Latrémolière <daniel.latremoliere at gmail.com>
To: 	amber-spec-comments at openjdk.java.net

I understand that records are transparent and have correct 
equals/hashcode, then are useful as keys in collections. When trying to 
find classes to evolve to records, I found classes having more or less 
the same use-cases in memory than a multi-column primary key would have 
in SQL.
Records are a sugar above classes, like enum but for another use case, 
is it planned to have more evolved collections (like enum has with 
EnumSet/EnumMap)? Given records are explicitly transparent, API for 
pooling records would need to use this explicit transparency to allow 
partial queries and not only the Set/Map exact operations.

If this is the case, it would probably need some specialised subtype of 
Set, like a new RecordSet (similar to a simple table without join, 
contrary to SQL). Current Java's Stream API would probably be perfect 
with some small enhancements, JPA-like (on a sub-type RecordStream<R>) 
allowing to refer directly to the field to be filtered.

In this case, the compiler would need to generate for each record one 
static field per instance field of the record to allow typed queries, 
like in the following example.

|record R(|||String foo, ...)| {||
||   ...||
desugarized more completely in:

|class R {||
||  public static final RecordField<R, String> FOO;||
||  private String foo;||
||   ...||
It would allow some typed code for partial querying, like:

|RecordSet<R> keyPool;||
||Predicate<String> fooFilter;||
||keyPool.stream().filter(R.FOO, fooFilter).forEach(...);||

Thanks for your attention,
NB: in desugarization, I used standard static fields, like JPA, and not 
an enum containing all meta-fields (which would probably be more correct 
and efficient). This is due to the lack of JEP 301 (needed for typed 
constants in enum). If allowed, the desugarized record will become 
something like:

|class R {||
||  public static enum META<X> implements RecordField<R, X> {||
||    FOO<String>(String.class);||
||  }||
||  private String foo;||
||  ...||
In query, it would be used as R.META.FOO for filtering on field "foo" of 
the record:

|keyPool.stream().filter(R.META.FOO, fooFilter).forEach(...)|
PS: I am not interested in interning records but using them in pools 
defined by programmer. Pooling would improve memory and performance to 
deduplicate records, because equals would more frequently succeed at 
identity test without continuing to real equality test (field by field). 
Having specialized implementations of collections, using fields of 
records following the order given by user, would probably be useful for 
performance against simple Set/Map: structures like a hierarchical Map 
of Map of ..., field by field, can be more efficient if partial queries 
are frequently used or if the pool is big.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200316/f77cf941/attachment.htm>

More information about the amber-spec-experts mailing list