1. Why not just call these "structs"? Everyone knows what a struct is. Also making "struct" a reserved keyword is less likely to cause issues than "record";
2. I get that these are trying to be simple but why can't I compose records from other records? I guess I can have a record member of a record?
3. I couldn't see if records can be passed entirely on the stack like primitive values can. This would be huge. I seem to recall there was some effort to add this to Java but I'm not sure whatever happened to that. It probably added a ton of complexity.
1. C popularized the `struct` keyword, but "record" is a more general, language-agnostic term for nominal tuple types in the literature.
2. Yes, it is widely accepted that a has-a relationship is the proper way to compose data. Using inheritance for composition is bad practice.
3. The article mentions inline classes, which is what the proposed value type feature is called these days. Presumably many or most record types will be inline if and when they're both implemented in some future Java version.
Disclaimer: it's been a long time since I coded in Java, and I have no knowledge of this new record feature, but coming from clojure I would guess the answers to be:
1. You can't change a record after the fact because if you do it's no longer reliable, it's been tampered with :)
2. Yes, existing records only. You can always create a new record pointing to the old or any other record.
3. Hope not, would make it unpractical to handle verbose facts.
They are not that similar to a struct in C in that they are not just about being a data carrier. So that might be confusing if that is what you expect.
Future work is intending to solve the third point and add deconstructing the record for pattern matching.
“We can declare a simple x-y point abstraction as follows:
record Point(int x, int y) { }
which will declare a final class called Point, with immutable components for x and y and appropriate accessors, constructors, equals, hashCode, and toString implementations.”
Records are great. If sealed classes become a thing (https://openjdk.java.net/jeps/360) I'll be absolutely elated. And it would be just the cherry on top if the two could be used together (along with a private constructor). Scala has this, i.e. `sealed abstract case class`, Kotlin does not, i.e. `sealed data class` is not valid.
I am thrilled that algebraic datatypes (effectively the combination of records and sealed classes) are finally entering mainstream consciousness and that statically typed languages all over the place are starting to adopt them.
I perhaps should have been more explicit about the goal rather than the method, since sealing records is only one part of this.
This is all in service of private constructors. You effectively cannot have private constructors for data classes in Kotlin because the copy method remains public and cannot be "turned off." `sealed abstract case class` in Scala gets rid of that.
Private constructors for record types is a fantastic light-weight way of incorporating runtime checks into compile-time types.
At first I thought it was project valhalla merging into mainline java. Apparently this is a java language feature. Java is starting to move away from being the C of jvm. Java constructs are no longer direct mappings of jvm constructs.
You'll still be chasing pointers with these. What you (and myself and many others) are looking for are inline types[0][1] that are part of Project Valhalla[2].
I always thought array elements were contiguous in memory? Is it that the objects are contiguous, but the pointers are not? If so, this does seem pretty expensive and I wonder if there's any workarounds.
Does it strike anyone as odd that something trivial in toy languages from the 70s is a separate project 30 years in and named for the the heaven of the gods in the world of Java?
Thanks, you're right on. That's what I'm after and that's exactly what Java needs to be useful for doing high performance computations in a sane fashion.
These seem extremely similar to Scala's case classes. In my experience, case classes are often the feature that sells people on moving over to Scala from Java (the other being exhaustive pattern matching warnings from the compiler).
Fingers crossed Java never implements the `implicit` keyword...
The implicit keyword is extremely powerful when used appropriately and not something that should just be shunned completely.
My favorite usage is probably in a typesafe Query engine that several people[1] built at Foursquare that is a lot better than what you can find in the java world.
Actually, implicits aren't going anywhere in Scala 3.
There will be new syntax, but otherwise the underlying semantics will remain the same; it's just the implicit keyword itself and the kitchen sink of functionality that it provides in Scala 2 will be split up into new (soft) keywords like "given foo(using: Bar) = ..." rather than "implicit def foo(implicit bar: Bar) = ...", along with "extension listOps of" replacing "implicit class ListOps ...".
The community isn't united over the proposed changes (mostly due to migration concerns it seems), but overall it looks like a nice improvement over the status quo, particularly around typeclass definitions.
I only see a superficial similarity. Case classes are much more powerful. Copy constructor, private constructor, pattern matching, overrideable apply/equals/hashcode. Granted, some of that stuff is esoteric, but it does make case classes a very different beast.
The keywords you refer to in your link are all "classic" keywords. The last one that was added was "assert" with Java 1.4, which broke a lot of code. And made people realize that adding new "classic" keywords was a bad idea.
Now, Java only adds contextual keywords. Which are basically a sequence of Java letters that are tokenized as a keyword in certain contexts but as an identifier in all other contexts. var, record, inline, module, ect. are examples hereof.
At what points in a valid legal Java program could you have previously written record, where it would now conflict with this keyword in the locations where it is valid?
1. Why not just call these "structs"? Everyone knows what a struct is. Also making "struct" a reserved keyword is less likely to cause issues than "record";
2. I get that these are trying to be simple but why can't I compose records from other records? I guess I can have a record member of a record?
3. I couldn't see if records can be passed entirely on the stack like primitive values can. This would be huge. I seem to recall there was some effort to add this to Java but I'm not sure whatever happened to that. It probably added a ton of complexity.
2. Yes, you can make records of other records.
3. Not yet, but Project Valhalla will be bringing inline types to Java https://wiki.openjdk.java.net/display/valhalla/Main
https://github.com/dotnet/roslyn/blob/features/records/docs/...
It's a struct or class but you only define the data members and the compiler auto-generates boiler plate like constructors, equality tests, etc.
2. Yes, it is widely accepted that a has-a relationship is the proper way to compose data. Using inheritance for composition is bad practice.
3. The article mentions inline classes, which is what the proposed value type feature is called these days. Presumably many or most record types will be inline if and when they're both implemented in some future Java version.
If you have two records {a: 1, b: 2}, those are equal because they are the same.
If you have two structs {a: 1, b: 2}, those are also equal but they are separate instances that consume more space. The comparison is recursive.
It's more like how string works in Java and most modern languages with constant pools - behaves like values but only takes constant space.
Deleted Comment
https://cr.openjdk.java.net/~briangoetz/amber/datum.html
1. You can't change a record after the fact because if you do it's no longer reliable, it's been tampered with :)
2. Yes, existing records only. You can always create a new record pointing to the old or any other record.
3. Hope not, would make it unpractical to handle verbose facts.
I guess clojure really twisted my mind ;)
Future work is intending to solve the third point and add deconstructing the record for pattern matching.
“We can declare a simple x-y point abstraction as follows: record Point(int x, int y) { } which will declare a final class called Point, with immutable components for x and y and appropriate accessors, constructors, equals, hashCode, and toString implementations.”
I am thrilled that algebraic datatypes (effectively the combination of records and sealed classes) are finally entering mainstream consciousness and that statically typed languages all over the place are starting to adopt them.
This is all in service of private constructors. You effectively cannot have private constructors for data classes in Kotlin because the copy method remains public and cannot be "turned off." `sealed abstract case class` in Scala gets rid of that.
Private constructors for record types is a fantastic light-weight way of incorporating runtime checks into compile-time types.
[0] https://openjdk.java.net/jeps/169
[1] https://dzone.com/articles/valhalla-lw2-progress-inline-type...
[2] https://wiki.openjdk.java.net/display/valhalla/Main
Fingers crossed Java never implements the `implicit` keyword...
[1] - http://learnyouahaskell.com/making-our-own-types-and-typecla...
My favorite usage is probably in a typesafe Query engine that several people[1] built at Foursquare that is a lot better than what you can find in the java world.
It allows for all sorts of typesafe queries that will fail at compile time if things are malformed including stuff like failing to query on an index.https://github.com/foursquare/rogue
1. Hi Jorge, Liszka & Neil!
The best case scenario is that they aren't instantly horrified / confused / repulsed.
More often than not Java programming just consists of throwing gang signs on your keyboard for your Ide to create tons of boilerplate.
Well case classes can implement traits, might have a companion object and can (poorly) replace enums.
Scala sometimes seems to not need standard classes.
Other languages like go, rust or c can do just fine without classes at all.
There will be new syntax, but otherwise the underlying semantics will remain the same; it's just the implicit keyword itself and the kitchen sink of functionality that it provides in Scala 2 will be split up into new (soft) keywords like "given foo(using: Bar) = ..." rather than "implicit def foo(implicit bar: Bar) = ...", along with "extension listOps of" replacing "implicit class ListOps ...".
The community isn't united over the proposed changes (mostly due to migration concerns it seems), but overall it looks like a nice improvement over the status quo, particularly around typeclass definitions.
Now, Java only adds contextual keywords. Which are basically a sequence of Java letters that are tokenized as a keyword in certain contexts but as an identifier in all other contexts. var, record, inline, module, ect. are examples hereof.
You can read more about it in this JEP Draft about "keyword management for the Java Language": https://openjdk.java.net/jeps/8223002
At what points in a valid legal Java program could you have previously written record, where it would now conflict with this keyword in the locations where it is valid?
Map<String, String> record = getSomeData();
This should no longer be valid if record is a keyword?