Live data from Hacker News

Java 8: No more loops

deadcoderising.com

41–50 of 99 posts

Re: Java 8: No more loops

#41

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.

Yeah, I read this and immediately thought it felt like a knockoff of LINQ.

Re: Java 8: No more loops

#42

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)

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

Are there professional programmers with only FP and no imperative language experience?

Re: Java 8: No more loops

#43
post #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.

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…

That's also one of the differences between Scala and Java. In Scala you have referential transparency, so you easily can switch between fields/properties and methods without changing the calling code.

Re: Java 8: No more loops

#44
post #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.

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…

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 no code is being executed - but you never see x.foo because everything has getters and setters. So all it does in practice is make things (even) more verbose.

Re: Java 8: No more loops

#45

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.

The main reason they build these on Stream rather than Iterable is b/c they wanted to include the `parallel()` method, which works via "spliterators" rather than plain old iterators.

In other words, in order to support a gimmick you can actually use in production in a maybe a handful of use cases, they complicated the api for the use cases you hit 99% of the time. Awesome.

Re: Java 8: No more loops

#46

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

It's doesn't take long when working with functional code to never want to go back to loops.

I had the opposite reaction after having to work with a number of complicated reductions; in a lot of cases, a short for-loop and accumulator variable would have made the code much easier to read...

Re: Java 8: No more loops

#47
post #18
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.

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.

Re: Java 8: No more loops

#48
post #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.

But you can still modify elements of a final List (thereby modifying the Article object).

Properly implemented getTags should create a copy of tags so that fiddling with the returned value doesn't affect the object.

Re: Java 8: No more loops

#49
post #45

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.

The main reason they build these on Stream rather than Iterable is b/c they wanted to include the `parallel()` method, which works via "spliterators" rather than plain old iterators. In other words, in order to support a gimmick you can actually use in production in a maybe a handful of use cases, they complicated the api for the use cases you hit 99% of the time. Awesome.

actually this is not true, what you're not noticing is that the parallel() use is akin to Spark, basically these streams are just map functions and if you can put the closure onto multiple cores/machines you get much better performance without any additional programmer intelligence.

If you think that api is complicated then I don't think programming is for you, this is a very ordinary and usual construct in programming.

Re: Java 8: No more loops

#50
post #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.

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…

Besides, getters and setters are debuggable. They allow you for setting breakpoints, adding Log calls etc... Not so in case of fields.

It would be nice to have some syntax sugar for defining properties more tersely though, like in C#.

Post reply on HN