Friday, May 23, 2014

What Is A Monad?

Being a hobbyist Haskell programmer, I have heard the term "monad" a lot. In my experience playing with Haskell I have used monads plenty of times, however, it was not until recently that I have come to a digestible understanding of what they really are.

Think Method Chaining

Some of the prominent phrases which I hear being used to describe monads are "they're ways to fake state" and "they are really just a form of method chaining." Although, in my (perhaps nieve) understanding of monads, both of these statements are true, the latter has been far more useful in helping me arrive at a useful understanding of "the m word." So I encourage anyone who may be struggling with the definition of a monad to do the same: think method chaining.

Method Chaining You Say?

Yes method chaining. In the object oriented world this may mean something like this:

someObject.someMethod(1)
          .otherMethod("Pizza")
          .finalMethod()
So, in OOP, the objects returned by each of these methods would encapsulate state. Now, in Haskell, there is not really a concept of state, things are what they are. The sequential mutilation of objects is not something Haskell supports naturally, so it uses the monad as a slick way to sort of "fake state."

What It Looks Like

Disclaimer: this is my current understand of Haskellian monads, and not the similar but slightly different, mathematically definition of monads

To build a monad, two main functions are necessary as well as a monadic type. First I'll discuss a monadic type.

Monadic Type

A monad's type can be whatever it needs to be. Perhaps one of the most famous ones in the Haskell world it the Maybe monad, which is defined simply as:

data Maybe a = Nothing | Just a
Maybe is one of the most beautiful aspects of Haskell. It is very similar to null or nil in other languages, but what makes it different is the fact that (as I understand it) in Haskell's pure, functional model, Maybe cannot go unhandled or pop up in unexpected places. In my mind, it is a kind of a neat and precise example of a monadic type.

The return Function

Another thing a monad needs is a return function whose signature looks like:

return :: a -> m a
return is simply a function whose purpose is to construct the monadic type. Pretty simple, eh? So for Maybe, this might be as simple as:
return n = Just n

The Bind Function

The other function needed by a monad, the function that truly brings out the magic, is the bind function which is usually denoted as (>>=) in the Haskell world. In the OOP example above, the bind function is kind of like the periods in between the different calls, but oh so much more magical. Bind's signature looks like:

(>>=) :: m a -> (a -> m b) -> m b
So, let's break this down.

The first thing that bind takes is a monadic type. So, this could be something as simple as Just 5 or whatever monadic type you are operating on. The second parameter is a function that takes the type boxed by the first parameter (the monadic type) and returns a monadic type boxing b (which could be the same type as a but by no means must be). In the end, bind returns another monadic type, as returned by the middle parameter.

All in all, this seems like a lot to swallow, and, uh, what does this have to do with method chaining or our return function?

Remember, bind is really one of those strange infix operators, so if I may make some simplifications, it kind of looks like:

a thing >>= function that returns another thing
In this simplification, "thing" is substituted for "monadic type" to make bind easier to swallow. The point is, all this whole mess does is return another monadic type! So, there's nothing keeping me from implementing another bind operator (or reusing the same one, if applicable) like such:
a thing >>= function that returns another thing >>= function that returns yet another thing ...
See what I mean about this being like the "period between" in that above OOP example? All bind really does is take some value (wrapped in a monad) and apply some function to it, and re-wrap the output!

return is pretty cool because a lot of the time it comes at the end of all the binding (wow, a return at the end? Sounds like some other paradigms out there). return is really the end game, the termination of the "chaining."

Parting Words

In conclusion, I hope I have shed some light on what can be a very difficult topic to understand. If you would like to learn more, the Haskell community has a great article on monads also there are some really awesome answers to the question of "what is a monad" on SO.

Wednesday, May 7, 2014

Why I Dig RSpec

I've been using RSpec a fair amount lately, so I thought I'd talk about some of its features I really dig.

The rspec -f d command

If contexts and describes are favored over loaded setup and it blocks that do too much, you can get some really nice, verbose output from this command.

For example, suppose I have some specs describing a #wear_hat? method of a SimpleDecisions class. My rspec -f d output might look something like the following:

SimpleDecisions
  #wear_hat?
    when I am a vampire
      and it's sunny out
        returns true
      and it's night time
        returns false
    when I am at a home baseball game
      returns true
    when I am at an away baseball game
      and my hat is for my home team
        returns false

Pretty nice, huh? The specs almost match what we would expect the structure of the implementation to be!

Template specs

There's a lot of debate out there about whether test code should be DRY. Some say it shouldn't and that tests should flow and provide context. Others assert (no pun intended) that tests should be maintainable and, therefore, just as clean as (or cleaner than) production code. Template specs meet somewhere in the middle. They can replace many repeated tests at the (slight) expense of maintainability by looping through values and outcomes. For example, a template spec on an absolute value method might look like:

describe Math do

  describe '.abs' do
    [
      [42, 42],
      [0, 0],
      [-42, 42]
    ].each do |given_number, expected_number|

      context "given #{given_number}" do
       subject { described_class.abs(given_number) } 

       it { should be(expected_number) }
      end

    end
  end

end

In my mind, templates are nice when testing a pure function or when there are multiple, similar tests that can be aggregated.

Argument matchers

These are very cool. For example, say I want to test that an error is logged in a certain case, and I don't care about the specific error text, rather I just want the message to be some String. I could write something like this:

  # ...
  it 'logs an error' do
    ErrorLogger.should_receive(:write).with(kind_of(String))
    # cause error
  end
  # ...

This is a fairly trivial example, but these things are powerful. For a further example, presume ErrorLogger.write actually takes two parameters but I don't care about the second. The line would then become ErrorLogger.should_receive(:write).with(kind_of(String), anything).

Natural decoupling

By providing methods like subject and described_class and providing mechanisms to easily redefine the former, RSpec decouples the specs from things like the name of the class under test or the method being tested. For example, in my above absolute value example, if I changed the class from Math to MathUtils then, assuming everywhere below I referenced Math as described_class, I would only have to rename at the top of the file. One change in the production code would merit one change in the tests. Perfect!

Conclusion

Well, I hope I've expressed some of my favorite things about RSpec. If you would like to see any of my specs, they shouldn't be hard to find in my ruby repositories on github. If you have any comments on these points, or anything you really like about RSpec (or dislike for that matter) I'd love to hear your comments.