Lazy primes with Java 8 (was Re: Java 8 Streams and Eratosthenes)
Am 05.06.2013 22:43, schrieb Arved Sandstrom:
On 06/05/2013 04:44 AM, Sebastian wrote:
[snip]
Me I wouldn't re-invent the wheel in this case. Implementing this type
of laziness is not that straightforward.
And why not use interop between JVM languages? This way you leverage the
strengths. I usually have Java as the main language, but for some
functionality in some apps I use Scala. Maintainability goes up, for
starters, as does reliability and speed of development.
It's all ultimately JVM bytecode.
AHS
It's not everyone has a management who sees it this way. In our large
project (we're talking several hundred developers and a really
complicated build process), I don't see anyone advocating more
complexity by adding another compiler and language.
Anyway, it's turned out not to be too complicated in straight Java.
One can simply extend a straightforward implementation of the usual
cons-list with the following features, giving one a
FilterableConsList<T>:
a) accept a Function<T> to generate the elements in the tail
in sequence
b) accept a Supplier<FilterableConsList<T>> to supply a tail
c) accept a Predicate<T> to filter out non-matching elements
from the tail
and make the implementation class LazyConsList<T> lazy for the tail
(but eager for the head).
It's also easy to implement AbstractCollection by providing an iterator
and make the thing streamable by providing a spliterator of unknown
size.
With that, the driver for generating the first 100 primes becomes:
LazyConsList<Integer> s = sieve(LazyConsList.newList(2, x -> x + 1));
s.stream().limit(100).forEach(x->System.out.print(x + " "));
where the interesting sieve() method is defined like this:
private LazyConsList<Integer> sieve(FilterableConsList<Integer> s) {
Integer p = s.head();
return cons(p, () -> sieve(s.tail().filter(x -> x % p != 0)));
}
Now I think that looks pretty neat (and almost exactly like the
corresponding Scala code.)
-- Sebastian