Live data from Hacker News

Java 8: No more loops

deadcoderising.com

71–80 of 99 posts

Re: Java 8: No more loops

#71
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…

Making a class immutable doesn't mean that the implementation is fixed. If you need to change your implementation to store data differently, the consumers of your API shouldn't need to be modified. The following modification to your first class would still be immutable:

  public class Article {
    private final Author author;
    ...
    public String getAuthor() {
      return author.getName();
    }
  }
Also, your first class isn't fully immutable—getTags should be implemented as follows:

  /**
   * @return Unmodifiable list of tags
   */
  public List getTags() {
    return Collections.unmodifiableList(tags);
  }

Re: Java 8: No more loops

#72

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)

SelectMany is flatMap.

Could the java equivalent be?

  articles.stream().flatMap(article -> article.getTags().stream())
Or is the previous map required?

Re: Java 8: No more loops

#73
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…

Making a class immutable doesn't mean that the implementation is fixed. If you need to change your implementation to store data differently, the consumers of your API shouldn't need to be modified. The following modification to your first class would still be immutable: public class Article { private final Author author; ... public String getAuthor() { return author.getName(); } } Also, your first class isn't fully i…

> Also, your first class isn't fully immutable—getTags should be implemented as follows:

True. It would be nice if Java had some immutable collection classes that don't have mutable methods. A method that gets a List made with Collections.unmodifiableList(tags), doesn't know that it is actually immutable.

Re: Java 8: No more loops

#74

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

I saw a quote recently from Rich Hickey: "Elegance and familiarity are orthogonal." I didn't fully understand this concept until I read your post and found myself disagreeing with you, thinking "what is obstinate talking about? OBVIOUSLY the streams way is way more readable and far less verbose". The thing is, I can't believe I'm thinking that because I was exactly in your place a few months ago. Since that time, how…

It might be worth mentioning that I already am quite fimiliar with functional concepts and occasionally use them in my code. I find them more verbose in C++ and Java despite my familiarity with them.

Re: Java 8: No more loops

#75
post #18

Earlier quoted context omitted.

I welcome the functional features, but I have to agree that these specific examples are ugly compared to the more familiar alternatives. Maybe this will look more readable after getting used to it, but I'd much rather be looking at Clojure or Scala for now.

Out of curiosity, could you share an example of how this compares to Clojure or Scala? I am not familiar with either.

Here's a quick version in Clojure. I'm sure it can be done cleaner than this..

  (def articles
    [{:title "title1" :author "author1" :tags #{:Java :t2 :t3}}
     {:title "title2" :author "author1" :tags #{:Jvxa :t2 :t3}}
     {:title "title3" :author "author3" :tags #{:Java :t3}}])
  
  ;; find the first article in the collection that has the tag “Java”.
  (first (filter #(contains? (:tags %) :Java) articles))
  ;; ==> {:tags #{:t2 :Java :t3}, :title "title1", :author "author1"}
  
  ;;get all the elements that match instead of just the first
  (filter #(contains? (:tags %) :Java) articles)
  ;; ==> ({:tags #{:t2 :Java :t3}, :title "title1", :author "author1"}
          {:tags #{:Java :t3}, :title "title3", :author "author3"})
  
  ;;group all the articles based on the author.
  (group-by :author articles)  ;; cheating?
  ;; ==> {"author1"
             [{:tags #{:t2 :Java :t3}, :title "title1", :author "author1"}
              {:tags #{:Jvxa :t2 :t3}, :title "title2", :author "author1"}],
          "author3"
             [{:tags #{:Java :t3}, :title "title3", :author "author3"}]}
  
  ;;find all the different tags used in the collections
  (apply clojure.set/union (map :tags articles))
  ;; ==> #{:Jvxa :t2 :Java :t3}

Re: Java 8: No more loops

#76
post #6

[deleted]

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?

Re: Java 8: No more loops

#77
post #29

Java's one of the worst language examples of using FP collections I've seen. Even with hindsight I still find this to be uglier and unnecessarily more verbose than it needs to be. E.g. same Example in Dart: class Article { String title; String author; List tags; Article(this.title, this.author, this.tags); } Article getFirstJavaArticle() => articles.firstWhere((x) => x.tags.contains("Java")); List getAllJavaArticles(…

Dart looks very elegant. You didn't include "group all the articles based on the author". Would that be equally clean in Dart?

Here's the Clojure version:

  ;; given articles = [{:title "t1" :author "a1" :tags #{:t1 :t2}} .. etc. ]
  ;; These 4 Clojure one-liners replace all the J8 code examples in the article.
  (first (filter #(contains? (:tags %) :Java) articles))
  (filter #(contains? (:tags %) :Java) articles)
  (group-by :author articles)
  (apply clojure.set/union (map :tags articles))

Re: Java 8: No more loops

#78

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.

[deleted]

Re: Java 8: No more loops

#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

Re: Java 8: No more loops

#80
post #61

Any thoughts on performance differences between loops and streams? My gut says that loops, being a more primitive concept are likely to perform better in most situations. In addition I just find loops easier to reason about, but that is probably purely personal.

I have not looked at the java8 constructs surrounding this. This is largely implementation specific. For instance, the .net LINQ to object implementations are largely syntactic sugar around loops (that is they compile to the same thing). Similarly, for loops are frequently just syntactic sugar around while loops.

Have they improved the implementation recently? I have not benchmarked myself, but according to [1], they are slower than the equivalent loop-based code.

    [1] http://arxiv.org/pdf/1406.6631v2.pdf
Post reply on HN