Erlang Notes – Records

Here is the eighth of some notes about erlang.
Obviously this is a very cursory glance at things. It’s really just notes to help me remember things. If you’re looking for something in more detail you can take a look at the erlang reference manual.

Records

Records are a way of providing a names for elements of tuples.

Record declarations are created in .hrl files with a syntax like:


-record(events, {day=monday,name=hangover}).

This gives us the ability to create a new event record with attributes of day and name. Like this:


X1 = #event{day=monday,name=hangover}).

Remember, its really just a tuple, but because we make it a record, it gets to have names for its variables. We can pattern match to get the variables out of the record. To get the values out of X1 above for example:


#event{day=D,name=N} = X1.
D.
monday

Erlang Notes – Gaurds and gaurd sequences

Here is the seventh of some notes about erlang.
Obviously this is a very cursory glance at things. It’s really just notes to help me remember things. If you’re looking for something in more detail you can take a look at the erlang reference manual.

Guards

As far as I understand, guards provide an enhancement to pattern matching, allowing us to enhance our pattern matching abilities by testing the values of variables. I’m not quite sure exactly where guards can be used: No limitations on where are mentioned yet, so I’m going to assume that you can use them anywhere you are using pattern matching, although it seems a bit odd to use them on the RHS of an expression.

The simplest example of a guard is probably something like:


sqrt(X) when X < 0 -> exit(dumbValue).

In this case when we call sqrt with a value less than 0 we’ll exit. Pretty straight forward.

Guard sequences

We can also combine guard clauses to give us more complex checks:


sqrt(X) when X < 0, X < 20 -> exit(notInValue).

Guard sequences are simply separate guard clauses conjoined in some way. They typical way they are conjoined is simply by a comma as above, in which case the comma represents an ‘and’ statement. They can also be combined by short-circuit boolean operators andalso or orelse, or by the normal boolean operators or or and.

These cases function much as you would expect, with short-circuit boolean expressions functioning as in other languages.

Erlang Notes – List comprehensions

Here is the sixth of some notes about erlang.
Obviously this is a very cursory glance at things. It’s really just notes to help me remember things. If you’re looking for something in more detail you can take a look at the erlang reference manual.

List comprehensions

I first encountered List Comprehensions in Python, and they were one of the things I loved, and missed as I started working in Ruby more. In principle, they are a simple way to define a mapping from one list to another. Here’s the notation in Erlang:

[2*X || X <- L].

This concise piece of code says something like: take each of the elements from the list L, and map them as element X into a new list defined by the function 2 times X.

Of course, the function you apply to the elements of the list could be a good deal more complex, and probably would be in real life.

There are some quite interesting isolated examples of list comprehension in Joe Armstrong’s book, including a terse quicksort implementation, but I don’t think there’s much more to say about them here, out of the context of a real application

Have you watched Giles Bowkett yet?

Have you seen Giles Bowkett yet?

This is hands down the best talk I have ever seen at a conference.

I don’t know if the feeling comes across on the video, but I have never seen the kind of reaction to a talk that Giles got to this talk at RubyFringe. The room was totally electric and he had a minute long standing ovation at the end of the talk. The hair was standing up on the back of my neck.

People left the room for lunch afterwards with stunned looks on their faces. Even Giles seemed to be amazed by the response he got, judging by the look on his face.

Absolutely recommended.

Erlang Notes – Higher order functions

Here is the fifth of some notes about erlang.
Obviously this is a very cursory glance at things. It’s really just notes to help me remember things. If you’re looking for something in more detail you can take a look at the erlang reference manual.

Higher order functions

A higher order function is any function which does one or more of the following:

  • Takes one or more functions as its input
  • Returns a function as its output

Functions that take functions as an argument

We already saw some examples of this in the last section. Remember this code:

1> List = [2,4,6,8,10].
[2,4,6,8,10]
2> Triple = fun(X) -> 3 * X end.
#Fun
3> lists:map(Triple, List).
[6,12,18,24,30]

In this code, lists:map takes a function as an argument and applies the function to each member of the passed in list. A map function is a very common example of this pattern. I would expect that its fairly fundamental to any language that allows functions to be passed around as first class entities.

Functions that return functions

Functions that return functions are somewhat less common, but they can be useful to help us write generic code that can be parameterized at runtime to do different things. Here’s some imaginary, untested, code to help get the point across:

1> % Imagine some readings of various types exist...
1>MakeReadingFinder = fun(Type) -> (fun(DateRange) -> readings:find(Type, Date) end end.
#Fun
2>BeforeBreakfastReadingFinder = MakeReadingFinder(before_breakfast).
#Fun
3>BeforeBreakfastReadingFinder(now()).
% Readings are magically returned!

Although the example isn’t perfectly clear (there’s a better one on pg. 45 of Programming Erlang) you can see that what we’re doing is using the ability to return a function as a way to fill in some of the returned functions parameters before we use it.

This allows us to parameterize the function, and is probably going to be ideal for implementing Factory patterns etc. very simply.