Tuesday, December 31, 2013

Joe Armstrong's Favorite Erlang Program... in LFE

It kind of shocked me to discover recently that a new post hasn't been pushed out on this blog since April. Looking at the drafts I've got backlogged -- 30 and counting -- I also realized that none of these were going to get finished in a single day. Of those 30, probably 6 will ever see the light of day, and all of those are drafts in various states of completion for the Lambda Calculus series.

There's a great Tiny Scheme example I want to write about, some cool Clojure stuff I've played with, and bunch of functional programming work I'd like to share, etc., etc., but again, none of these are anything I can complete in a few minutes (allowing me to do the other things that I'd like to do today!).

I'd given up, when I remembered that there was something short, sweet, and a bit of ol' fun that I wanted to share! Mr. Erlang himself recently blogged about it, and I wanted to convert it to LFE: Joe Armstrong's Favorite Erlang Program.

This little puppy is quite delightful -- and Joe shares a great little story about how he deployed it on Planet Lab in his "aside" section of that post :-)

After you read his post, come back and take a look at this code:
(defmodule joes-fav
(export all))
(defun universal-server ()
(receive
((tuple 'become server-function)
(funcall server-function))))
(defun factorial
((0) 1)
((number) (* number (factorial (- number 1)))))
(defun factorial-server ()
(receive
((tuple sender number)
(! sender (factorial number))
(factorial-server))))
(defun run-it ()
(let ((pid (spawn #'universal-server/0)))
(! pid (tuple 'become #'factorial-server/0))
(! pid (tuple (self) 50)))
(receive
(data data)))
view raw joes-fav.lfe hosted with ❤ by GitHub
That's how you do it in LFE! (Also, did you notice that Github now knows how to colorize *.lfe files? That happened here.)

Ain't it just the purdiest thing you ever saw?

This code has also been submitted for inclusion in the LFE examples (thus the "examples/" below). Let's do a quick sanity check:
> (slurp '"examples/joes-fav.lfe")
#(ok joes-fav)
> (factorial 10)
3628800
> (factorial 20)
2432902008176640000
> (factorial 50)
30414093201713378043612608166064768844377641568960512000000000000
And now, let's run the example!
> (run-it)
30414093201713378043612608166064768844377641568960512000000000000
view raw run-it.lfe hosted with ❤ by GitHub

Happy New Year, everyone :-D