Live data from Hacker News

Data Classes for Java

cr.openjdk.java.net

161–170 of 216 posts

Re: Data Classes for Java

#162
post #32

Earlier quoted context omitted.

> Possibly more importantly, public fields give you no way to create immutable types. public readonly int Foo; readonly fields can only be set in the constructor, great for immutable types and with much better guarantees than protected/private/no setters.

And when you want to make Foo no longer a primary value and instead calculated from some other field? When you want to add logging to every change of Foo? Every access? When you want to switch to having Foo's value come from a database? Web service?

Then that is when you have to change the public field to a property, with no change to calling code.

Reasons for going with a property from the start is if you a) ever use reflection (which would need to change depending on whether the storage is a public field vs a property) b) If you need to implement interfaces using the property. Reasons for going with a public field is for special cases where you know a lot about how inlining affects your performance. Typically in structs.

Since there is no more boilerplate used to write "public int Id { get; }" vs "public readonly int Id", in 99% of cases I'd choose the latter.

Re: Data Classes for Java

#163
post #88

Earlier quoted context omitted.

Make fields public final and your constructor is your "builder".

Those two patterns aren't the same. You can pass around a half constructed builder but you can't pass around a half constructed public final object like you described.

You can in most modern or functional languages, by currying/partial evaluation/binding. It's rare for data classes.

In scala:

    case class Foo(a: Int, b: String)
    val halfBuilt: String => Foo = Foo(1, _)
    val foo = halfBuilt("foo")

Re: Data Classes for Java

#164

Earlier quoted context omitted.

Java reserved words are reserved in all contexts. You can't have a variable called "class" because class is a reserved word. If 'data' becomes a reserved word, imagine the code that would no longer compile...

Not exactly true, but true for this use case. The new module keyword in Java 9 is only a keyword in module-info.java. You can still have a variable named module in regular class files. They wouldn't be able to pull this syntax trick with data as a keyword though.

Why not? `data class X` is currently invalid code. What is the problem with allow the `data` keyword in a class definition and not forbidding it in other contexts?

Re: Data Classes for Java

#165

Earlier quoted context omitted.

I don't think many of Scala's wartier bits will go away without Java getting its act together re: things like type erasure and a bifurcated type system, because a lot of the odder things in Scala are basically workarounds for deficiencies in the underlying platform. And I just don't see much political momentum behind either of those.

Why would type erasure affect the front end language? I'm generally interested.

One of the earliest use cases for implicits is that in Java most types are erased but Arrays aren't, so you can't instantiate an Array in a generic method without having some way to pass the concrete type through.

Re: Data Classes for Java

#166
post #100
post #26

Earlier quoted context omitted.

Is there something that a builder gets you that Kotlin-style data classes doesn't?

One thing I love about builders, besides the sibling replies, is that builders force users to explicitly name the arguments. Passing args to a constructor/method/whatever with implicit argument ordering can be error-prone in certain situations (multiple adjacent args with the same type). c = Class(firstName, lastname) // are these passed in the right order? c = Class(lastName=firstName, firstName=lastName) // obvious…

Named parameters for functions (including constructors) are a good idea - better to build them in as a general case rather than making people read a lot more code to have them in one specific case. Look at what Scala does.

Re: Data Classes for Java

#167

... To write such a class responsibly, one has to write a lot of low-value, repetitive code: constructors, accessors ... If you're writing a plain data class, why on earth would you write getters and setters? Just make your fields public and be done with it. I will be forever perplexed by the idea of getters and setters (and this extends to C#s syntax sugar). I have no idea what problem they solve. If you're at the l…

If you ever have to change a fields meaning or add a new field and provide the old fields value for older clients, you can't just make it private and add a public setters and getters without breaking compatibility for all your users - not just binary compatibility but also source-level compatibility.

Re: Data Classes for Java

#168
post #85

Earlier quoted context omitted.

Today's fields are tomorrow's computed properties. Fields are rigid and cannot be changed without recompiling dependencies. Notice how few fields there are in Java's standard library. Why have fields at all?

How many times have you run into this in your career (the need to convert "today's fields to tomorrow's computer properties")?

Enough times that I remember it. Luckily, with modern IDEs, going from fields to accessors is just a "refactoring" menu away.

Re: Data Classes for Java

#169
post #68

Earlier quoted context omitted.

How about a class that stores temperature and the current state of the satellite? It's easy to come up with circumstances where requirements change.

Then I would implement it as a "real" class, not a data one. class Satellite { Coordinates coordinates; double celcius; /*** constructors, etc ***/ public double Celcius() { ... } public double Kelvins() { ... } public void Move(...) { /* modifies state */ } } Note how none of the methods make any mention of low level operations like setting/getting internal fields. You could make the argument that I do have a getter…

The concept of getters & setters exist in languages where it's not conventional to write them as methods named getX() or setX(y).

Writing the that example in C#, you'd likely have

    public double Kelvins {get; set;};
    public double Celsius {
        get { ... }; 
        set { ... };
    }
and [modern] Javascript could have

    let kelvins;
    get celsius()  { ... };
    set celsius(c) { ... };
And you'd set both of them with [eg] s.celsius = 5. This is how getters/setter look when a language supports them.

Writing and using methods named 'getX' and 'setX' is conventional in Java because support for this feature doesn't exist at the language level, but is essentially implemented by the common IDEs. Probably not the ideal situation, but that's where Java is at.

Re: Data Classes for Java

#170
post #51

Earlier quoted context omitted.

And when you want to make Foo no longer a primary value and instead calculated from some other field? When you want to add logging to every change of Foo? Every access? When you want to switch to having Foo's value come from a database? Web service?

Then I'd change it to a property and recompile. If it's value comes from the database or a web service then nothing has to change, whatever is calling the service will invoke the constructor as always. The only exception here is for public APIs, but that's a minority of projects.

> Then I'd change it to a property and recompile

You mean, change it to a property, then fix dozens or hundreds of references, possibly in downstream dependencies some of which aren't under your control and can't be changed. Sounds fun.

Post reply on HN