Programming Erlang: Functional Programming
I started reading the book Programming Erlang and while I read I blog along what I find most interesting/important. In the end, this will hopefully be some kind of erlang tutorial, for your pleasure and my reference
Here’s the first post and now comes the second:
Yesterday I started reading the next chapter called “Sequential Programming”. It actually is about functional programming: functions, anonymous functions, higher order functions, predicates, pattern matching for calling functions a.s.o. - I had to read most of it twice to actually understand it and haven’t even finished the chapter yet. Anyway, let’s start. By the way I started creating an Erlang Cheat Sheet with all the syntax on it. Being used to the very clear Ruby syntax, things started to get a bit confusing in this chapter.
functions
Note: You can not enter function definitions in the erlang shell erl. see the modules section below to learn how to run this code.
A function in erlang is a function as in any (?) language. It receives parameters and returns a value (well, there’s more, read on). The definition looks like this:
This defines the function area which takes a tuple containing the atom rectangle (to identify the type of shape) and its with and height. It of course returns the area of the rectangle by multiplying width and height.
parameter matching
We can now define the same function again with different parameters, e.g. like this:
As you might have guessed already, this now computes the area of a circle. The cool thing is, that when you now call area, erlang works out which of the function to call, depending on the given parameters. If you pass a tuple with the atom rectangle as its first element and two values, the first definition matches ({rectangle, Width, Height}). With circle and one value, the second one matches.
Note: the order of the function definitions id important, erlang starts with the first and goes down the list until it finds a match. But this is only important if you call a function where multiple definitions will match your parameters.
List recursions
one thing you can do with this pattern matching is processing lists recursively. for example, you could define a function that takes a list of numbers and returns the negated values. you do this by defining two functions: one takes a list with at least one element in it. this function does the computation with the head (first element) and then calls itself recursively with the tail (rest) of the list. the second definition expects an empty list and simply denotes the end of the recursion. take a look:
The first definition computes the negated value of the head. It then puts the result in a list (the angle brackets around the Head * -1) and concatenates the result of the computation of the tails - which is again a list of values.
Modules
Modules are as usual collections of functions. A module definition starts with -module(my_module).. after that you have to export all the functions you want to use from outside of the module using -export([my_function/1]). where the /1 denotes the arity of the function (the number of aruments).
If you want to run any of the functions above, you have to put them into a module and save it as a .erl file. You can then compile and use the module from the shell:
So that was the easy part of this chapter (chapter 3 in the book) but enough already for this post. Stay tuned for more.
Tags: erlang, programming, programming-erlang, tutorial
July 24th, 2007 at 9:29 am
I’m glad you’re enjoying the book - it’s fun
to see what you make of it.
You might like to change should change
negate([Head|Tail]) -> [Head * -1] ++ negate(Tail);
to
negate([Head|Tail]) -> [-Head | negate(Tail)];
Even better
negate(L) -> [-X || X
July 24th, 2007 at 9:32 am
Your software gobbled up my code seems
like I have to quote “less than”
This is a bug in your web interface.
Try this:
negate(L) -> [-X || <- L].
/Joe
July 24th, 2007 at 9:34 am
Indeed it was a bug.
If you type a naked “<” in the comment window it gets swallowed up. you have to write <
but there is no comment to warn you about this.
/Joe
July 24th, 2007 at 9:38 am
i just realize the author of the book is commenting on my little blog, wow
thanks for the help. i was planning to introduce list comprehensions in the next post. (have to go really slow to digest all this as it’s mostly new to me)
sorry for the buggy wordpress, i’ll see what i can do.
July 24th, 2007 at 10:23 am
Your area function for a circle actually computes the circumference.
July 24th, 2007 at 10:32 am
oops, sorry and thanks for the hint. just fixed it.
July 24th, 2007 at 7:34 pm
Since I’m lazy, I get around the limitation of not being able to enter function definitions in the shell by using the format
F = fun() … end.
This isn’t as always as easy as it looks however, when recursion is involved. For example, I write the classic permutation function in the shell by dividing it into two functions:
P = fun([],F)->[[]]; (L,F)->[[H|T] || H <- L, T <- F(L–[H], F)] end.
Perms = fun(L) -> P(L,P) end.
Now
Perms([1,2,3]).
evaluates correctly to
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
July 25th, 2007 at 9:25 am
cool thanks. that makes playing around with erlang much easier.
July 28th, 2007 at 6:25 pm
[...] again a list with the results. This way we could rewrite our list processing example from the previous post like [...]
November 26th, 2007 at 2:08 pm
Hallo hier der Nachschwaermer wollte nur mal hallo sagen und mich für die Infos bedanken. Bin zufällig ueber Google blog search auf Deinen aufmerksam geworden. Weißt du eigentlich dass dein Blog unter den Top 10 ist??
November 26th, 2007 at 8:03 pm
keine ursache. ja unter manchen keywords sind wir ziemlich weit oben bei google. und das ganz ohne seo
ich muss unbedingt mal das buch weiterlesen.