Live data from Hacker News

Java 8: No more loops

deadcoderising.com

91–99 of 99 posts

Re: Java 8: No more loops

#91
post #10

I really want to like functional programming, but the functional version of each of these seems less readable and more verbose.

This was exactly what I was thinking when I read the code. The goal should not be to remove loops. As a language construct there is nothing wrong with loops itself. The goal should be to make more readable and maintainable code, preferably without increasing verbosity. The functional alternatives posted here are not actually code quality improvements and should not be presented as such.

Well, it depends. I think the primary improvement is that loop is no longer a language construct. It is just another function. As a prime example I would take Clojure.

On first look: "No loops?" "This reduce functions everyhere look ugly."

On second look: "Oh, I can import paralel reduce instead of the single-threaded one?" [1] "Somebody created a library to transparently switch between local reduce and one using hadoop?" [2]

[1] http://clojure.org/reducers [2] https://github.com/aphyr/tesser

Re: Java 8: No more loops

#92
post #69

Earlier quoted context omitted.

If you ever want to change the implementation of Article, you'd break anyone that was using that part of your API. If you use getters, you can change your implementation without breaking the consumers of your API. For instance, let's say that you don't want to store the author's name as a string anymore, and want to store a reference to an Author object. If you have a getAuthor() method, you can change it from a simp…

> If you ever want to change the implementation of Article, you'd break anyone that was using that part of your API. If you use getters, you can change your implementation without breaking the consumers of your API. Then it wouldn't be immutable, if I can change the implementation I can also create a mutable version. Edit example public class Article { private final String title; private final String author; private…

For some reason seeing your code really bothers me. Is it normal to ever use private variables in inheritance like that?

Say you had toString() in Article class that returned ("%s%" author, title).

Now if you create a MutableArticle on it, ma.toString() will return null unless you override toString on it as well (since Articles variables are private and not inherited).

I don't code much so I don't know is it normal to see code like that?

Also less relevant but Articles constructor should probably be public?

Re: Java 8: No more loops

#93
post #91
post #10

Earlier quoted context omitted.

This was exactly what I was thinking when I read the code. The goal should not be to remove loops. As a language construct there is nothing wrong with loops itself. The goal should be to make more readable and maintainable code, preferably without increasing verbosity. The functional alternatives posted here are not actually code quality improvements and should not be presented as such.

Well, it depends. I think the primary improvement is that loop is no longer a language construct. It is just another function. As a prime example I would take Clojure. On first look: "No loops?" "This reduce functions everyhere look ugly." On second look: "Oh, I can import paralel reduce instead of the single-threaded one?" [1] "Somebody created a library to transparently switch between local reduce and one using had…

I understand what you're saying and you make good points but I still do not think removing a loop as a language feature is necessarily an interesting goal. Generally speaking this discussion tends to revolve around reducing verbosity or doing more with less (so, generalizing multiple language features into a single one). I'm just not sure if that's the most interesting discussion to have. The goal and primary focus should be clean, readable, maintainable code. If I buy a more maintainable and more easy to share codebase with a few extra lines of code or a more verbose expression of a loop that's a trade I'd always make (note; I'm not claiming that's necessarily a trade you need to make for every case in every language).

Re: Java 8: No more loops

#94
post #69

Earlier quoted context omitted.

> If you ever want to change the implementation of Article, you'd break anyone that was using that part of your API. If you use getters, you can change your implementation without breaking the consumers of your API. Then it wouldn't be immutable, if I can change the implementation I can also create a mutable version. Edit example public class Article { private final String title; private final String author; private…

For some reason seeing your code really bothers me. Is it normal to ever use private variables in inheritance like that? Say you had toString() in Article class that returned ("%s%" author, title). Now if you create a MutableArticle on it, ma.toString() will return null unless you override toString on it as well (since Articles variables are private and not inherited). I don't code much so I don't know is it normal t…

I agree that this design is sub-optimal. However, if a.toString() called the getters instead of using the instance variables directly, you wouldn't have problems.

The Article class is unusable as provided due to the private constructor (in fact, the MutableArticle class wouldn't even compile), but private constructors can be useful. I often use private constructors and instead provide public static methods that call the constructors. This practice is often derided, and goes into Java's perception as a verbose, arcane language, but it allows for improving an API without breaking clients built to previous versions, as well as making an API more clear (since we can give the static methods more descriptive names).

Re: Java 8: No more loops

#95
post #79

In C#, this is significantly more elegant: public IList getDistinctTags(IEnumerable articles) { return articles.SelectMany(a => a.Tags).Distinct().ToList(); } The entire LINQ "empire" (.NET 3.5) is built on top of IEnumerable which was around since .NET 2.0. Streams seem to be very artificial; why not rely on Iterable ? Oh, and no "yield" in Java.

I've done this in Java for almost ten years now articles.findAll{ it.tags.contains("Java") } All I've done is adding groovy.jar

Your example code is not valid Java syntax so you haven't been able to do it in Java for almost 10 years. Your example is written in Groovy, one of many alternative languages for the JVM, along with Scala, JRuby, Clojure, Beanshell (which Groovy was "inspired" by), Jython (which has been around for 18 years now, and originally called "JPython"), Gosu, and more recently Kotlin and Ceylon. Java didn't have such anonymous functions (called "lambdas" in Java, and "closures" in Groovy) until Java 8.

Re: Java 8: No more loops

#96

In C#, this is significantly more elegant: public IList getDistinctTags(IEnumerable articles) { return articles.SelectMany(a => a.Tags).Distinct().ToList(); } The entire LINQ "empire" (.NET 3.5) is built on top of IEnumerable which was around since .NET 2.0. Streams seem to be very artificial; why not rely on Iterable ? Oh, and no "yield" in Java.

"Significantly" is a bit dramatic when we are talking about the difference between a single extra method call. One of the benefits of the Java version is it is easier to understand if you don't have a Java background but do have an FP background. With your C# example you'd need to find the documentation to find out what SelectMany does (which is probably just a helper method that abstracts a map and flatMap call)

> "Significantly" is a bit dramatic when we are talking about the difference between a single extra method call.

It's not just a single method call; it's the entire approach. This entire method chain is something that cannot be done in Java as cleanly as it is in C#. Grouping is a prime example. Compare

    articles.stream().collect(Collectors.groupingBy(Article::getAuthor))
with

    articles.GroupBy(a => a.Author)

Re: Java 8: No more loops

#97
post #76

Earlier quoted context omitted.

No its the price you pay, when you improperly implement generics and do not have polymorphic functions. In other words its the price you pay, if you ignore the developments in computer science in the last 10 years and invent a crippled terrible language in 1995 (roughly the same time OCaml came out) and push it onto the world with success, because you are a big corporation. At the point they introduced generics, ther…

Did you deliberately revese the arguments?

I wanted it to be as close to the Java version as possible. Of course in Haskell you can't write

x.(map f)

Re: Java 8: No more loops

#98

Earlier quoted context omitted.

For some reason seeing your code really bothers me. Is it normal to ever use private variables in inheritance like that? Say you had toString() in Article class that returned ("%s%" author, title). Now if you create a MutableArticle on it, ma.toString() will return null unless you override toString on it as well (since Articles variables are private and not inherited). I don't code much so I don't know is it normal t…

I agree that this design is sub-optimal. However, if a.toString() called the getters instead of using the instance variables directly, you wouldn't have problems. The Article class is unusable as provided due to the private constructor (in fact, the MutableArticle class wouldn't even compile), but private constructors can be useful. I often use private constructors and instead provide public static methods that call…

Thanks for taking time to reply. Didn't think about having toString use the getters instead of accessing the instances directly. I guess in some way that's the more proper way of doing it in the context of OOP.

I'm familiar with Java private constructors and builders/factory methods though, that was more of a minor nitpick, but again thanks for explaining on that.

Re: Java 8: No more loops

#99

Earlier quoted context omitted.

And this is one of the major reasons why Java is regarded as verbose. There's a simple solution (have the compiler transparently rewrite references to x.foo to x.getFoo / x.setFoo and transparently add getFoo/setFoo - the JVM inlines (trivial) getters and setters anyways) and yet Java, in the interests of "transparency", doesn't allow it. And their justification fails. Sure, currently if you read x.foo you know that…

That's one of my favorite things about Swift. I can do, for example: // version 1 var author: String // version 2 var author: String { get {"\(authorFirst) \(authorLast)"} }

C# as well. C# 6 is very concise.
Post reply on HN