Epic failure \/ success? Refactoring to *real* FP

specs2 has been around for 4 years now and while it tried to take the “functional route” (with immutability at least), it is actually largely using uncontrolled effects.

This talk will present a diagnosis of everything that is not “functional” in specs2, and will describe implemented or proposed solutions to remediate to this. Here’s a list of some problems:

  • system properties are read directly
  • the file system is accessed to get the state of previous runs and written to after execution
  • some configuration is global (execution context for threads)
  • text is freely emitted to the console via printlns
  • an attempt at processing lazily the execution miserably failed (via Reducers)
  • the code base is not easily extensible to create new reporters

The solutions (still being implemented/experimented) include:

  • using a ReaderT / ErrorT / WriterT / IO stack to control effects. This actually opens very interesting possibilities in terms of flexibility for writing your specification! Question: how tedious is that to use in practice?
  • using scalaz-stream to process results as they happen, even when running concurrently. This should remove some poorly performing code and simplify the code base. Question: does it work with specs2 execution model where it is possible to run only some sections of the specification concurrently, where a failed execution can stop the rest of the processing,…?
  • using functions extensively instead of traits to compose functionality (who knew?). Traits will only be used to compose implicits for DSLs. Question: why not take the Cake Pattern route?

In conclusion we will talk about strategies for effectively migrating a non-functional code base to a functional one. What was learnt during this experiment?


Target Audience




schedule Submitted 1 year ago