From daniel.latremoliere at gmail.com Wed Mar 11 14:45:32 2020 From: daniel.latremoliere at gmail.com (=?UTF-8?B?RGFuaWVsIExhdHLDqW1vbGnDqHJl?=) Date: Wed, 11 Mar 2020 15:45:32 +0100 Subject: [Records] Transparency and effects on collections Message-ID: 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) 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 FOO;|| ||? private String foo;|| ||?? ...|| ||}|| | It would allow some typed code for partial querying, like: |RecordSet keyPool;|| ||Predicate fooFilter;|| ||keyPool.stream().filter(R.FOO, fooFilter).forEach(...);|| | Thanks for your attention, Daniel. ------------------------------------------------------------------------ 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 implements RecordField {|| ||??? FOO(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. From romanowski.mateusz at gmail.com Tue Mar 24 16:07:57 2020 From: romanowski.mateusz at gmail.com (Mateusz Romanowski) Date: Tue, 24 Mar 2020 16:07:57 -0000 Subject: do expression In-Reply-To: <642D307F-2A06-4872-A1F7-C98952632B20@oracle.com> References: <642D307F-2A06-4872-A1F7-C98952632B20@oracle.com> Message-ID: Hi All, I have seen your discussion regarding using a new expression to place field's initialization block with the field instead of in class/instance initializer. While I understand reluctance to introduce new keywords, there is the idea of using lazy static final fields [1] instead of complicated class static initializers. I think that scenario might also need a new expression more. Has there been any thoughts how to declare source-code static final field to be translated into a LazyValue backed by condy? Moreover, has there been any thoughts how to declare such field to throw checked exception on field read when its initialization might? Sorry if the issue has already been discussed. Thanks, Mateusz Romanowski [1] https://bugs.openjdk.java.net/browse/JDK-820996 On Tue, Mar 24, 2020 at 4:56 AM John Rose wrote: > The keyword ?do? is so short and sweet, and so under-used, > that it?s tempting to give it a new job. > > But I don?t think this job is important enough. It?s just making > a little sugar for something you can express already with switch. > > As Guy says there are many ways to wrap a block in an expression, > if we should want to do this. If we use a keyword, I would think > it should be a larger keyword than ?do?, just to make it more > visible. Or, if invisibility is OK, perhaps no keyword at all is > OK, just ?({ x })?: But that clearly shows the problems with > making the shift between statement and expression go almost > invisible; and ?do? is like that also, just two characters. > We went round and round on these issues with lambdas, > because they are similar. It takes a long while to settle on > just the right syntax to (a) read well, (b) not be too noisy, > and (c) not be too invisible either. > > Let?s keep ?do? in reserve. There are much deeper things we can > eventually ?do? with that keyword. In particular, if we open > up Java to allow extended execution modes, such as parallel > or differentiable or symbolic or side-effect-controlled, we will want > a concise way to mark the blocks of code which are to be ?done? > in an extended execution mode. For my money, that?s worth > ?doing up? with a pretty keyword. > > Before anyone asks, no I don?t have a specific proposal for > such a thing. A first draft, IMO, will use something like > lambda cracking (or maybe a clumsier form of quoting) > to work out the details of how to abstract over evaluation > modes, and apply them independently of the code snippets > themselves. There?s a lot of experimentation to work > through first, with no sugar anywhere, before we would > be confident of the correct degrees of freedom, the > different ways to ?do? code. > > I ?do? have an unspecific proposal: Look at F# computation > expression, and Haskell ?do? syntax. They cannot be spliced > whole-sale into Java without many adjustments, but they are > examples of what I mean by abstracting apart mode of computation > from code-structure of computation. What?s required are two > chunks of ordinary-looking code, one to supply local rules for > evaluation, and one to execute, non-standardly, under the > local rules. I have no idea (1) what the looks in in detail > for Java, and (2) what the sugary syntax would be, but that?s > the sort of juicy feature where little old ?do? might come > into its own, something like (OK, syntax) ?using (x) do y?. > > ? John > > On Mar 23, 2020, at 7:23 PM, Tagir Valeev wrote: > > > > Hello! > > > > Now we have a legal way to execute several statements within an > expression, yielding the result with a yield statement. This could be done > via `switch` expression. > > > > Sometimes it's desired to do this without any switch. One may abuse the > switch expression feature writing `switch(0) { default -> { ... code block > ending with 'yield' }}`. > > > > How about creating a special syntax for such kind of expression. It > could look like `do { ... code block ending with 'yield' }`? > > > > E.g. consider: > > > > class X { > > static final String field; > > > > // now we are forced to split field declaration and initialization > > // also initializer could be long and it could be not evident that its > main purpose > > // is to initialize the field > > static { > > try { > > field = initializeField(); > > } > > catch(CheckedException e) { > > throw new RuntimeException(e); > > } > > } > > } > > > > Since Java 14 we can write > > > > class X { > > // field declaration and initialization in the same place: easier to > navigate through code > > // though we are abusing the switch expression > > static final String field = switch(0) { default -> { > > try { > > yield initializeField(); > > } > > catch(CheckedException e) { > > throw new RuntimeException(e); > > } > > }}; > > } > > > > It could be like > > > > class X { > > // concise syntax. Now we know that the main block purpose > > // is to initialize the field > > static final String field = do { > > try { > > yield initializeField(); > > } > > catch(CheckedException e) { > > throw new RuntimeException(e); > > } > > }; > > } > > > > It's similar to Perl 'do BLOCK' expression > > https://perldoc.perl.org/functions/do.html < > https://perldoc.perl.org/functions/do.html> > > > > What do you think? > > > > With best regards, > > Tagir Valeev > >