Live data from Hacker News

Java 8: No more loops

deadcoderising.com

21–30 of 99 posts

Re: Java 8: No more loops

#21
In the last example's "for" loop, a Set would probably be clearer and more efficient than a List for gathering distinct elements, at least for large data sets. I haven't tried the functional Java yet, but I wonder if using Collectors.toSet() and skipping the distinct() stage would be better?

Re: Java 8: No more loops

#22
post #6

[deleted]

"Static typing" is not quite where those come from – mapTo{Int,Long,Double} exist because of Java's primitive/object dichotomy. You can just write map and do the same calculation, but then your lambda will have type ? -> Long (vs. the http://docs.oracle.com/javase/8/docs/api/java/util/function/... , which provides ? -> long).

It's mostly the same semantics, but it costs an extra object for each element in your list. If the only thing you're going to do is sum those longs or serialize them over the wire or something, the extra 6 characters have a significant impact on run-time. There's lots of solutions in this space (e.g. Rust is a static language that uses a lot of "zero-cost" abstractions like tagged pointers that it can prove are safe specifically because of the static types), but Java's "make the programmer do it explicitly" isn't so bad for 1995.

Re: Java 8: No more loops

#23
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.

Re: Java 8: No more loops

#24
post #6

[deleted]

It's the price to pay for implementing generics via type erasure, not for getting functional features in a statically typed language. http://stackoverflow.com/a/24421331

This isn't necessarily due to erasure. This actually about boxing. Reified generics is one way to solve this. Another option is tagged pointers. That is how OCaml handles this[1].

[1] http://stackoverflow.com/questions/3773985/why-is-an-int-in-...

edit: clarity

Re: Java 8: No more loops

#25

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

I don't think the article should have framed it as "let's replace traditional looping constructs," but "let's apply a filter or query to a data set." That's how I've typically seen .NET LINQ written up, and it makes more sense to me.

Re: Java 8: No more loops

#26
This demonstrates a major problem with development of Java since the Collections work (which was fantastic): the libraries suffer from over-engineering and surface far too much implementation flavor in the API.

Who cares about streams? Who cares about Optional? We just want to filter a list in a clear, terse manner. (Some people do care about streams and Optional, and I wish them well, but that's orthogonal to the question at hand.)

Consider the examples given. Here they are implemented in Gosu:

  getFirstJavaArticle() : Article {  
    return articles.firstWhere(\ article -> article.Tags.contains("Java"))
  }

  getAllJavaArticles() : List {  
    return articles.where(\ article -> article.Tags.contains("Java"))
  }

  groupByAuthor() : Map> {  
    return articles.partition( \ article -> article.Author )
  }

  public getDistinctTags() : Set {  
    return articles.*Tags.toSet()
  }
(I cheated a bit on the last one by just using a Set, but that's more appropriate and communicates the uniqueness of the elements in the collection to the API consumer.)

Beyond the dot-star flatmap operator, there isn't anything very fancy going on: just closures being passed to methods, returning familiar classes that don't require additional transformation to pass on to the rest of the world.

It's too bad, because this is certainly good enough. As Jack Nicholson said: What if this... is as good as it gets?

Re: Java 8: No more loops

#27
The examples feel very much like Ruby to me. In a good way. This sort of chaining of operations also feels very natural for someone thinking in terms of a chain of Unix commands piped together.

However, having that explicit "stream()" signifier is a very Java-y thing to do and appears to ask the programmer to decide how best to compile the given line. I would expect the compiler should be doing that work for us.

Re: Java 8: No more loops

#28
post #13
post #12

Earlier quoted context omitted.

I disagree. The benefit of having the standard terms is they are the same in every FP library you use. If you spend the time to learn and internalize them within one, it'll be the same in every language or library that implements them. I don't understand how map, filter, collect, reduce are obtuse or arcane.

Those aren't the worst offenders. I'm referring to curry, cadr, lambda, monad, etc. But map is confusing: it's also a data structure. "Wait, does map() create a new key-value dictionary?" Filter and collect are okay. Reduce is pretty arcane but tolerable, but the actual operation feels intuitively closer to "categorize" or "group." My point about math was cultural. Math seems to revel in having its own peculiar and o…

reduce (or fold) would be accumulate, certainly not categorize or group.

Re: Java 8: No more loops

#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() =>
        articles.where((x) => x.tags.contains("Java"));

    List getDistinctTags() =>
        articles.expand((x) => x.tags).toSet().toList();
Can even be shorter without the Optional typing, but it's more readable to be explicit to have them. Dart benefits from having Collection and Stream mixins so you always get a rich API on Dart's collections.

If anyone's interested to comparing FP collections in different languages, I've ported C# 101 LINQ examples in:

  - Swift    https://github.com/mythz/swift-linq-examples
  - Clojure  https://github.com/mythz/clojure-linq-examples
  - Dart     https://github.com/dartist/101LinqSamples

Re: Java 8: No more loops

#30
why not use:

  public final class Article{
    public final String title;
    public final String author;
    public final List tags;
    public Article(String title, String author, List tags) {
      this.title = title;
      this.author = author;
      this.tags = tags;
    }
  }
Getters don't seem very useful on an immutable object.
Post reply on HN