Funs
Table of Contents

So far, we've been playing with basic stuff in Erlang, but it's been important stuff. What have we accomplished thus far? Well, we've learned our way around the Erlang shell a bit. We've played with the way Erlang does arbitrary precision math, and we've seen that Erlang has two uses for the = sign. The first use is to bind a value to a variable (which is uppercase of course). The second use of = is to pattern match values.

In this lesson, we're going to start putting what we've learned to use by combining them into more powerful features. This is actually what makes Erlang programming so much fun: ideas can be combined together to produce really powerful constructs.

Let's get started. Fire up your interpreter and follow along:

Eshell V5.7.2  (abort with ^G)
1> fun() -> 100 end.
#Fun<erl_eval.20.67289768>
2> Boil = fun() -> 100 end.
#Fun<erl_eval.20.67289768>
3> Boil.
#Fun<erl_eval.20.67289768>
4> Boil().
100
5> To_F = fun(C) -> C * (9/5) + 32 end.
#Fun<erl_eval.6.13229925>
6> To_F().
** exception error: interpreted function with arity 1 called with no
  arguments
7> To_F(100).
212.0
8> To_F(50 + 50).
212.0
9> Hot = 100.
100
10> To_F(Hot).
212.0
11> To_F(Boil).
** exception error: bad argument in an arithmetic expression
     in operator */2 
        called as #Fun * 1.8
12> To_F(Boil()).
212.0
13> b().
Boil =
     fun() ->
            100
     end
To_F = 
     fun(C) ->
             C * (9 / 5) + 32
     end
Hot = 100
ok
14> % This is a comment
14> % It makes everything after the '%' invisible
14> % Comments are used to insert notes for yourself
14> % Just Watch:
14> % b().
14> % q().
14> % Nothing... Also, notice that same line number keeps repeating
14> % Erlang ignores everything on the line behind a % sign
14> % Alright, enough comments for now
14> q().
ok
15> clay@Hal $

Pop Quiz: Look back over the lines we just typed and tell me what funs do.

Answer: they create functions. Thus the name... And what does that mean? Well, it's easier to see than explain. So let's just watch and learn.

In line 1, we create an anonymous function that will spit back 100 every time it's called. Of course, the problem is that there's no way to call an anonymous function like this because...it's anonymous. It doesn't have a name that we can use to actually call it. Let's fix that.

In line 2, we use the same fun from line 1, only this time we bind it to Boil which is short for the Celsius boiling point. Notice how the value Erlang returns is this weirdo thing about #Fun something or other. That's erlang's way of keeping track of these things. We'll use the name Boil instead.

In line 3, we try to get the value of 'Boil' just like any other variable, but Erlang acts funny. Instead of returning 100, it gives us that weird ID stuff again. What went wrong? Oh yeah, the first rule of functions! Which is:

FUNCTIONS ONLY WORK WITH PARENTHESES

In line 4, we call Boil() using parens on the end and erlang happily returns the number 100. Those terms (call and return) are programming terms-of-art by the way. You should make a mental note to use them. So, "call" means use a function and "return" means what the functions spits back.

In line 5, we define another anonymous function that converts Celsius to Fahrenheit. Ok. This looks tricky, but don't run away just yet; it's actually not that bad. Trust me.

We are binding an anonymous function to a new variable named To_F. Notice that our function includes something called C that shows up first in the parens of the fun part like so: fun(C) and then later in the equation part following the arrow. That C is called an argument. It lets us pass values into our function from the outside world. That's a good thing. It means this one little function can recieve any Celcius temperature there is and convert it to Fahrenheit. Pretty useful stuff!

Which brings us to the second rule of functions:

YOU MUST USE AS MANY ARGUMENTS AS THE FUNCTION DEFINITION SPECIFIES

In line 6, we take To_F out for a spin and promptly forget the second rule of functions: we didn't pass To_F a value and Erlang told us to take a hike, though it was nice enough to say why. "arity 1> means To_F requires 1 argument and we didn't give it one. Properly chastised, we try again.

In line 7, we follow the second rule of functions this time and pass 100 to 'To_F' like so To_F(100). and Erlang rewards us with 212.0. I'm beaming like a new dad. How about you?

Feeling our oats, we pass an equation to 'To_F' in line 8 with a stacatto To_F(50 + 50). and are once again astounded by our genius. Apparently, Erlang will process equations before sending the result on to the function as an argument. Interesting...

In line 9, we bind the value 100 to the variable Hot and then in line 10, pass 'Hot' into 'To_F' like so: To_F(Hot). and once again get 212.0 as our answer. More! We want more!

Drunk with success, we pass 'Boil' into 'To_F' on line 11 and watch in shattered silence as Erlang blows up in our faces. Why? Well, remember, 'Boil' isn't bound to 100. 'Boil' is bound to a function that returns 100. What was the first rule of functions again? Oh yeah, functions always get called with parentheses. So, let's treat 'Boil' like the function it always dreamed of becoming.

On line 12, we do this: To_F(Boil()). and it works like a charm even if it looks a little messy there at the end with that double )) stuff. What is this? Lisp?

Whatever. It works. That's the point. It also illustrates that interesting possibility I mentioned regarding line 8: the ability to stack things inside functions. That will turn out to be really cool!

On line 13, we ask what variables exist out there and get back an interesting list of bindings. Take a moment to review these.

On line 14. I demonstrate with obnoxious fervor how to write comments. Comments are little notes programmers stick into source code to explain something imporant: like what the code is doing. As this example shows, Erlang ignores everything in a comment. Comments are code for people so that months later, when you go back to look at a particular piece of code and have forgotten why you did something, rather than figuring out the code all over again, you can just read the reminder and save yourself a lot of time and frustration.

And then we call it day.

Alright. We've now covered enough to start doing some fun stuff. In the mean time, play around with funs, variables, and the math functions we've looked at. If you need a problem to solve, try creating a fun that calculates how many inches are in a light year. Silly though that sounds, most languages won't let you do it. In Erlang, it's easy. And math isn't even Erlang's strong suit.

Think about that.

Next Stop: First Summary