The Forum for Discussion about The Third Manifesto and Related Matters

You need to log in to create posts and topics.

Java gets tuples

It's astonishingly difficult to come up with a record concept in a programming language that checks all the boxes. The compiled languages tend to treat all identifiers as compiler fodder, not be seen at runtime. Variables become pointers to memory locations, and fields in a record are memory offsets. Dynamic languages turn both variables and record members into dictionaries. Both tend to provide some control over name visibility, but otherwise really different.

The designers of Java made a decision (presumably while it was still Oak) that all user-defined types are classes. Even enums are classes. So records are just classes, with a few handy features to make life easier for programmers. Members are effectively a memory layout within the class. Backward compatibility sits high on the priority list.

I think Haskell is in rather a different place. It's always had a strong experimental culture with divergence of solutions to problems. It would obviously be a good idea to pick one and go with it, but will that happen? And will it look more like a memory layout, or more like a dictionary, or something uniquely Haskell-ish? Time may tell.

Andl - A New Database Language - andl.org
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Thanks Dave, hmm now I'm confused.

This seems (on a quick scan) very comparable to what's been in Haskell for a long time. Yes Haskell records have nominal not structural typing. (To be precise, bits like the compiler auto-generating the hashCode()  has been in place less than 10 years, but value-equals(), toString() equivalents date back to Haskell 1998. And Haskell has always had pattern matching on records. Of course Haskell records are not pointers to updatable structures: you 'update' by creating a new record with some fields copiied-forward.

I'm confused because the constant complaint is that Haskell's functionality is embarrassingly poor compared to other languages. And there's a design process been going on for several months trying to improve it, but failing to get much agreement (which has been the problem all along; there's no lack of 'just make it like C++'/'no, make it like Idris/Scala/...'/'no that'll break a lot of code').

And in Haskell there's heaps of packages providing record-alikes via generics and/or macros/templating -- of course they're mutually incompatible, and incompatible with this latest proposal.

So this latest in Java is trying to compiler-generate what otherwise needs a load of boilerplate code. Aside from the volume of boilerplate, was anybody unhappy with using as-was Java records?

In the Java world, there's always someone who's unhappy with everything, but there weren't Java records before. There were only -- and still are only -- classes. The new record is just a built-in mechanism for generating a class. It mainly looks like a built-in replacement for Lombok, which a popular third-party library for generating "record" classes.

Pretty much everyone in the Java world is ok with classes.

I presume those complaining that "Haskell's functionality is embarrassingly poor compared to other languages" don't mean Java, C#, or similar ilk when they're talking about "other languages."

To tease this out a bit, the chief complaint with Haskell is wrt namespacing for fields. The Oracle blog says

Each component gives rise to a final field that holds the provided value and an accessor method to retrieve the value. The field name and the accessor name match the name of the component. ...

One consequence of this is the field names become your API, so it becomes even more important to pick good names.

Does this mean that creating a record type FXOrder with field units clashes with record SwapOrder having field units? It does in Haskell98, meaning that you have to declare them in separate modules/namespaces. The reason in H98 is it wants the field name to uniquely identify the record type for both building and accessing that record type. (It's quite happy for the field's type to be polymorphic; but to have both-ways polymorphism was thought to be too much indeterminism, especially given that records typically have components (fields) that are themselves records, to deep nesting.)

Are these Java records of the classes everybody is "ok with"? the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Thanks Dave, hmm now I'm confused.

This seems (on a quick scan) very comparable to what's been in Haskell for a long time. Yes Haskell records have nominal not structural typing. (To be precise, bits like the compiler auto-generating the hashCode()  has been in place less than 10 years, but value-equals(), toString() equivalents date back to Haskell 1998. And Haskell has always had pattern matching on records. Of course Haskell records are not pointers to updatable structures: you 'update' by creating a new record with some fields copiied-forward.

I'm confused because the constant complaint is that Haskell's functionality is embarrassingly poor compared to other languages. And there's a design process been going on for several months trying to improve it, but failing to get much agreement (which has been the problem all along; there's no lack of 'just make it like C++'/'no, make it like Idris/Scala/...'/'no that'll break a lot of code').

And in Haskell there's heaps of packages providing record-alikes via generics and/or macros/templating -- of course they're mutually incompatible, and incompatible with this latest proposal.

So this latest in Java is trying to compiler-generate what otherwise needs a load of boilerplate code. Aside from the volume of boilerplate, was anybody unhappy with using as-was Java records?

