Records. (Learning Erlang 10)

Published on Nov 24, 2012

Other articles in the Learning Erlang series.

  1. Learning Erlang.
  2. Heads and tails, working with lists. (Learning Erlang 2)
  3. Variables, comparisons and dynamic typing. (Learning Erlang 3)
  4. Modules and functions, Erlang building blocks (Learning Erlang 4).
  5. Module attributes and compilation (Learning Erlang 5).
  6. Playing with recursion, (Learning Erlang 6).
  7. Playing with the file module (part 1). (Learning Erlang 7)
  8. The file module (part 2). (Learning Erlang 8)
  9. String manipulation in Erlang. (Learning Erlang 9)
  10. Functional arrays. (Learning Erlang 11)

You can certainly use Tuples to create complex types and use an atom as the first item to identify the type of the Tuple.

Creating a person using this convention looks like this.


  2> P = {person, "Hernan", "Garcia", "@theprogrammer"}.
  3> {person, Fname, Lname, Handler} = P.
  4> Fname.
  "Hernan"
  5> Handler.
  "@theprogrammer"

If we want to access the Fname field of the person directly we need to either use pattern matching or use the element/2 function, but we need to remember the position of the field.
Not very convenient.

Enter records.

Note of caution. These are my notes while learning Erlang. You are welcome to follow along and use them as a guide. Please make sure to check the Erlang language site

We can define a record and access the fields by name.
The same person example as a record looks like this.


  1> rd(person, {first = "", last = "", handler = "@"}).
  person
  2> P = #person{first = "Hernan"}.
  #person{first = "Hernan",last = [],handler = "@"}
  3> Fname = P#person.first.
  4> Fname.
  "Hernan"

Once we define a record it will enforce the field names in case we want to access a field that have not been defined.


  1> P = #person{age = 25}.
  * 1: field age undefined in record person

We can check if a variable is of a given record type using the is_record/2 function.


  1> is_record(P, person).
  true
  2> A = "string".
  3> is_record(A, person).
  false

The syntax to update a record is not obvious. You may be tempted to try to change the value of a given record but that will not work.


  1> P#person{first = "Diego2"}.
  #person{first = "Diego2",last = [],handler = "@"}
  2> P.
  #person{first = "Hernan",last = [],handler = "@"}

We need to remember that Erlang is immutable, so you really don’t update a record but assign the record with the changed values to a new variable.


  1> P2 = P#person{first= "Diego"}.
  2> P2.
  #person{first = "Diego",last = [],handler = "@"}
  3> P.
  #person{first = "Hernan",last = [],handler = "@"}

Pattern matching works pretty much as expected.


  1> #person{first = Name} = P.
  2> Name.
  "Hernan"

You can use a record as the value of a record field as well. Aka nested records.


  1> rd(actor, {name="", gender=""}).
  2> rd(movie, {title="", mainactor=actor}).
  2> M = #movie{title = "The movie", mainactor = #actor{name = "Diva", gender = "F"}}.
  3> M#movie.mainactor#actor.name.
  "Diva"

Conclusion.

We will see records more and more once we start to work in our first applications and interact with databases.