Erlang Notes – Anonymous functions

Here is the fourth 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.

Anonymous functions

Anonymous functions in erlang are known as funs.

Funs work mostly like regular functions – they can take any number of arguments, the arguments can be of any type, and the function can have multiple clauses. The thing that makes anonymous functions useful is that they can be bound to a variable. For example:

1> Half = fun(X) -> X / 2 end.
#Fun
2> Half(3).
1.5

Or, with multiple clauses:

1> DistanceConvert = fun({miles, M}) -> {kilometers, 1.609344 * M};
1> ({kilometers, K}) -> {miles, 0.6213 * K}
1> end.
#Fun
2> DistanceConvert({miles, 10}).
{kilometers,16.09344}
3> DistanceConvert({kilometers, 15}).
{miles,9.3195}

Many other languages allow anonymous functions bound to variables. Think of Ruby or Python’s lambdas or, as an even closer analogy, of Javascript’s assignment of methods to variables.

Anonymous functions as arguments

Much like Javascript or Ruby, you can use these anonymous functions as arguments to other functions. This enables us to perform list wide operations using internal iterators, and to perform operations such as map and filter. For example:

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]

As you can imagine, this opens up a lot of power. As far as I can tell the syntax for passing in funs allows you to pass them in as any parameter, and to call them inside a function clause body just by using the () call syntax.

It would also be interesting to know if funs are full closures. That is, do they keep their bindings with them when they’re passed around? As far as I know, I think they lose it, so they’re not.

Erlang Notes – Functions

Here is the third 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.

Functions

Functions in erlang are consist of multiple clauses. Each clause is separated by a semicolon and the final clause is terminated by a dot-whitespace. For example:

utter(dog) -> "woof";
utter(cat) -> "meow";
utter(cow) -> "moo".

In the case above we have a function utter with three clauses. Each of the clauses has a head and a body.

The head

  • The head is a function name then a pattern
    in parens, such as:

    utter(cow)

  • The pattern in the head is pattern matched based on the parameters passed when the function is called. So to execute the clause with the head defined above we would write:

    utter(cow).

  • If there are multiple clauses with heads that match the call, then the first one that matches will be used.

The body

  • The body consists of a series of expressions.
  • An expression is anything that can be evaluated to produce a value
  • You can have a series of expressions, separated by commas to produce an expression sequence. The value of the expression sequence is the value of the last expression that was evaluated.

Putting it all together

So we have:

utter(dog) -> "woof";
utter(cat) -> "meow";
utter(cow) -> "moo".

Tweaking an example from the great Programming Erlang, we can do:

-module(perimiter).
-compile(export_all).

perimiter({square, Distance}) -> Distance * 4;
perimiter({rectangle, With, Height}) -> Width * Height * 2.


Where you can see that having multiple clauses for a function, combined with tuples allows us to implement a sort of polymorphism.

Another thing to note about functions is that functions with the same name and a different arity are completely different functions.

That is, area(Radius) is a totally different function from area(Length * Width) as far as the runtime system is concerned.

Joe Armstrong says that erlang programmers often use this feature to provide helper functions for a main function, but that makes me throw up in my mouth a little.

Erlang Notes – Variables and assignment

Here is the second 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.

Variables

  • Literals starting with an upper case character, such as Pizza are variables
  • Variables are single assignment only, meaning that once they are bound to a value, that value cannot be changed. That’s different from a lot of languages, obviously, where we can change the values of variables during the run of the program. For example:

    1> % Lets assign X to be 6
    1> X = 6.
    6
    2> X = 7.
    ** exception error: no match of right hand side value 7

    When trying to re-assign a new value to a variable, we get an error message. The error message complains about bad matching, which leads us into the next issue.

Assignment

Assignment is slightly different from traditional languages. It is done by pattern matching the RHS against the LHS of an expression, rather than the more traditional manner of simply plugging the value of the RHS into the LHS.

Numbers

Pattern matching a number is simple. If the number or expression on the RHS evaluates to the same number as on the LHS, then there is a match. For example:

1> X = 6.
6
2> Y = 2.
2
3> X = 7.
** exception error: no match of right hand side value 7
4> X = Y.
** exception error: no match of right hand side value 2
5> X = Y + 4.
6

Tuples

Matching tuples is a little more complicated. Of course, you can have a direct match between two tuples, but more commonly, you can extract values from tuples by pattern matching. Lets say we have a tuple structure that represents an employee and we want to extract the employee name

2> % First we'll define a tuple
2> Employee = {employee, {name, grant}}.
{employee,{name,grant}}
3> % Now we'll pattern match on the tuple to extract the
3> % particular element we want from the tuple
3> {employee, {name, EmployeeName}} = Employee.
{employee,{name,grant}}
4> % So we expect that the EmployeeName variable
4> % will have the value grant now.
4> EmployeeName.
grant

Interestingly, this seems to reverse the common pattern of accessing elements deeply nested in structures in more conventional languages. In ruby, for instance, we might have an example like this:

