Live data from Hacker News

Data Classes for Java

cr.openjdk.java.net

191–200 of 216 posts

Re: Data Classes for Java

#191
post #46

Earlier quoted context omitted.

The pattern evolved from early Java’s lack of reflection. In order to give tools the ability to set/get data, we got the JavaBean. The culture internalized the pattern, and we’ve been mindlessly doing it ever since.

This is correct. JavaBeans were a bad solution to a problem. It was Swing (or was it AWT then?) that needed it first, so that tool builders could allow widgets to have their properties customised. So the vile JavaBean conventions took hold. I only quibble on the "mindlessly" part. I will never add a get/set in a class if it isn't needed. But invariably, in a Java project, some library somewhere insists that I have th…

> I only quibble on the "mindlessly" part.

I'll grant that you're mindful ;-)

Re: Data Classes for Java

#192
post #164

Earlier quoted context omitted.

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?

That's just not the rest of the Java grammar is designed. It would be an unwelcome edge case.

Re: Data Classes for Java

#193
post #173
post #90

Earlier quoted context omitted.

Appeal to authority. Show me a language with little to no patterns.

I don't think there is a language without patterns. But in other programming languages (Lisp, Haskell), we just call them functions. Edit: Actually, I think your request is even more ridiculous. If what Norvig is saying is true, then every language has patterns, because every language has bugs. So you are asking to substantiate his statement by providing a counterexample.

Bingo!

Re: Data Classes for Java

#194

Earlier quoted context omitted.

I can't speak to Java, but in C#, the original goal was to reduce coupling. You can add behavior to getter and setter methods without breaking binary compatibility among packages. It absolutely is obfuscation, to the extent that encapsulation is just a special kind of obfuscation. Possibly more importantly, public fields give you no way to create immutable types.

> I can't speak to Java, but in C#, the original goal was to reduce coupling. If you want to reduce coupling, why not write a real method? Get/Set couples you to your class fields. If you change your class fields, your getters and setters all suddenly become useless. Maybe I just hate the middle ground (:

No, they don't.

I have, plenty of times in the past, changed a class's implementation details in a way that results in fields being removed, without having to create a breaking change in the associated property getters and setters. All it took was changing their implementation to work with whatever the new thing was.

Re: Data Classes for Java

#195
post #176

Earlier quoted context omitted.

The type within a generic method can't be statically known. Consider a generic library method that creates an array somewhere deep in its internals, and is called from an application compiled separately. Now of course you can say that library method requires some extra information from its caller - but how do you reflect that in the method signature in such a way that the binary compatibility constraints are clear an…

If it creates a specialised concrete array at runtime, then it can't be a truly "generic" method (whereby I assume generic here means parametric polymorphism?). If you want to specialise object arrays to primitive arrays for efficiency, then I do not see why this cannot be a compiler optimization, since the types are statically known at the use sites. Perhaps Java interoperability is the reason for the choices Scala…

> If it creates a specialised concrete array at runtime, then it can't be a truly "generic" method (whereby I assume generic here means parametric polymorphism?).

I'd argue it is, because the semantics of an array are the same whatever that array contains. In any case, there's no nice alternatives: a lot of Java APIs use Arrays, so not being able to work with them would be unpleasant, while having contexts in which you could work with existing arrays but not instantiate new ones would be weird and not a good fit for an immutability-oriented language like Scala (it would match what Java does, but Java is a lot more mutation-oriented).

> not see why this cannot be a compiler optimization, since the types are statically known at the use sites.

The use site for the generics could be arbitrarily many compilation units away from the code that instantiates the array. If it were just primitives then we could use @specialized and generate multiple copies, sure, the issue is that Java arrays are unboxed for any type including custom ones.

> Perhaps Java interoperability is the reason for the choices Scala made, but it doesn't appear that e.g. Scala collections can be used from Java?

They can be used, though in practice it's cumbersome enough that you probably wouldn't want to. The current collections API was created after Scala was relatively well-established and so had different priorities from early language design.

Re: Data Classes for Java

#196

Earlier quoted context omitted.

sure, ok, if you only write immutable classes, by definition you never need setters, right? i won't defend mutable classes (i won't decry them either), because i haven't personally thought tons about the benefits of immutability. i mean, i can see a lot of reasons why it's a good thing to shoot for, and i think it's a thing i often try to shoot for. but people often write mutable classes, or must maintain mutable cla…

If you have a mutable class, and you're modifying its fields, you're doing it for a reason, right? Often it's part of a larger operation. So why not name the method that mutates the field after that reason. I got away from thinking about "I am altering the internal representation of this struct + vtable" to "I am sending a message to this opaque thing and I don't really care how it's done when I'm outside the black b…

> If you have a mutable class, and you're modifying its fields, you're doing it for a reason, right? Often it's part of a larger operation. So why not name the method that mutates the field after that reason. I got away from thinking about "I am altering the internal representation of this struct + vtable" to "I am sending a message to this opaque thing and I don't really care how it's done when I'm outside the black box".

> > but "setters are always bad and i don't understand why anyone would ever use them" seems like a needlessly hard-line sentiment, IMO.

> I have a strong opinion because I read some compelling arguments, thought about a lot, stopped using setters, and the quality of my code improved. I don't see a need to moderate my opinions on programming, especially when that's what I really think. Again, happy to be shown a great counter example and admit I was wrong.

that's all fair. i think we might actually agree more than disagree. all your arguments are compelling, and i could see myself holding a similar opinion after giving the matter more thought.

Re: Data Classes for Java

#197

Earlier quoted context omitted.

Sure, for a simple class like this I would make it immutable too. But the example is just a demonstration of the concept - you should be able to change the implementation without changing the exposed interface. When you first write a class, it may look like a simple bag of fields. But when that inevitably changes, getters and setters allow you to do it without breaking the clients. Even if we keep this immutable, you…

But the example is just a demonstration of the concept - you should be able to change the implementation without changing the exposed interface. My argument is that having getters and setters exposes your implementation. If you have "getFoo" and "setFoo" it exposes that your class contains a value called Foo. My argument is that you should either give your methods better names, or get rid of the pretense of encapsula…

> My argument is that having getters and setters exposes your implementation. If you have "getFoo" and "setFoo" it exposes that your class contains a value called Foo. My argument is that you should either give your methods better names, or get rid of the pretense of encapsulation altogether and just make them public. Get/Set is just an awkward middle ground.

this phrasing/perspective definitely brings me around more to your point.

Re: Data Classes for Java

#198

Earlier quoted context omitted.

I do not see why this problem cannot be solved by a compiler rather than a language feature. The type is statically known. It may require additional metadata alongside class files for separate compilation, but I don't see this as a big issue.

Scala needs to interoperate with other Java languages, and there is no platform-wide spec for supplying such metadata. Even if there were, it couldn't be statically known at compile time in the case where a library written in Scala is being called by code that was written at a later date. And even without that consideration, types still cannot be statically known in cases where you're being handed objects whose type…

> Scala needs to interoperate with other Java languages

But does it? Can I even use e.g. a Scala collection from Java? (let alone Clojure, Kotlin, etc) Certainly it looks easy to import and use Java objects, but that looks to be the extent of it.

> it couldn't be statically known at compile time in the case where a library written in Scala is being called by code that was written at a later date

When you build some new code that uses an existing library, any parametric polymorphic type variables get instantiated at the use sites. Where I admit this isn't true, is the adhoc polymorphic dynamic dispatch via subtyping, but this wasn't given to me as an example. I don't see that ArrayLists and ADTs should present a problem.

> types still cannot be statically known in cases where you're being handed objects whose type is not determined until run time

Again, I think you are referring to dynamic dispatch here? I agree this could be a problem in open class hierarchies. But the ADT encoding in Scala is a closed statically-known hierarchy, so I can't see why it has to cause problems. Truly "generic" or parametric polymorphic code should not depend on type tags or even be allowed to introspect the runtime type, doing so violates parametricity, which ultimately reduces our ability to reason about the code.

Re: Data Classes for Java

#199

... 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…

Some reasons:

- more efficient representation

- thread safety

- security (defensive copy)

- validation

- logging

- debugging

- backward compatibility

Re: Data Classes for Java

#200

Earlier quoted context omitted.

Scala needs to interoperate with other Java languages, and there is no platform-wide spec for supplying such metadata. Even if there were, it couldn't be statically known at compile time in the case where a library written in Scala is being called by code that was written at a later date. And even without that consideration, types still cannot be statically known in cases where you're being handed objects whose type…

> Scala needs to interoperate with other Java languages But does it? Can I even use e.g. a Scala collection from Java? (let alone Clojure, Kotlin, etc) Certainly it looks easy to import and use Java objects, but that looks to be the extent of it. > it couldn't be statically known at compile time in the case where a library written in Scala is being called by code that was written at a later date When you build some n…

> Can I even use e.g. a Scala collection from Java? (let alone Clojure, Kotlin, etc)

Yup to all. Sometimes the code comes out looking a bit ugly (e.g, you can access default parameters from Java, but it's done by calling methods with kind of awful auto-generated names), but the only things you really can't get at are things that relies on implicits, type tags, or traits with fields.

Post reply on HN