If we can do it, so can everyone else ;)
If we can do it, so can everyone else ;)
"Prove it" is our first line of defense. By always writing total functions, we can be confident that our services and jobs don't fail in uncontrolled ways. "Proving of theorems" is what you end up doing as you write total functions. NonEmptyList, ADTs, Options, Coproducts, These, singleton types, sized collections. All these things can provide powerful proof that is used to write total functions. The proof that various types provide makes it easier to write total functions as we can use Scala's powerful type system to greatly restrict which programs we even have to think about. And (thinking in reverse), forcing yourself to write pure, total programs ends up forcing you to prove various things about your program in order to achieve those properties.
So all in all, we perform the "proving of theorems" all the time. It just doesn't look or feel like it. But a large portion of CR discussion is about the types used in a program, which is in effect a discussion about which theorems we think we should prove before we push the code to production.
For example, the ruby library I use to connect to webservices is very OO, and requires you to derive from its base class to build each webservice client.
This is of course very natural in Ruby, but I do see lots of OO in Scala libraries too (e.g. Spray).
Agreed. This makes it a pretty easy sell to get everyone to commit to using immutability and purity and all those nice things in the business logic layer.
> Where things start to get trickier is the boilerplate and boundaries, e.g. I'm writing a Rails app at the moment where the business logic is in pure functions, but the boundaries with other systems like ActiveRecord and external webservices tends to end up being more object-oriented.
We're in the same boat, except in an in-house Java-based service framework. The "shell" of the program reads from the DB/makes service calls to gather input, passes this input to the pure business logic layer, and then based on the output throws exceptions, writes to the DB, makes other service calls, etc. This conscious division between effects and logic alone makes programs better.
In areas where we need concurrency or have more complicated effects we wish to unit test, we have started to use scalaz.concurrent.Task and scalaz.Free.
I'm the only one who came in knowing pure FP at all and I didn't learn it via classes.
Students there have more FP experience than most.