Thoughts on Programming Erlang: Software for a Concurrent World

I finally finished reading Joe Armstrong’s second revision of his book this week and having never programmed Erlang before it has been a tremendous help. There are some issues with information in the book, but for the most part it’s pretty rock solid.

What I was Expecting

  • The book does a great job of building on itself from one chapter to the next. Never is there a time when something completely out of the blue comes out at you.
  • Prepares you for R17, which has some really nice features in it!
  • Examples are easy to follow and the exercises re-enforce and help you remember each chapter.
  • Highlights pitfalls of introducing concurrency in the wrong places.

What I Wished For

  • More coverage of OTP in the book. There is not much mention of the OTP framework in the book. I plan to find another that goes more into this aspect of Erlang.
  • A bit more detail on the -behavior() tag. This may relate to the prior point of wanting more on OTP. It would be nice to know how to write your own behaviors and unfortunately this was not in the book.

Ruby Refactoring: Ugly Null Checking

When you can, always try to use the Null Object Pattern; however, there are times that may prove difficult. This doesn’t mean you need to abandon all readability though. Here is a block of code I ran into today that was improved with a little refactoring TLC.

Before

items.each do |item|
next unless item.widget
update_widget! item.widget
end

After

items.each do |item|
next if item.widget.nil?
update_widget! item.widget
end

Just because nil is conveniently falsey doesn’t mean it’s always best to treat it that way. Compare the before and after blocks above. Which has clearer intent on why next is called? I’m sure if you read it a bit the first makes sense, but the whole point is to avoid the necessity of reading code that much to figure out what it’s doing.

This is one of the cooler idioms I love about Ruby. nil? is baked into nil to be true and on Object, everything else, it’s false. Using this makes your code more readable, use it every chance you get instead of that ugly null boolean check!

The Snoopy Inspector

This week we had a very deep and hard to track down bug that was only happening on certain Mac architectures. The problem came down to setting shape object data on ActiveRecord models and then mysteriously having that field become nil.

After setting pry breakpoints in several dozen places we still weren’t any closer to solving the problem. The magic meta that ActiveRecord supplies was making it an impossible exercise of patience to step through what seemed to be several hundred stacks of a statement that was this simple on the outside:

shape = FactoryGirl.create :spatial_rectangle
rect = Shape.new
rect.data = shape

Empty Raise and Rescue

I was helping debug some open source ruby code today and saw a code block that looked like this:

def risky_method
# Logic Here ...
rescue
# Logging and record cleanup
raise
end

Christmas Tree Unlocked

Tonight Cass and I set up our Christmas tree tonight. It’s like opening a time portal every time we set it up. I remember all the Holidays we’ve had together and it’s just an awesome time. Cass says it’s this tree’s last year but part of me hopes that’s not true.

One Year Blogging

Boom! I’ve made it a whole year with my blog. Today is Thanksgiving and I am happy to have kept it going this long. May I find the time and energy to continue contributing to it!

Collecting URLs in Erlang

In chapter 16 of the book “Programming Erlang” Software for a Concurrent World” there is an example of reading through a web page and parsing out all of the anchor tags found in it. Here is the meat of the code that I found myself trying to understand for awhile and would now like to explain:

-export([gather_urls/2]).
-import(lists, [reverse/1, reverse/2, map/2]).
gather_urls("<a href" ++ T, L) ->
{Url, T1} = collect_url_body(T, reverse("<a href")),
gather_urls(T1, [Url|L]);
gather_urls([_|T], L) ->
gather_urls(T, L);
gather_urls([], L) ->
L.
collect_url_body("</a>" ++ T, L) -> {reverse(L, "</a>"), T};
collect_url_body([H|T], L) -> collect_url_body(T, [H|L]);
collect_url_body([], _) -> {[],[]}.

Burgess and Cummings Falls Adventure

Went out to the Burgess and Cummings Falls state parks this weekend. What an amazing set of parks that are fairly close together. Very excited to go back in the summer for some in-water action!

Cosmos Javascript

If you’ve been following my blog you’ll notice a spacy, cosmos background with little stars floating about. I saw this effect on another website and had to replicate it for myself! There isn’t too much going on, but I did enjoy building it. For anyone curious about the source; here is a repo created to help tool it out: Cosmos.

Kerl - Installing Erlang Easier

Installing Erlang has been somewhat of a pain. When trying to make sure I have the version I want, relying on the ppa has not been that great. Thankfully someone has shared with me an amazing tool, kerl.