• Post Reply Bookmark Topic Watch Topic
  • New Topic

Functional Porgramming in Java: lazyness

 
Ivano Pagano
Ranch Hand
Posts: 54
Java Mac OS X Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello.
I see from the book content that there's a chapter on lazyness.

Since I consider it as one of the traditional fp features that Java doesn't natively support, how do you approach it in the book?
Is there any workaround to the language (like using closures) and how much do the solution impact the runtime performance?

Thank you

Ivano Pagano
 
Campbell Ritchie
Marshal
Posts: 52549
119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Lazy execution is a standard feature of a Stream. Not only does the Stream downstream only execute as many instances are necessary to produce the requisite result, but it stops all the upstream Streams too, because they use lazy execution too.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 96
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since I consider it as one of the traditional functional programming features that Java doesn't natively support, how do you approach it in the book?
Is there any workaround to the language (like using closures) and how much do the solution impact the runtime performance?


There is a full chapter in the book about streams. It is not about Java 8 streams, but about implementing streams, which are basically lazy lists. The reason not to use Java 8 streams is that these have been implemented mostly to serve as a basis to automatic parallel processing. It seems that, for this reason, some very important methods of streams have not been implemented. In any case, it is very useful to learn how to implement streams functionally. It is important to note that a functional structure like streams does not indeed need to be implemented functionally. Streams must have a functional interface. What happens inside may be imperative, this does not make streams non functional. Java 8 streams are not implemented functionally, but this is not the problem. They are not functional because they are mutable. Once a stream has been used (by a terminal operation), its state has changed and it can't be used any longer.

But this is not the main reason not to use them (in the book, I mean!) The main reason is that laziness is used everywhere, so it is important to learn how to work with it. By the way, laziness has been used by Java from the start. What could we do without laziness? Can you imagine programming in a language in which both branches of an if...else structure would always be evaluated? Or a language in which you could not escape from a loop until all iterations have been executed? No very useful. Java also has the lazy boolean operators (&& and ||). In Java 8, Optional has lazy methods such as orElseGet() and orElseThrow(). If orElseThrow was not lazy, the exception would always be thrown even when the Optional holds a value!

In Java 8, lazy values are represented by the Supplier interface. In the book, laziness is used in many places. Too many to list them all!
 
Ivano Pagano
Ranch Hand
Posts: 54
Java Mac OS X Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Pierre-Yves Saumont wrote:
But this is not the main reason not to use them (in the book, I mean!) The main reason is that laziness is used everywhere, so it is important to learn how to work with it. By the way, laziness has been used by Java from the start. What could we do without laziness? Can you imagine programming in a language in which both branches of an if...else structure would always be evaluated? Or a language in which you could not escape from a loop until all iterations have been executed? No very useful. Java also has the lazy boolean operators (&& and ||). In Java 8, Optional has lazy methods such as orElseGet() and orElseThrow(). If orElseThrow was not lazy, the exception would always be thrown even when the Optional holds a value!

I was thinking more of library support over built-in language features.

Pierre-Yves Saumont wrote:In Java 8, lazy values are represented by the Supplier interface. In the book, laziness is used in many places. Too many to list them all!


Didn't know about Supplier, I'm going to check that for sure. Would you consider it the equivalent of a OO closure intended to make evaluation lazy?
In your experience, is there a significant cost at runtime (caused by instances generated in memory and GCed?). I heard many complain about the performance cost in scala for automatic generation of many "functional objects" used by collections and such.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 96
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In fact, lambdas are often inlined by the compiler, in which case no additional object is created. This is an important difference between lambdas (as well method references) and anonymous classes. It is also the reason why this in an anonymous class refers to the anonymous class, whether in a lambda, it refers to the enclosing class.

Of course, this is not true if you explicitly declare a named function. But on the other hand, declaring a named function makes it reusable. To benefit from reusability and inlining, use method references.



It is however unfortunate that we can't write:



 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!