News for hackers. Stuff that matters.
Re:Java 9 features announced by ryanobjc on Monday August 18, 2014 @04:20PM (#8194425)
It is addressed by better design.

First off, it's important to know the difference between value types and objects.

For a value type, public final fields are good. They are set in the constructor once, and can only be read, and can't change. Getters are pointless, and my code does not have them. If you want them for a reason, then intellij does an amazing job fixing that.

Objects encapsulate mutable state, and getFoo() and setFoo() are inappropriate methods to have. They should be things that affect the behavior of the object, not simple setters and getters.

The big issue is that a lot of java was created when we still hadn't figured out how to properly do Object Oriented Programming. But we know now (well - some of us), and there is nothing in Java that prevents you from doing it well.

Re:Java 9 features announced by adevine on Monday August 18, 2014 @05:41PM (#8194875)
I disagree. A fundamental, language-level problem with Java is that clients need to know when they are accessing a member var, e.g. obj.foo, vs. calling a method, e.g. obj.foo(). This means that its much safer to always wrap things in a method, because if you ever need to change something (or do things like add logging, delegation, or some other filtering behavior), you can do it behind your method without clients needing to change.

Contrast Java with Ruby or C#. There, the clients don't need to know whether they're accessing a member var or calling a method to get/set a property, NOR SHOULD THEY. The inability to do this in Java fundamentally breaks encapsulation.

Re:Java 9 features announced by dragonwriter on Monday August 18, 2014 @06:02PM (#8194959)
> Contrast Java with Ruby or C#. There, the clients don't need to know whether they're accessing a member var or calling a method to get/set a property, NOR SHOULD THEY.

Others have noted that in many contexts in C# there is a difference, so clients do need to know.

As far as Ruby, clients definitely need to know, its just that since public fields can't happen in Ruby, its always method-based access for the normal cases.

Both of these lines are always calling a method on "obj" in Ruby:

  foo = obj.a  # equivalent to foo = obj.a() 
  obj.a = foo  # equivalent to obj.a=(foo)
While these are using instance var (the closest thing to a "field" in Ruby) access:

  foo = obj.instance_variable_get :@a
  obj.instance_variable_set :@a, foo
  foo = obj.instance_eval { @a }
  obj.instance_exec { @a = foo }
There's no common syntax like C#-style properties that unifies field-based and method-based access, so Ruby is sort of the extreme opposite of attempts to have "properties" that make method-based access look the same as field-based access in the same language, even though its method syntax can make method-based access in Ruby look like field-based access in a completely different language.
Re:Java 9 features announced by Guvante on Monday August 18, 2014 @06:30PM (#8195071)
> Others have noted that in many contexts in C# there is a difference, so clients do need to know.

Which is why C# added automatic properties. You get the expandability without breaking clients or having to read/write extra code.

    public int Foo { get; set; }
Re:Java 9 features announced by Renaud on Monday August 18, 2014 @08:26PM (#8195431)
Which becomes even more useful over a field when you can do:

    public int Foo { get; private set; }
Re:Java 9 features announced by marvy on Tuesday August 19, 2014 @03:15AM (#8196286)
Last time I checked (long ago), properties in C# don't work as ref or out parameters. Since C# actually distinguishes between ref and out parameters, it would be pretty easy to extend the language such that properties work whenever fields work, but sadly no one but me seems to care.
Re:Java 9 features announced by Guvante on Tuesday August 19, 2014 @01:05PM (#8198459)
See the following example for why that is excluded.

    public string Foo { get { return ""; } }

    private void DoBar(ref string input) { input = "123"; }

    public void Main() { DoBar(ref Foo); }
Typically C# points you towards using a different methodology than ref/out parameters. But I do agree it is annoying when you want to use them.
Re:Java 9 features announced by bcj on Monday August 18, 2014 @10:23PM (#8195752)
Python has a solution to this. There are decorators that allow you to access methods as if they are properties:

    class Foo(object):
        def __init__(self, bar):
            self._bar = bar

        @property
        def bar(self):
            return self._bar

        @bar.setter
        def bar(self, value):
            self._bar = value
Re:Java 9 features announced by illumen on Tuesday August 19, 2014 @07:27AM (#8196781)
As does Objective-C, and JavaScript.
Re:Java 9 features announced by jayd16 on Monday August 18, 2014 @05:55PM (#8194935)
You haven't addressed his comment at all. Either you're building an immutable object and fields are the proper choice, or you're building an abstract, stateful, concept in which you should be using methods that may or may not map to fields.
Re:Java 9 features announced by gutnor on Monday August 18, 2014 @11:14PM (#8195904)
That works alright up until you need to integrate with third party libraries like JSF, Seam, Hibernate, Jaxb, Spring, EL, plenty of other stuff that requires a "javabean"

Sure, you can beat the big ones into working, and there is generally no shortage of libraries in Java. But at some point you are just wasting resource to work around other people code. Java has properties and some libraries use them.

Discussing if you should use them at all is offtopic, the real problem is that java has properties but instead of being a language/compiler supported feature, it is only defined as a "convention" with some half-assed support classes. Seeing how popular properties are, that either needs fixing or deprecation (starting with all the Oracle provided framework that use them)

Re:Java 9 features announced by rbanffy on Monday August 18, 2014 @04:34PM (#8194502)
> It is addressed by better design.

This! A lot of the horrible Java you see around is nothing but an artifact of mindlessly applying patterns to constructs that don't need them.

> a lot of java was created when we still hadn't figured out how to properly do Object Oriented Programming.

Which is quite unforgivable, considering Smalltalk has been around since the early 80's.

Re:Java 9 features announced by spopejoy on Monday August 18, 2014 @07:09PM (#8195197)
My problem is I don't think there's any agreement what Object Oriented Programming is and isn't, so it's pretty hard to "properly do it".

Let's see. OOP generally involves "objects", ie structs or records with visibility controls on fields, sporting "methods," ie functions with a magic/hidden this/self argument. This alone doesn't buy you much, and in fact is quite inflexible when compared to good old ADTs, so let's hope there's more to it.

OOP does not mean "all methods are defined within the class declaration/file" a la Java, plenty of OOPLs allow external method definition. So it doesn't mean "well in OOP I always know the behavior of my class" when you have friend functions etc.

OOP might mean "abstract classes" ie virtual methods. This leads us to inheritance, which is a) not confined to OOP and b) widely criticized. Remember that inheritance != polymorphism, c.f. Visual Basic for instance (at least VB5. Showing my age...). In practice, OOP usually invokes a great-chain-of-being-like hierarchy descending from Object, but again this is not universal.

OOP generally means "polymorphism", but the mechanisms vary widely. OOP's "Classic" inheritance-driven polymorphism is probably the worst way to do it, good for quick code-reuse and that's about it. "Interfaces"/pure virtual classes are a design pattern on top of abstract classes, better expressed as mixins or type-classes.

OOP generally implies strong typing but not always (python). OOP typing is quite clunky, especially in "noun-oriented" Java. You can make an argument that the rise of DI frameworks is in response to having impoverished type systems.

My semi-rant here is because people say things like "do it this way, it's good OOP" without there being any agreement about whether we're discussing polymorphism, inheritance, encapsulation, factoring, normalization, or design patterns that are largely a response to the confusion.

On the other hand we have folks like the clojure crowd bagging on OOP using similarly vague concepts like "OOP means stateful objects/side effects" ...

Re:Java 9 features announced by king_jester on Tuesday August 19, 2014 @08:48AM (#8197004)
> This alone doesn't buy you much, and in fact is quite inflexible when compared to good old ADTs, so let's hope there's more to it.

It at least buys you a way of organizing your code that makes it easier to understand not just for yourself, but other programmers who read it in the future. Creating objects and using data types isn't really mutually exclusive, you use both as needed.

> OOP does not mean "all methods are defined within the class declaration/file" a la Java, plenty of OOPLs allow external method definition. So it doesn't mean "well in OOP I always know the behavior of my class" when you have friend functions etc.

This is true. The main benefit of OOP in this regard is to help see the interactions between related groups of functions as organized into objects.

> OOP might mean "abstract classes" ie virtual methods. This leads us to inheritance, which is a) not confined to OOP and b) widely criticized. Remember that inheritance != polymorphism, c.f. Visual Basic for instance (at least VB5. Showing my age...). In practice, OOP usually invokes a great-chain-of-being-like hierarchy descending from Object, but again this is not universal.

Inheritance definitely has downsides and should be considered carefully when used, but it also has valid use cases. As with any language feature, it really is more of a question of is this useful to fix the problem I'm trying to solve? Granted, a lot of programmers (at least from the code I've worked on) seem to see inheritance as a universal hammer to their current problem nail :)

> OOP generally means "polymorphism", but the mechanisms vary widely. OOP's "Classic" inheritance-driven polymorphism is probably the worst way to do it, good for quick code-reuse and that's about it. "Interfaces"/pure virtual classes are a design pattern on top of abstract classes, better expressed as mixins or type-classes.

Whether mixins, type-classes, or a polymorphic inheritance is the right choice really depends on language and problem space. At least with mixins there are definitely circumstances where a mixin could have so many methods that it is essentially a form of multiple inheritance. Again, knowing the right tool for the job and knowing what limitations your development language has is more important than the existence of any one feature or tool.

> OOP generally implies strong typing but not always (python). OOP typing is quite clunky, especially in "noun-oriented" Java. You can make an argument that the rise of DI frameworks is in response to having impoverished type systems.

I'm not sure about DI being the result of impoverished type systems. Generally DI is about insuring that function dependencies are explicitly consumed rather than implicitly existing somewhere as a more global state. DI is more about contract enforcement on functions than anything else.

> My semi-rant here is because people say things like "do it this way, it's good OOP" without there being any agreement about whether we're discussing polymorphism, inheritance, encapsulation, factoring, normalization, or design patterns that are largely a response to the confusion.

This is definitely the crux of it. "Good OOP" is a meaningless phrase for the most part. What exactly is good for a project? Given the amount of tools available in OO languages, many different approaches could be used that would function as good based on your particular problem and developers.

Re:Java 9 features announced by sdegutis on Monday August 18, 2014 @05:11PM (#8194704)
This reminds me of two tweets from Nat Pryce[1][2]:

> Colleagues & I once doubled system's functionality & replaced 750K lines of Java with 50K lines of ... Can you guess the language.

> Of course it was Java!

[1] https://twitter.com/natpryce/status/409034320108867584

[2] https://twitter.com/natpryce/status/409232836945010688

Re:Java 9 features announced by kasey_junk on Monday August 18, 2014 @07:02PM (#8195171)
I agree with your design idea, but it fundamentally misses the point of getter auto-properties and that is binary compatibility in the case of future change. That is, if you need to add some functionality to the accessing of the variable. Now I personally don't think this happens much, but it would be nice if the language allowed something that preserved binary compatibility across that change and was not verbose.
Re:Java 9 features announced by stevebot on Monday August 18, 2014 @05:10PM (#8194697)
I agree and I hate getters, but I am one of those who still hasn't figure out how to do OOP correctly. Do you have an example or maybe some suggested reading? For example, if I have a user object, with name, age, number, how would that work without get/set? I'd love to avoid it, I hate the bloat it creates, and also how frivolous it seems to test get/set.
Re:Java 9 features announced by vetler on Tuesday August 19, 2014 @08:23AM (#8196930)
Here's a tip: instead of changing your objects, you can create a new object with the same values except the ones you want to change.

Another option is to use builders (that are mutable), to build/copy your immutable business (?) objects.

Re:Java 9 features announced by mercurial on Tuesday August 19, 2014 @08:43AM (#8196990)
That's what we do at work. Then when work is done, I look at OCaml and repeat the mantra "I'm not going to think about how many lines it takes in Java to do a functional update 'let foo2 = { foo1 with foo_field = "bar" }'".

It is possible to have immutable objects in Java and have the equivalent of functional updates, but it's a hell of a lot of pointless boilerplate. It still beats traditional Java beans, though.

Re:Java 9 features announced by arjie on Monday August 18, 2014 @05:31PM (#8194820)
Well, the answer depends on the function, the purpose. I suppose he's saying that you should encapsulate with the object. For example, you have an OrderLine object, you don't `o.setStatus(CANCELLED)`, you `o.cancel()` etc.
Re:Java 9 features announced by stevebot on Monday August 18, 2014 @06:09PM (#8194990)
That examples makes sense, but what about Strings and other types? I'm not sure you can do the same thing for a User object with name, age etc. I'd love to not have getters/setters but I have yet to see a replacement for all get/set scenarios.
Re:Java 9 features announced by arjie on Monday August 18, 2014 @07:05PM (#8195181)
That's a Plain Old Data object and back in the day the Sun Java Coding Conventions recommended public instance variables for classes which "would have been a struct if Java supported it" or something like that.

I suppose it's all about behaviour. If the class is literally just a struct - a box for data, there's no functionality to describe. Choosing public instance variables vs. getter/setter is just a matter of choice at that point.

The latter let you check Preconditions, etc. but that means that you actually have some invariant you intend to preserve (date of birth of the user cannot be in the future, for instance, so your well-formed user has some characteristics). Any members that can take any value their type permits should, in my opinion, just be public. Logically if you perceive that you could have some invariant in the near future, you'd want to have getters/setters but there's no point overdoing it.

Re:Java 9 features announced by jsmeaton on Monday August 18, 2014 @07:09PM (#8195198)
The parent would have the `User` type as a value type, with read-only final fields.
Re:Java 9 features announced by Alupis on Monday August 18, 2014 @05:19PM (#8194747)
Anyone know what the "sjavac" is about? The link just talks about improving it so it can become the new default... but what is better about it? Is it just the new javac?(why not just in-place upgrade javac then?)

(link provides no real details: http://openjdk.java.net/jeps/199)

Re:Java 9 features announced by Afforess on Monday August 18, 2014 @06:14PM (#8195012)
I was curious myself. I dug up the original proposal to create sjavac, which is here: http://openjdk.java.net/jeps/139
Re:Java 9 features announced by Alupis on Monday August 18, 2014 @06:34PM (#8195081)
Interesting -- finally bringing multiple-core/process compiling to javac. Although, I must admit, I have yet to work on a project where compile times were a major issue. I guess I'm just in the habit of typing "ant release" and getting some coffee ;)
Re:Java 9 features announced by mdaniel on Wednesday August 20, 2014 @11:17PM (#8205781)
It's unclear if you are poking fun, but one of the major features of Eclipse (and ejc, by extension) is the "compile on save", so there is no compilation step while working in your IDE (unless, of course, you desired one).

If that is a goal of the sjavac project, then the ability to compile in parallel the different branches of the dependency tree for a set of classes would make for a major upgrade in user experience.

Re:Java 9 features announced by MrBuddyCasino on Monday August 18, 2014 @05:13PM (#8194718)
This only works well if we get named parameters, too (and maybe defaults). It is too easy to make mistakes with lots of subsequent constructor arguments of the same type.
Re:Java 9 features announced by batbomb on Monday August 18, 2014 @05:31PM (#8194821)
We already have that, it's called the Builder pattern.
Re:Java 9 features announced by stevebot on Monday August 18, 2014 @06:13PM (#8195007)
Up until recently, I've enjoyed the builder pattern. It becomes a pain in the ass though when your objects are deeply nested.

For example, with protocol buffers you end up doing things like.

AlbumCollection collection = user.getPreferences().getFavorites().getAlbums().toBuilder().addAlbum(album).build();

Favorites favorites = user.getPrefernces().getFavorties().toBuilder().setAlbumCollection(collection).build();

Preferences preferences = user.getPreferences().toBuilder().setFavorites(favorites).build();

and then you have to work your way up the chain of builders. Such a pain in the ass for something that could be much simpler with getters and setters.

Re:Java 9 features announced by ollysb on Monday August 18, 2014 @06:50PM (#8195135)
This seems like a perfect example of a pattern applied in the wrong way. The builder pattern is supposed to be used to construct new instances (in other languages named parameters make it pretty redundant). I could perhaps understand allowing people to batch up changes but when you're forced to switch to a builder and back again to make a change to one field you've definitely got a poor design. The example seems particularly egregious because you're also forced to walk the domain where really you should just be able to do:

    user.addFavourite(album);
Re:Java 9 features announced by kasey_junk on Monday August 18, 2014 @07:33PM (#8195268)
His example is creating new instances. It just happens to be creating them from existing instances. Basically a clone and change kind of operation.

You are right that normally you'd want the addFavourite method but in his example he is dealing with generated code which has a tendency towards verbosity.

You could add the method if Java allowed extension methods...

Re:Java 9 features announced by nostrademons on Tuesday August 19, 2014 @01:06AM (#8196087)
If you used the generated builder methods provided by protobufs, would it really be that bad?

  user.getPreferencesBuilder()
      .getFavoritesBuilder()
      .getAlbumsBuilder().addAlbum(album).build()
Re:Java 9 features announced by mercurial on Tuesday August 19, 2014 @08:46AM (#8196999)
> Up until recently, I've enjoyed the builder pattern. It becomes a pain in the ass though when your objects are deeply nested.

That and good luck adding a new required field in your "constructor", because you just gave up on statically checking the parameters of the "constructor".

Re:Java 9 features announced by mercurial on Tuesday August 19, 2014 @01:49PM (#8198745)
Can't say I understand the downvotes on this one. If you add a parameter in a traditional constructor but don't update the site calls, your code won't compile. If you add a builder method, your code will still happily compile, you'll have to wait until runtime to get an exception, if you added a check in the build() method. That's something to think about, just like you give up safety for convenience when you move to a DI framework.
Re:Java 9 features announced by MrBuddyCasino on Thursday August 21, 2014 @10:49AM (#8207593)
So for every class in Java, we just create a corresponding builder class, because we lack certain features in the language?

This is not a solution, this is a workaround.

Re:Java 9 features announced by pjmlp on Tuesday August 19, 2014 @08:27AM (#8196938)
> The big issue is that a lot of java was created when we still hadn't figured out how to properly do Object Oriented Programming.

Bollocks, there were already plenty of OO languages when Java appeared on the block.

Re:Java 9 features announced by sltkr on Tuesday August 19, 2014 @08:40AM (#8196981)
Sure, but more radicial OO languages like Smalltalk were full of getters/setters too (e.g. in Smalltalk all member variables are private, so getters/setters are the only way to access those) so it makes sense to think that this was just the way to go.
Re:Java 9 features announced by pjmlp on Tuesday August 19, 2014 @10:08AM (#8197326)
Eiffel introduced properties in 1985.

The famous CLOS book was written in 1988, which makes use of slots instead.

I am at work now, otherwise I could provide more information.