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 comment14>% It makes everything after the '%' invisible14>% Comments are used to insert notes for yourself14>% Just Watch:14>% b().14>% q().14>% Nothing... Also, notice that same line number keeps repeating14>% Erlang ignores everything on the line behind a % sign14>% Alright, enough comments for now14>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
