The biggest problem with records is that you cannot dynamically modify them. For example, suppose you want to create a table in Mnesia, but you don't know at the moment how many columns your table will have. With records, you have to provide all record declarations for all tables you plan to generate on compilation time, which sometimes is simply impossible.
I did some research on the topic while writing Mnapi, and I must say it wasn't that easy if you don't know where to start. Finally, I managed to decipher Erlang records secrets mostly by analyzing Mnesia source code. One more reason for using open source software, by the way :-)
It turns out that records are in fact wrappers for tuples. So a record defined as:
-record(book, {isbn, author, title}).gets translated internally into:
{book, isbn, author, title}.Thus, an equivalent of:
mnesia:write(#book{isbn = I, author = A, title = T}).is:
mnesia:write({book, I, A, T}).The only advantage of such crippled structure is that the compiler knows the positions of all elements in the record, so it can always put them in a valid tuple in correct order and find possible errors instantly at the compilation stage. No matter if you write:
#book{isbn = I, author = A, title = T}. #book{author = A, isbn = I, title = T}. #book{title = T, author = A, isbn = I}.the #book record will eventually end up in Erlang as:
{book, I, A, T}.Records try to make accessing data easier. To get an author from the tuple above you would have to use element function:
X = element(3, {book, I, A, T}).which can become problematic if you shift fields in the tuple. With record you can do the same simply with:
X = #book.author.no matter what the order of the record is. But it's still cumbersome and static.
Fortunately, Erlang allows you to build dictionaries, which can be used to store Key - Value pairs dynamically. For example:
D = dict:new(), D1 = dict:store(isbn, 1234, D), D2 = dict:store(author, myAuthor, D1), D3 = dict:store(title, myTitle, D2), Book = dict:store(book, D3, D3), dict:find(author, Book).Personally, I don't use records, unless I really have to. I use dictionaries instead, they are much more powerful and elegant. And you can evaluate them on runtime.
2 comments:
You are right of course, but records are explained in the Erlang documentation:
http://erlang.org/doc/reference_manual/records.html#8
http://erlang.org/doc/programming_examples/records.html#1
For a little more detailed description of why they look, and work, like they do look in the Erlang Rationale which has a section on them. (The last PDF file is the best)
Thank you for the links, they are indeed a very good source of information about the Erlang records.
Post a Comment