Как я узнал о преобразователях в Clojure, мне внезапно показалось, что они напомнили мне: Java 8 потоков!
Clojure:
(def xf
(comp
(filter odd?)
(map inc)
(take 5)))
(println
(transduce xf + (range 100))) ; => 30
(println
(into [] xf (range 100))) ; => [2 4 6 8 10]
Java:
// Purposely using Function and boxed primitive streams (instead of
// UnaryOperator<LongStream>) in order to keep it general.
Function<Stream<Long>, Stream<Long>> xf =
s -> s.filter(n -> n % 2L == 1L)
.map(n -> n + 1L)
.limit(5L);
System.out.println(
xf.apply(LongStream.range(0L, 100L).boxed())
.reduce(0L, Math::addExact)); // => 30
System.out.println(
xf.apply(LongStream.range(0L, 100L).boxed())
.collect(Collectors.toList())); // => [2, 4, 6, 8, 10]
Помимо различий в статическом/динамическом типировании, они кажутся мне очень похожими по назначению и использованию.
Является ли аналогия с преобразованиями потоков Java разумным образом думать о преобразователях? Если нет, то как это порочит, или как эти два отличаются по понятию (не говоря уже о реализации)?