Either you’re with us or against us

So I was happily going on with my Scala journey avoid exceptions everywhere.  Then I ran into this use case where I sorta needed them.  But I really liked not having try/catch all over the place mucking up stuff.  So here’s this use case:

I’m in the middle tier, people call me via Rest, then I call sql, sprocs and more sprocs, Rest, your mom’s old couch, whatever and make that rationale and pass it back up.  The thing is that Rest service I’m calling might poop out on me, and I’d like to just pass up the json it sends me to the guy above me.  So I have this situation where I need to return two things.

I know exceptions can work here, I can return my object in the good case, or an exception in the bad case, but I really hate checked exceptions, not to get into a whole theological discussion about it, but I’m definitely in the camp of exceptions are best for exceptional stuff.  That whole FinderException crap EJB started, pisses me off.  Sun really went ape shit with that stuff.  I digress..

So how can I return two different things.  Well I could create some wrapper object thingy.  Yeah that would work, but its so icky, and then, I’m going to have to down cast stuff, or have a bunch of icky wrappers.  I don’t think that will work.  Then I discovered Either.

A common use of Either is as an alternative to Option for dealing with possible missing values. In this usage, scala.None is replaced with a Left which can contain useful information.Right takes the place of Some. Convention dictates that Left is used for failure and Right is used for success.

This is the medicine I was looking for.  I can return this, or I can return that.  OMG, genius!!!  What is even better, is that the convention is that the good stuff is on the right, and the bad stuff on the left.  Now Scala is even jelling with my political sensibilities.  Wow, mind blow.

So I can write stuff like this which is pretty fun:

 

So back to how I use this.  When I call into my store like this:

I send back up an EIther.  Which has a list in this case and then the raw DataStoreResponse on the left.  So if something bad happens, you get the raw DataStoreResponse, else the object(s) you were looking for. So in my case where I’m a service sending json back up in the good or bad case, things end up like this:

That’s so much nicer that try/catch all over the place.  But the thing is, this is stable, resilient code, it handles failure well.  But it doesn’t hurt your eyes to look at, is very concise, and reads well.

Advertisements

Chain Gang

So as my Scala journey has progressed.  It has really stepped up since I’ve switched jobs and been able to focus on it for a few weeks without distraction.  I’ve found that I’ve crossed into the functional style.  If statements annoy me now, and anything mutable causes me concern.  I was doing really well, getting the hang of things and then I ran into an issue.

Here was my use case.  I’ve got a deep domain, its heavily customized per customer in many ways.  The way I’m dealing with this right now, is that the actual field names of wide domain objects have customized labels per client.  We are talking 100 columns or more that can be customized.  I knew I needed to get all meta data with it, and use reflection, no problem, been there before.  But what I wanted to do, was read data from the store, then apply the label just in time, I don’t want to do a bunch of “select * as name from”  …, but rather get data, and then transform it.  Partially, because that would perform badly, partially because I’m going to have to transform the same data again and again, I don’t want that logic all wrapped up in the data access layer, and frankly its not available there, well yet anyway.

So that’s my use case, here’s my technical problem.  I had this list I needed to iterate over using a normal map type flow.  As I was going over that list, I was modifying some json.  What I ended up having was a nice functional map activity that had to pass in some json, and then return some json, for the next guy to transform.  It meant I had to create a var, and I found myself being annoyed greatly by this, I really wanted a val not a var.

Here is the before:

So you can see what is wrong here, looking at transform().  I’m taking an object, modifying it, and then sending it back, mutating stuff as I go.  I really wanted to pass the output of one function as input to the next function.  I knew that is what I wanted, but I wasn’t sure how to do it, and I didn’t know the right words to google.  In my mind I thought it should wind up being some like f(f(f(value))), which felt really recursive, only I’m going thru this list as I do stuff, so not really.

Then I found this blog post: http://danielwestheide.com/blog/2013/01/23/the-neophytes-guide-to-scala-part-10-staying-dry-with-higher-order-functions.html

In the middle he talks about “Composing a transformation pipeline”.  That is exactly what I needed, I wanted to pass the output from one function as the input to the next function.

So here’s how it ended up after applying that idea:

Ok so don’t worry about all the reflection the key bits are how this:

Becomes this:

Instead of taking in the JsValue object and then returning it back for the next guy to mutate, I return a function which accepts a JsValue and returns one.  So when this map activity finishes I end up with a Seq of functions.  The built in Scala Function.chain() function takes a Seqs of functions and applies the output of one to the input to the next.  From the Scala docs that business looks like this.

def chain[a](fs: Seq[(a) ⇒ a]): (a) ⇒ a

Given a sequence of functions f1, …, fn, return the function f1 andThen ... andThen fn.

So read about partial functions and composition.  I’m finding that learning the functional vernacular really helps you google stuff to find what you are looking for.  As a professional day to day programmer, what I need is to make these tools part of my everyday toolbox.  They aren’t just esoteric academic things, they are tools I can use to solve real problems, which is why I’m blogging about this, so others might see how I used this capability to solve a problem.