In the Java world, there's always someone who's unhappy with everything, but there weren't Java records before. There were only -- and still are only -- classes. The new record is just a built-in mechanism for generating a class. It mainly looks like a built-in replacement for Lombok, which a popular third-party library for generating "record" classes.

Pretty much everyone in the Java world is ok with classes.

I presume those complaining that "Haskell's functionality is embarrassingly poor compared to other languages" don't mean Java, C#, or similar ilk when they're talking about "other languages."

To tease this out a bit, the chief complaint with Haskell is wrt namespacing for fields. The Oracle blog says

Each component gives rise to a final field that holds the provided value and an accessor method to retrieve the value. The field name and the accessor name match the name of the component. ...

One consequence of this is the field names become your API, so it becomes even more important to pick good names.

Does this mean that creating a record type FXOrder with field units clashes with record SwapOrder having field units?

No, I believe it means that given an instance variable p of record type FXOrder, and instance variable q of record type SwapOrder, you could say p.units() or q.units() without problems.

It does in Haskell98, meaning that you have to declare them in separate modules/namespaces. The reason in H98 is it wants the field name to uniquely identify the record type for both building and accessing that record type. (It's quite happy for the field's type to be polymorphic; but to have both-ways polymorphism was thought to be too much indeterminism, especially given that records typically have components (fields) that are themselves records, to deep nesting.)

Are these Java records of the classes everybody is "ok with"?

Not sure I understand the question. Java currently doesn't have any inbuilt construct called "records".  You can currently use a third-party library like Lombok to code-generate classes to use as records from simple specifications of the desired record. The new record construct makes it a built-in feature.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

Contrast that Haskell classes contain only methods; and data is declared with a data declaration. You can extend classes with extra methods (in effect, by declaring an extra class that inherits the base class's methods). You can't extend datatypes.

I take David's earlier point that designing a records system gives you a hiding to nowhere. I suspect a structurally-typed system is more like a bundle of methods than a bunch of fields; which is why it won't fit Java nor Haskell.

OTOH, the more I see attempts to improve Haskell, the more I dislike the baroqueness in the designs; and the more I hanker after structural-typing. This recent proposal is making a land-grab for one of the few remaining bits of syntactic real-estate, so as I see it it's closing off any hope of getting Haskell majorly better. (I don't think I'm letting the perfect get in the way of the good enough. But perhaps the Haskell community will live with: no worse than Java.)

Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

Presumably it's the same justification as this...

Contrast that Haskell classes contain only methods; and data is declared with a data declaration. You can extend classes with extra methods (in effect, by declaring an extra class that inherits the base class's methods). You can't extend datatypes.

...where a Java record is notionally isomorphic to Haskell's data types.

The justification from the horse's mouth, so to speak, at https://openjdk.java.net/jeps/359 is:

Records are implicitly final, and cannot be abstract. These restrictions emphasize that the API of a record is defined solely by its state description, and cannot be enhanced later by another class or record.

"Implicitly final" means they can't be extended, but it looks like you may be able to define methods within the record definition which would allow the methods in (say) PointOperations to be defined inside Point.

But I'm not certain about this. When I get a moment, I'll download the Java 14 release candidate to try it.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from Dave Voorhis on February 7, 2020, 9:33 am
Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

...

The justification from the horse's mouth, so to speak, at https://openjdk.java.net/jeps/359 is:

Records are implicitly final, and cannot be abstract. These restrictions emphasize that the API of a record is defined solely by its state description, and cannot be enhanced later by another class or record.

"Implicitly final" means they can't be extended, but it looks like you may be able to define methods within the record definition which would allow the methods in (say) PointOperations to be defined inside Point.

But I'm not certain about this. When I get a moment, I'll download the Java 14 release candidate to try it.

Hmm, if the operation amounts to an alternative PossRep such as Polar() or even a read-only such as Area(), that's not interfering with the state description. Even if it's some operation that updates the visible state description, such as using Polar() as a shorthand to update Cartesian coords, I'm not seeing any harm. But I guess Java has no concept of extending a class with only methods vs bundling extra fields with methods(?)

Haskell very strictly keeps datatypes and their fields and names distinct from classes/methods -- to the extent it's probably misleading to an OOP-er to call them 'classes'. I'll continue teasing-out in a separate message, if that isn't stretching your patience too far off-topic.

Quote from Dave Voorhis on February 7, 2020, 9:33 am
Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

Presumably it's the same justification as this...

Contrast that Haskell classes contain only methods; and data is declared with a data declaration. You can extend classes with extra methods (in effect, by declaring an extra class that inherits the base class's methods). You can't extend datatypes.

...where a Java record is notionally isomorphic to Haskell's data types.

I think not. Haskell has a layering of declarations; and you can define datatypes without record-alike access; and your functions/methods can work fine with positional access. Then opting to include field names in your datatype decl amounts to defining a shorthand to the positional access.

I think this 'shorthand to positional' is the root of the blessing/curse. The compiler is not at liberty to abstract-away or re-order the field names: each name is tied to a specific position in a particular datatype. Indeed it's common to 'mix modes' within the same program:

* If you're building a whole data structure/record or accessing nearly all its fields, use a positional constructor and positional pattern match on the structure.

* If it's a one-off field, use the field name.

* The compiler having to support both and keep them aligned is something like SQL's supporting both named and positional access. (But at least there's no projecting or extending data structures: you must name and declare a different structure and map fields to it individually.)

So the more I look at Haskell's attempts to in effect shoehorn structural typing on top of this, the more I can see it's adding compiler complexity without really delivering what coders want. I guess Java records will face the same limits.

Quote from AntC on February 9, 2020, 6:46 am
Quote from Dave Voorhis on February 7, 2020, 9:33 am
Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

...

The justification from the horse's mouth, so to speak, at https://openjdk.java.net/jeps/359 is:

Records are implicitly final, and cannot be abstract. These restrictions emphasize that the API of a record is defined solely by its state description, and cannot be enhanced later by another class or record.

"Implicitly final" means they can't be extended, but it looks like you may be able to define methods within the record definition which would allow the methods in (say) PointOperations to be defined inside Point.

But I'm not certain about this. When I get a moment, I'll download the Java 14 release candidate to try it.

Hmm, if the operation amounts to an alternative PossRep such as Polar() or even a read-only such as Area(), that's not interfering with the state description. Even if it's some operation that updates the visible state description, such as using Polar() as a shorthand to update Cartesian coords, I'm not seeing any harm. But I guess Java has no concept of extending a class with only methods vs bundling extra fields with methods(?)

No, in Java there is no means to allow extending a class with additional methods but disallow additional fields.

That might be a feature of other, more sophisticated Java-compatible JVM languages like Kotlin or Scala; I don't know.

Given a record class's fields are declared 'final', there would be no means to update coordinates. Nor is there multiple representations similar to Possreps. There is only one record structure, i.e., a specific set of fields.

Quote from AntC on February 9, 2020, 7:15 am
Quote from Dave Voorhis on February 7, 2020, 9:33 am
Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

Presumably it's the same justification as this...

Contrast that Haskell classes contain only methods; and data is declared with a data declaration. You can extend classes with extra methods (in effect, by declaring an extra class that inherits the base class's methods). You can't extend datatypes.

...where a Java record is notionally isomorphic to Haskell's data types.

I think not. Haskell has a layering of declarations; and you can define datatypes without record-alike access; and your functions/methods can work fine with positional access. Then opting to include field names in your datatype decl amounts to defining a shorthand to the positional access.

I meant only that the new Java record feature seem to be similar to Haskell's data types -- like tuple types in general, in various languages.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from AntC on February 9, 2020, 6:46 am

But I guess Java has no concept of extending a class with only methods vs bundling extra fields with methods(?)

Java has a concept of extending, and while extending you, as a designer, have the freedom to do any of the above (e.g. extend with only methods by your own "disciplined" choice).

java does not have a concept of "particular kinds of extending" in the sense you indicated above, e.g. where the developer declares that he's going to do "methods-only" or "fields-only" and the language/compiler subsequently verifies whether or not the developer keeps up to the promise.

The definitional problem for java, as I perceive, is that a class consists of ***members***, and "members" is not limited to just [state-carrying] fields and methods (e.g. -inner- classes can also be members).

Quote from Dave Voorhis on February 9, 2020, 12:53 pm
Quote from AntC on February 9, 2020, 6:46 am
Quote from Dave Voorhis on February 7, 2020, 9:33 am
Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

Java programmers are generally ok with classes.

the blog says

The java.lang.Record class cannot be directly extended, ...

I would have thought any data structure you might want to declare additional methods besides put/get -- for example, area() of the classic shapes or polar()  of a cartesian co-ord. (You can arbitrarily add methods for Haskell records, although it requires rather more code than for standard equal(), toString().)

You may not extend a record via inheritance. If you have a record Point and wish to define polar() for it, you'd be expected to define a class like PointOperations that either references a Point specified via the PointOperations constructor or (more likely) defines polar() as polar(Point p).

So PointOperations is a class containing only methods; whereas class Point contains only the record? This is to avoid 'bundling' methods with data? Except class Point includes methods to access the data/fields (and data without any means to access it would be useless). So what's the rationale for a separate PointOperations class?

...

The justification from the horse's mouth, so to speak, at https://openjdk.java.net/jeps/359 is:

Records are implicitly final, and cannot be abstract. These restrictions emphasize that the API of a record is defined solely by its state description, and cannot be enhanced later by another class or record.

"Implicitly final" means they can't be extended, but it looks like you may be able to define methods within the record definition which would allow the methods in (say) PointOperations to be defined inside Point.

But I'm not certain about this. When I get a moment, I'll download the Java 14 release candidate to try it.

Hmm, if the operation amounts to an alternative PossRep such as Polar() or even a read-only such as Area(), that's not interfering with the state description. Even if it's some operation that updates the visible state description, such as using Polar() as a shorthand to update Cartesian coords, I'm not seeing any harm. But I guess Java has no concept of extending a class with only methods vs bundling extra fields with methods(?)

No, in Java there is no means to allow extending a class with additional methods but disallow additional fields.

Thanks, and thank you to Erwin for more detail.

That might be a feature of other, more sophisticated Java-compatible JVM languages like Kotlin or Scala; I don't know.

I'm trying to reconcile what Java 14 provides vs the "horse's mouth" bit you quote about state description. I think Scala follows Haskell pretty closely on this point: it compiles to JVM, but its semantics are much closer to FP.

I don't see that extra methods has any effect on the state description. Erwin mentions inner classes, but again that would not have an effect if they included only methods(?)

Given a record class's fields are declared 'final', there would be no means to update coordinates.

Ah, by "update" I meant 'update'. That is, a function that takes an existing Point instance and some delta to the Polar() values, and returns a new Point instance whose coords result from applying the deltas.

Nor is there multiple representations similar to Possreps. There is only one record structure, i.e., a specific set of fields.

In the past I've been dismissive of Multiple PossReps on the grounds no other language does that. And that would be true of Haskell 98 and the revised 2010 standard. But over the past decade, Haskell has grown features that come close to Multiple PossReps. Yet with a difference: the data decl is the one that gives 'the' Representation. Alternative Representations can be used for read and 'update', but need not be available for every possible value of 'the' Representation. They're aimed at representation-hiding and applying constraints beyond type-constraints.

The features are recent-ish, but the ideas are not (Wadler, again, mid-1990's; the delay was in figuring out how to integrate them into the type system). I'd have thought Java would want representation-hiding(?)

Quote from AntC on February 9, 2020, 7:15 am
Quote from Dave Voorhis on February 7, 2020, 9:33 am
Quote from AntC on February 7, 2020, 6:22 am
Quote from Dave Voorhis on February 3, 2020, 10:51 am
Quote from AntC on February 3, 2020, 9:38 am
Quote from Dave Voorhis on February 2, 2020, 12:46 pm
Quote from AntC on February 2, 2020, 12:25 pm
Quote from Dave Voorhis on February 1, 2020, 12:05 pm

For those interested in Java development, see https://blogs.oracle.com/javamagazine/records-come-to-java

Notably, still nominal typing rather than structural, but this is unsurprising in the overall context of Java.

Java only has classes, which you use to create records and everything else. The new record is just a convenience for creating certain classes.

...where a Java record is notionally isomorphic to Haskell's data types.

I think not. Haskell has a layering of declarations; and you can define datatypes without record-alike access; and your functions/methods can work fine with positional access. Then opting to include field names in your datatype decl amounts to defining a shorthand to the positional access.

I meant only that the new Java record feature seem to be similar to Haskell's data types -- like tuple types in general, in various languages.

Hmm. hmm. Tuple types in general do not have named access, only positional. Haskell's name-accessed data types are not Haskell "tuples". I think the differences are the sort of detail the devil inhabits. It looks like Java 14 records do not support positional access; whereas Haskell name-accessed data types must support positional access.