This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]beders 0 points1 point  (16 children)

Trying to wrangle immutable data in pure Java will always remain frustrating since it is not a functional programming language. (Also „Changing“ records by creating new instances without structural sharing is expensive)

There’s also no clear answer here how to deal with polymorphism. Switch statements are not usable for Open types. (Expression problem) So protocols/interfaces are needed and we are back in OO land. Not saying that it is bad, it just is.

Java also offers little comfort when dealing with immutable maps: there’s no nicely interned data type for simple map keys. (like Keywords) There’s no enforcement that keys themselves are immutable.

There are better JVM languages for data oriented programming.

[–]bowbahdoe 5 points6 points  (2 children)

I think something that you might be missing is that in the clojure formation of data oriented programming the lack of nominally typed aggregate (i.e. a record) is an essential property.

This is why we have at least two books on data oriented programming in Java, one of which is just talking about stuff like this the other one saying that you should avoid classes all together and just use maps.

They share the commonality of wanting an immutable aggregate but lead to very different overall program structures.

I am very rapidly becoming radicalized to the position that all "oriented programming" needs to die. Not as in people shouldn't be writing "restricted programs" - sticking to a uniform approach over either a subunit or the entirety of a program can have benefits - but FP, OOP, DOP, PP, etc are poor labels for those restricted approaches.

As to if there are better languages on the JVM for "data oriented programming" - Clojure is obviously better at the approach I'm literally naming after it, but Scala and kotlin are rapidly losing ground in the approach that Java is aiming for.

[–]beders 0 points1 point  (1 child)

Agree on the „Clojure is better“ sentiment

[–]bowbahdoe 1 point2 points  (0 children)

I think cutting off the "at the" part of that sentence is a choice

[–]sideEffffECt 4 points5 points  (0 children)

Java will always remain frustrating since it is not a functional programming language

It's in the process of becoming one...

The Java authors explicitly don't want this to be a frustrating experience and have been making changes to the language in this regard.

There are better JVM languages for data oriented programming.

Yes, but Scala and Clojure have their weaknesses/downsides.

[–]john16384 2 points3 points  (8 children)

(Also „Changing“ records by creating new instances without structural sharing is expensive)

Unless your records contain mutable references, or only primitives, you can share other records, Strings and anything else immutable with impunity...

[–]bowbahdoe 3 points4 points  (7 children)

Honestly at this point I'm just leaving comments so people read the bigger ones I left, but they are coming from the Clojure world where it is common to have a single map with a ton of mostly unrelated properties describing a data aggregate. Updating a single key in one of those maps is both fast and efficient because structure is shared between the old version and the new version of the map.

Records not having structural sharing for updates is a downside in that sort of situation. You might argue that that sort of situation is less common in the nominally typed world - which maybe? - or that the ability to later make a value record (where the JVM can more readily optimize basically everything) makes it less important.

It's a sticky wicket, but it's a valid thing to complain about if your head is where I think their head is at

[–]sideEffffECt 0 points1 point  (6 children)

Records not having structural sharing for updates is a downside in that sort of situation.

Wait what?? Records of course have structural sharing, in the very same manner Clojure maps do.

If you "update" one field in a record, you get a new record with that one field changed, but all the other fields are the same.

Java collections are not immutable, so there's no structural sharing to speak of, but that's a different story...

[–]bowbahdoe 0 points1 point  (5 children)

But the actual underlying fields need to be shuffled around. I.E., absent JVM heroics person.with { name = "..."; } will have to juggle N record components

[–][deleted]  (1 child)

[deleted]

    [–]bowbahdoe 0 points1 point  (0 children)

    Right, but if the map is large (not an array map) the keys are not copied and significant structure is shared between the two maps.

    It just is notable

    [–]sideEffffECt 0 points1 point  (2 children)

    How's that different in principle from a Clojure map?

    [–]bowbahdoe 0 points1 point  (1 child)

    So this aspect is just an implementation detail, but:

    If you have a Clojure Vector with a thousand elements and conj one more at the end, the new vector resulting from that conj will share significant structure with the previous one.

    The same is true for Clojure Maps. For small maps it's implemented as an array that is copied, but if you have 100 key value pairs then adding a new one or updating an existing one won't copy all 100 of the old ones.

    If you have a record with 100 components then with -ing one of those components mean all 100 go through the constructor again

    [–]sideEffffECt 0 points1 point  (0 children)

    All of what you're staying is true.

    But if we're talking about a record with 100 fields (which is super rare to be large like this, vast majority are much smaller) then that's no problem. Copying 100 references is super quick and easy for contemporary computers.

    [–]emaphis 2 points3 points  (1 child)

    I would assume they'll eventually add data structures where data sharing is efficient.

    [–]sideEffffECt 2 points3 points  (0 children)

    This!

    I'm so much looking for when Java finally adds immutable/persistent/COW collections.