Skip to content

Instantly share code, notes, and snippets.

@manuelp
Last active June 7, 2023 06:48
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manuelp/69da2f154a6703b0ed9042a6abbd0d19 to your computer and use it in GitHub Desktop.
Save manuelp/69da2f154a6703b0ed9042a6abbd0d19 to your computer and use it in GitHub Desktop.
(Some) Functional Java Libraries: A quick comparison

Disclaiment: FP in Java is doable, even in Java 7- without lambda expressions (I use it basically every day), but there are limits. Sometimes the pragmatic choice is to NOT use it (for example for performance or readability reasons), but in most cases I find it applicable and beneficial. My kingdom for, at least: higher-kinded types, type inference and value types!

TotallyLazy

Warning: I have experience with the 1.x line of development and I'm going to talk about it.

  • Sites:
  • License: Apache 2
  • What it is: a functional toolkit inspired by Clojure, Scala, Haskell and F#. The 1.x version targets Java 7- (it's maintained as far as I can see), the 2.x one targets Java 8.
  • What provides:
    • Persistent data structures, tuples, streams, lazy data structures, etc.
    • Useful types like: Option, Either, Validation, Eq, etc.
    • Lenses (sort-of, just a tiny tiny subset of a full lenses implementation).
    • Functions, functor, applicative, monad.
    • Utilities: files, randomness, URLs, XML, JSON (encode/decode), reflection, property files, date and time.
    • Parsers.
    • Trampoline (to obviate the lack of tail-call elimination).
  • Documentation: sadly, none. Not even a JavaDoc API reference. The author doesn't "believe" in documentation, and the only option is to dig into the code (which is also largely without comments). This is the main reason why we've switched to another library.

This library provides a lot of stuff and to be honest is nice to use. However, it has a number of disadvantages:

  • There is essentially NO documentation. This makes it a hard sell to anyone new to FP.
  • The JSON encoding/decoding was buggy when I used it (it could have been fixed by now).
  • Makes the "pragmatic" choice to model functions that can throw exceptions. This IMO encourages a shallow error-handling strategy.
  • And then there are things that I find disturbing, like: aNull, callThrows and nullGuard.

TL;DR: it's a big collection of useful stuff, but undocumented and that doesn't encourage enough a pure and null-free style.

Functional Java

This is the library I currently use in several projects.

  • Sites:
  • License: BSD 3
  • What it is: A functional programming toolkit for Java. It's available for Java 8 and even for Java 7-. It's inspired by Haskell and has a strong emphasis on purity and type-safety. It properly implements some algebraic structures like semigroup, monoid and monads (some of them, unfortunately Java doesn't provide higher-kinded types).
  • What provides:
    • Persistent data structures: lists, sets, maps, tuples, type-safe heterogeneous lists, streams, queues, etc.
    • Option, Either, Validation.
    • Pure functions (F), functions that can throw exceptions (Try).
    • Monadic IO and effects. Plus other monads instances (like parser combinators, reader, writer and state, etc).
      • Primitives for monadic DB access.
    • Proper optics (lenses, prisms, traversals, etc).
    • A generative testing framework.
    • Concurrent and parallel primitives: Promise, ParModule and a simple actors framework.
  • Documentation: it has a quick start guide, examples, some tutorials and a JavaDoc API reference with enough comments.

IMO it's a much better option than TotallyLazy:

  • It's documented. It's easier to "sell".
  • It empasizes purity and a good functional style (tries to ensure, as much as possible, referential transparency).

But there are also downsides:

  • Java as it is right now has some serious limits when it comes down to FP (higher-kinded types, no type inference, no value types, no algebraic data types, no pattern matching, nullability, runtime exceptions, etc). Java 8 is an improvement, and Java 9-10 are promising, but it's still painful sometimes.
  • The DB monadic IO is incomplete.
  • The documentation could be better (there API reference is good, but it's still weak in the guides/tutorials department).

TL;DR: Better than TotallyLazy. Moar functional, moar documented, moar reasonable. Use it (rather than TotallyLazy).

JavaSlang?

I know there are a lot of other options out there. JavaSlang is one of the most popular right now: it has fantastic documentation and it's gaining traction. However:

  • I have not used it.
  • Replicates the Scala collection API, which I find amusing since a total redesign of Scala's collections API is on the roadmap. It's not a mystery that there are several problems with the current design/implementation.
  • The purity and functional aspects of the library seems to be somewhat second-class. Describing the javaslang-pure module (now merged in the main codebase) as "Bikeshed for aficionados of purely functional programming, highly experimental." doesn't inspire a lot of trust in the general direction of the project. But I'd love to be proved wrong.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment