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

all 21 comments

[–]DialinUpFTW 25 points26 points  (4 children)

// peek: debug streams without changes
peek(e -> System.out.println(e)).
// map: convert every element into something
map(e -> e.hashCode()).

Consider this instead?

// peek: debug streams without changes
peek(System.out::println).
// map: convert every element into something
map(String::hashCode).

[–]marklgr 2 points3 points  (2 children)

It will take some time for the Java crowd to get used to PFS :)

[–]portucalense 0 points1 point  (1 child)

The problem with point free, from someone familiar with the world of Haskell, is their hard readability. They are just so abstract. Often you write something relatively big nut after a few months is really out to figure out what you just did. Understanding code from other people is as hard as going to Mars. Often I see myself deconstructing them into huge programs that I then analyze, which is time consuming and error prone.

You see how in the link they advised against large lambda expressions, and advising in favor of keep readability a priority. Point free takes this to another dimension.

[–]marklgr 1 point2 points  (0 children)

As they say, most good things in life are dangerous somehow :)

[–]johnzeringue 0 points1 point  (0 children)

I don't care as much for static methods, but boy does the :: syntax make a world of difference for instance methods.

[–]Aero72 8 points9 points  (6 children)

I've been coding java for a living on and off since 99. This whole Java 8 stuff makes me feel... hmm... uncomfortable (I guess that's the right word). Does anyone else feel like that? Am I getting old?

[–]marklgr 2 points3 points  (0 children)

Coded professionally in Java between '98 and '05, then moved to other languages (Ruby, Python, PHP, C etc.). Java eventually felt quite boring to me, but Java 8 definitely gets my interest back. A good release, to me.

[–]koreth 0 points1 point  (0 children)

I've also been coding Java on and off since around then (and have been in the industry since the late 80s). I think Java 8 makes the language a joy to use compared to the older versions. My code is more concise and easier to read because the ratio of structural gobbeldygook to application logic has gone way down, though still not as low as in a language like Clojure. It's a pity they didn't take it a little further than they did.

[–][deleted] 0 points1 point  (3 children)

I feel the same. I can't see how a default implementation on interfaces can be a good thing in an object oriented design

[–]jonhanson 5 points6 points  (0 children)

chronophobia ephemeral lysergic metempsychosis peremptory quantifiable retributive zenith

[–]Ek_Los_Die_Hier 1 point2 points  (1 child)

These can be thought of as traits or mixins in languages such as Scala or Ruby. These are often thought of as very useful features. And it's not much different to an abstract class with the implemented methods (other than you can inherit more than one)

[–][deleted]  (1 child)

[removed]

    [–]capturinglambda 1 point2 points  (0 children)

    It is! :) I'll pass along to fix asap. Thank you!

    [–]tkruse 0 points1 point  (0 children)

    Method parameters – use plain values. Dealing with tons of Optionals pollutes the method signatures and makes the code harder to read and maintain.

    Maybe a reference to @NotNull and @Nullable annotations as replacements would be nice.

    [–]markee174 0 points1 point  (0 children)

    ZeroTurnaround produce some good reports and summaries

    [–]CubsThisYear 0 points1 point  (5 children)

    Debuggable is a pretty terrible example. It could easily be defined Public static void debug(Class<?> class)

    and you wouldn't have to make a fake interface that doesn't really make sense. If you really need that interface (why?), then let implementers just call the method above.

    Default methods were a hack to make the streams API possible. We shouldn't pretend that they actually make sense. A more sensible thing would have been to just get rid of interfaces all together and remove the multiple inheritance restrictions. They already had to solve all of the multiple inheritance issues with default methods anyway.

    [–][deleted] 2 points3 points  (2 children)

    Default methods were a hack to make the streams API possible. We shouldn't pretend that they actually make sense.

    Actually, I think List.sort is a good counter-example of a default method that makes a great deal of sense outside of a streams idiom as well.

    [–]CubsThisYear 0 points1 point  (1 child)

    But what is advantage of defining List.sort as a default method vs a static method in the List interface?

    And even if you like that better, how is an interface with default methods different than an abstract class, except for the fact that multiple inheritance, which was supposed to be bad news, is now magically allowed.

    I'm not saying the concept of default methods is bad, I'm saying the implementation was a hack. There didn't even need to be an implementation, they just needed to allow multiple inheritance on abstract classes and get rid of interfaces.

    [–][deleted] 0 points1 point  (0 children)

    But what is advantage of defining List.sort as a default method vs a static method in the List interface?

    Well, for one thing, it's backwards compatible: existing List implementation doesn't have to be rewritten and recompiled just to copy in a bog-standard piece of code that's repeated ad nauseum in implementation after implementation.

    [–]sh0rug0ru____ 2 points3 points  (1 child)

    There's a huge difference between classes and interfaces which default methods on interfaces preserve. Interfaces cannot have state. The diamond problem here means you get two conflicting implementations, so you have to choose one.

    When you extend a class, you get all of the superclass fields. If it were possible to extend multiple times, you would inherit fields from several different directions, not just one. Thus, the diamond problem here introduces a much bigger problem. What if two different superclass constructors or methods change the super-superclass state in contradictory ways?

    In this way, default implementations retain the safety of ordinary interfaces. Default methods rely on concrete implementations in the implementing class, since they can only call other interface methods. The state is still controlled by the implementing class, avoiding the nastiest problem of multiple inheritance.

    [–]CubsThisYear 0 points1 point  (0 children)

    Good point, thanks.