person = {:employee => {:name => 'grant'}}
employee_name = person[:employee][:name]

In this case we have a naked variable name on the LHS and do some silly walking on the structure on the RHS to get at the value we want. Erlang reverses this so that we have a naked structure (meaning no function calls or other manipulation) on the RHS and we pattern match our way to the value that we want on the LHS of the expression.

Lists

Pattern matching Lists seems to be a little more simple. In general, a list can be pattern matched by the form [A, B, C... | T] where A, B and C are variables substituted by the first, second and third elements of the list respectively, and T is substituted by the remaining elements of the list. For example:

1> L = [1,2,3,4,5].
[1,2,3,4,5]
2> [A,B,C | T] = L.
[1,2,3,4,5]
3> A.
1
4> B.
2
5> C.
3
6> T.
[4,5]
7> [A, B, C, D, E, F, G] = L.
** exception error: no match of right hand side value [1,2,3,4,5]

Note that if we run out of elements on the RHS of the expression we’ll get a bad match type message. Also, the most common operation with this type of matching is more than likely to remove the head of the list into a variable so that we can work with it, and store the tail of the list for future work.

Erlang Notes – Simple data types

Here is the first 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.

Basic Data Types

Integers

  • Integer arithmetic is arbitrary sized. Yay for no overflows
  • Base 16 and 32 can be represented by 16#1a and 32#1a respectively. In fact, that
    works for arbitrary bases up to 36, I think. Base 2 is 2#1101

Floating-Point Numbers

  • Floating point numbers must have a decimal point followed by at least one decimal digit
  • As far as I can tell floats are also aribrarily sized.
  • Not sure yet how to specify precision, or if you can.
  • Cooercion from integer to float seems to be automatic, if one of the terms is a float

Atoms

  • Atoms usually start with lowercase letters. They can start with uppercase letters or non-alphanumerics if they are enclosed in
    quotes though.
  • foo, ‘Foo’, ‘@Foo’, dave@smith are all valid atoms
  • Atoms are used to represent symbolic constants, similar to Symbols in Ruby, or the #define FOO 1 construct in C

Tuples

  • A group of things enclosed in curly braces, {Foo, bar, 1, “22″} is a tuple
  • Tuples group a fixed number of things together. It performs the same function as a Struct in C or some other type of Record type of data structure
  • Tuples seem to be commonly used as a way of differentiating between functions that need to have different behaviours, but keep their arity the same. One example from Joe Armstrong’s book:


    area({rectangle, W, H}) -> W*H;
    area({circle, R}) -> 3.14 * R * R.

    By passing a tuple we are able to keep the arity the same, but cheat on the type of behaviour the function is implementing

Lists

  • A group of things enclosed in square brackets, [foo, X, 23, "toad"] is a list
  • Lists are useful for storing variable length numbers of things.
  • The first element of a list is called the head and the remainder is called the tail We can talk about these two elements using the general form [Head|Tail]. This is a common operation, especially when using recursive implementations of algorithms.

Strings

  • Strings are enclosed in double quotation marks. “My big ass” is a string.
  • Remember that things enclosed in single quotation marks are atoms – don’t confuse the two
  • Strings in erlang are really just lists of integers.
  • The shell will print a list of integers as a string if all the integers in the list represent printable characters under iso 8809 encoding

ciaweb home phone service

I recently switched over to cia.com for intartubes provision, and it’s been fine. With the service give you a voip line for more or less free (it works out to about $7 /mos. or something). So far that’s been nothing but a pile of shit – the Linksys ATA they send constantly loses registration with their servers for some reason.

Given that their customer service is notoriously bad, I haven’t even tried phoning in to see what condition their condition is in. But, if you reboot the cable modem, router and ATA in that order it re-registers, so I’m guessing the ATA only gets a window to register after their dhcp server has assigned a lease, and if the ATA drops the registration it’s not able to re-register until something asks for a new lease. (Btw, I”m using a linksys WRT 54G with DD-WRT firmware on the router, and the ATA is behind the router, so that I can do QOS routing on the SIP packets).

Anyhow….

I’m just writing this as a quick note to anyone else who might want to hack this setup. The ATA can be reset following Cyberweb’s instructions by dialing 1111 then RESET then # then 1 into your phone. This puts it in a factory default state where you can log into its admin web page and futz around – it’s at http://192.168.0.1 and the username is admin, password is also admin.

Then Cyberweb then instructs you to download a file from them through the modem to provision it. Once you download this file, the admin interface of the modem becomes locked, so it’s no longer possible to edit its setup parameters. Fortunately the file they ask you to download contains the admin password in clear text, so it’s trivial to get back in to the ATA.

Having said this though, I’ve no reason to believe that getting into it is useful. Unless you know what parameters their sip server is using at the other end, I doubt that changing anything will get you a better service. More than likely it’ll still suck. But its nice to know it’s doable even for the hack value. It’s also probably handy if you want to bring your own ATA or set up an asterisk box at home.

If anyone finds some params to frob that will make the whole thing more reliable though, let me know.