News for hackers. Stuff that matters.
Re:Java 1.0 Turns 25 by derefr on Saturday January 23, 2021 @10:47AM (#25883025)
I don’t fault Java programmers for their “love” of getters/setters; they’re taking something that really is a best-practice in certain situations, and which mostly doesn’t hurt otherwise (that best-practice being “making the contractual interface for an object its methods, so that the implementation can change while the interface remains stable”) and just deciding to do it all the time rather than only when it will likely have future benefits.

Which makes a lot of sense, if you look at it through the lens of cultural anthropology. Enterprises dictate approaches like this, because the alternative is leaving the choice to the individual programmer — and these same enterprises don’t hire experienced-enough programmers to trust their judgement. And so all the programmers who work for these enterprises end up absorbing this approach as a social norm, just “something you do”, rather than “independently rediscovering the need for it” in a way that would lead to them actually knowing when it’s useful. So, even when not locked into an enterprise that forces it on them, they just keep doing it, because that’s the culture that’s been inculcated on them (and how all the examples look, how all the libraries do it, etc.)

Personally, I’m not in theory against “unilateral” use of getters/setters, either. I just kind of which they worked in Java the way they work in Ruby: where referencing a field on any object other than `this` would actually just be sugar for a call to the getter/setter. Where the Java optimizer would then take special care to optimize-away the call frame for known-‘trivial’ getters/setters.

Re:Java 1.0 Turns 25 by jrochkind1 on Saturday January 23, 2021 @12:47PM (#25884441)
I was thinking of ruby as you write this... it's not quite true that in ruby "referencing a field on any object... is just sugar for a call to the getter/setter."

It's actually true that ruby makes it impossible to directly access fields in objects other than `self` (ie `this`). Seriously, it's not possible ruby takes away the ability to do so, thereby making it not even a choice anymore, you have to create a getter/setter, it's the only option. There is no sugar, there is simply a prohibition on direct access to iVars in other objects, period.

What might make it look like "sugar" is that parentheses method calls are optional in ruby -- `obj.foo` is just another syntax for `obj.foo()` Whether or not it's a getter, any method at all, nothing special for getter/setter here. That's literally the only thing going on here that makes you think there is "sugar", ruby syntax having parentheses be optional in method calls.

And additionally ruby gives you a shortcut "macro" to defining the getter/setter, `attr_accessor :foo` inside a class body just automatically defines the conventional getter and setter for you. You still do need to define them though, again no "sugar".

So ruby actually comes down solidly on the side of "yes, always use getters/setters"... in some ways this is what you are complaining about, people always doing it, right?

But it turns out differently and not annoying anyone, I think, because it was planned for by the language designers in the first place, both by making it mandatory (eliminating it as a point of debate or as something a programmer will spend any time ever considering when implmeenting), and by providing devices to make it convenient.

I think the choice to make parentheses optional in method calls actually goes along with the choice to forbid direct access to fields in other objects; both because there is now no need to syntactically distinguish between the two, and because it makes it less annoying to forbid. It also causes all sorts of other complexity in writing parsers for ruby though...

Re:Java 1.0 Turns 25 by derefr on Sunday January 24, 2021 @11:20AM (#25893187)
I happen to know a bit about Ruby. (A lot more than I know about Java, as it happens.) Let me pick a few nits :)

#instance_variable_get / #instance_variable_set is a thing. The (default) implementations of these methods on Object are just C code that do direct IVar reads/writes. You can thus think of #instance_variable_get and #instance_variable_set as real “field access” in Ruby. It’s just that, unlike most languages, there is sugar† for the getter/setter, and there isn’t any sugar for the “direct” field access.

† (The setter’s sugar is obvious — `a.b=x` is re-written by the lexer into a call `a.send(:"b=", x)`. The getter’s sugar is less obvious — it’s seemingly just a regular method call. But think about why Ruby makes parens optional on arity-0 method calls in the first place. To sweeten getters into something field-access-looking!)

But, well, you might say, #instance_variable_get is just a method, too! I can override it as I want! Really, it’s just another kind of getter/setter — sort of a categorical one.

Well, let’s go one level deeper — you can literally “reach into” the object to take a look at its IVars as it sees them:

    obj.instance_eval{ @foo }
“Objection! #instance_eval can be overridden! DRb proxy-objects do it!”

Well, okay, let’s get creative, and start breaking through the seemingly pure-OOP semantics of Ruby, revealing the more functional-language underpinnings:

    inst_eval_fn = Object.instance_method(:instance_eval)
    inst_eval_fn.bind(obj).call{ @foo }
Re:Java 1.0 Turns 25 by nsxwolf on Saturday January 23, 2021 @11:31AM (#25883521)
Is anyone not using Lombok these days? I haven’t written a getter or a setter in years.
Re:Java 1.0 Turns 25 by JackFr on Saturday January 23, 2021 @07:29PM (#25887538)
Working with java for 20 years. Have never used Lombok, and honestly don’t personally know anyone who has. (Same with Kotlin.)

It’s a big world.

(Another weird thing for the first 25 years of my career never used anything but Sybase as a relational database — across 5 different firms. Never used Oracle or SQL Server.)

Re:Java 1.0 Turns 25 by pjmlp on Saturday January 23, 2021 @11:54AM (#25883816)
I never used and never plan to. Don't need bytecode magic that my IDE can do for me.
Re:Java 1.0 Turns 25 by marvy on Saturday January 23, 2021 @01:16PM (#25884713)
Consider the following two cases:

1. MyClass has 10 private fields, each with a trivial getter and setter.

2. YourClass has 10 private fields, of which 9 have a trivial getter and setter. The last one has a trivial getter but the setter is non-trivial.

If you use your IDE to write your getters and setters, than the two classes above will look the same at glance.

If you use Lombok, the "special" field will stick out at once.

Personally, I prefer to avoid Lombok and just use public fields. That way, the field with a nontrivial setter will also stick out, and no need for bytecode magic.

Re:Java 1.0 Turns 25 by pjmlp on Saturday January 23, 2021 @03:27PM (#25885732)
When I use my IDE, I use its code navigation features to my profit.
Re:Java 1.0 Turns 25 by marvy on Saturday January 23, 2021 @06:23PM (#25887071)
Okay now I'm curious: what IDE do you use that makes this a non-issue?
Re:Java 1.0 Turns 25 by pjmlp on Sunday January 24, 2021 @02:14AM (#25890024)
Eclipse, here are some tips.

- Ctrl + shift + T => search for types

- Ctrl + O => search for methods

- Ctrl + T => switch between classes

- Filters, https://help.eclipse.org/2020-12/index.jsp?topic=%2Forg.ecli...

Re:Java 1.0 Turns 25 by nsxwolf on Saturday January 23, 2021 @12:47PM (#25884440)
A bean with nothing but fields and a couple annotations is much cleaner and smaller than one full of generated getter/setter code. And I can rename a field without having to fumble around with the IDE to regenerate them.
Re:Java 1.0 Turns 25 by pjmlp on Saturday January 23, 2021 @01:11PM (#25884667)
Never learned to use code navigation tools and respective IDE filters?
Re:Java 1.0 Turns 25 by nsxwolf on Saturday January 23, 2021 @01:18PM (#25884736)
Those aren’t as good as just using Lombok.
Re:Java 1.0 Turns 25 by pjmlp on Saturday January 23, 2021 @01:30PM (#25884846)
Indeed, they don't provide the pleasure to dig out bugs caused by mishandling bytecodes or the verifier.
Re:Java 1.0 Turns 25 by petersellers on Sunday January 24, 2021 @12:47AM (#25889650)
Are you referring to code folding? Stuff like that helps but it's still not as good as Lombok just generating the getters and setters for you. I'm not sure if IntelliJ can filter out some of the other stuff Lombok can generate (builders, value objects, constructors, etc.)
Re:Java 1.0 Turns 25 by pjmlp on Sunday January 24, 2021 @02:06AM (#25889987)
Lombok generates too much for its own good.
Re:Java 1.0 Turns 25 by diroussel on Saturday January 23, 2021 @04:32PM (#25886320)
There is no magic. You have source code and when you compile you get byte code.

In the early versions of Lombok it was a bit dodgy as it used private APIs, but now the compiler has the public hooks and its all good honest compiler plugins.

Re:Java 1.0 Turns 25 by rufus_foreman on Saturday January 23, 2021 @12:12PM (#25884061)
I'm not a fan but the place where I work now uses it and it doesn't bother me as much as I thought it would. IDEs are smart enough to work with it. Although I still wouldn't use it on a project of my own.
Re:Java 1.0 Turns 25 by u678u on Saturday January 23, 2021 @05:19PM (#25886681)
Agreed Lombok is nice, but why can't they just put that in the runtime? You have to be suspicious of every extra package.
Re:Java 1.0 Turns 25 by dkarl on Saturday January 23, 2021 @12:31PM (#25884266)
Yeah, I think it's no accident that the best thing about working on the JVM is the massive ecosystem of popular libraries. Java and the Java community did a pretty good job of solving the problem of extremely large numbers of developers sharing code with little coordination over long timelines. Unfortunately, they did it because that was their vision of how enterprise software would be created: dozens if not hundreds of programmers working together on enormous monolithic applications with months-long release cycles. Your code had to be extremely defensive, so you could change the internals without fear, and also extensible and customizable, so you would be less likely to be interrupted by requests to make changes to support someone else's work. All the extra work and complexity to accomplish that became the "right" way to write Java code regardless of context.
Re:Java 1.0 Turns 25 by The_rationalist on Saturday January 23, 2021 @10:55AM (#25883104)
This is why Kotlin has the best of both worlds. You can access a variable through A.b and it will automatically call the getter if there's one
Re:Java 1.0 Turns 25 by kabes on Saturday January 23, 2021 @11:09AM (#25883252)
Javascript can do the same, but I think it's an anti pattern, since now the caller doesn't know what side effects, or performance characteristics you get by accessing the property with an implicit getter/setter.
Re:Java 1.0 Turns 25 by dragonwriter on Saturday January 23, 2021 @03:34PM (#25885806)
> now the caller doesn't know what side effects, or performance characteristics you get by accessing the property with an implicit getter/setter.

Beyond method call overhead (which may or may not be a given depending on how things are optimized in some languages), the caller doesn't know that automatically with explicit getters/setters, either; you'd have to read the source to know that just as much if they are explicit as implicit (or rely on documentation, which hopefully is complete and current).

Re:Java 1.0 Turns 25 by augustk on Saturday January 23, 2021 @03:47PM (#25885902)
In the programming language Eiffel this is called the uniform access principle.
Re:Java 1.0 Turns 25 by edflsafoiewq on Saturday January 23, 2021 @04:32PM (#25886315)
The uniform access principle is that features are "available through a uniform notation, which does not betray whether they are implemented through storage or through computation"; it doesn't imply anything about what the uniform notation is. Java-style getters/setters also achieve the uniform access principle; everything is accessed only via get_X()/set_X() and never a raw field .X that would betray it was implemented through storage.
Re:Java 1.0 Turns 25 by augustk on Sunday January 24, 2021 @03:19AM (#25890329)
"Although it's a fundamental feature of object-oriented programming, remarkably few OO languages really follow it. (Eiffel is naturally an exception.) Most languages simulate it by convention, hence the habit of using accessors such as getAge in Java and C++ programs."

https://martinfowler.com/bliki/UniformAccessPrinciple.html

Re:Java 1.0 Turns 25 by mgkimsal on Saturday January 23, 2021 @11:06AM (#25883220)
groovy did/does this too. any property automatically has a getter/setter in the compiled code if an explicit getter or setter doesn't exist.