What to do About Erlang’s Records?
Programming in the 21st Century - James Hague - January 30, 2010The second most common complaint about Erlang, right after confusion about commas and semicolons as separators, is about records. Gotta give those complainers some credit, because they’ve got taste. Statically defined records are out of place in a highly dynamic language. There have been various proposals over the years, including Richard O’Keefe’s abstract syntax patterns and Joe Armstrong’s structs. Getting one of those implemented needs the solid support of the Erlang system maintainers, and it’s understandably difficult to commit to such a sweeping change to the language. So what are the alternatives to records that can be used right now?
To clarify, I’m really talking about smallish, purely functional dictionaries. For large amounts of data there’s already the gb_trees module, plus several others with similar purposes.
In Python, a technique I often use is to return a small dictionary with a couple of named values in it. I could use a tuple, but a dictionary removes the need to worry about order. This is straightforward in Erlang, too:
fun(length) -> 46; (width) -> 17; (color) -> sea_green end.
Getting the value corresponding to a key is easy enough:
Result(color)
This is handy, but only in certain situations. One shortcoming is that there’s no way to iterate through the keys. Well, there’s this idea:
fun(keys) -> [length, width, color]; (length) -> 46; (width) -> 17; (color) -> sea_green end.
Now there’s a way to get a list of keys, but there’s room for error: each key appears twice in the code. The second issue is there’s no simple way to take one dictionary and create a new one with a value added or removed. This road is becoming messy to go down, so here’s more data-driven representation:
[{length, 46}, {width, 17}, {color, sea_green}]
That’s just a list of key/value pairs, which is searchable via the fast, written-in-C function lists:keyfind. New values can be appended to the head of the list, and there are other functions in the lists module for deleting and replacing values. Iteration is also easy: it’s just a list.
We still haven’t bettered records in all ways. A big win for records, and this is something few purely functional data structures handle well, is the ability to create a new version where multiple keys get different values. For example, start with the above list and create this:
[{length, 200}, {width, 1400}, {color, sea_green}]
If we knew that only those three keys were allowed, fine, but that’s cheating. The whole point of dictionaries is that we can put all sorts of stuff in there, and it doesn’t change how the dictionary is manipulated. The general solution is to delete all the keys that should have new values, then insert the new key/value pairs at the head of the list. Or step through the list and see if the current key is one that has a new value and replace it. These are not linear algorithms, unfortunately. And you’ve got the same problem if you want to change multiple values in a gb_tree at the same time.
What I’ve been using, and I admit that this isn’t perfect, is the key/value list approach, but forcing the lists to be sorted.This allows the original list and a list of changes to be merged together in linear time. The downside is that I have to remember to keep a literal list in sorted order (or write a parse transform to do this for me).
There’s still one more feature of records that can’t be emulated: extracting / comparing values using Erlang’s standard pattern matching capabilities. It’s not a terrible omission, but there’s no way to dodge this one: it needs compiler and runtime system support.
Categories: Blogs Programming in the 21st Century
Comments
With respect, the omission of pattern-matching is significant in my mind, and it’s the only reason I use records over the more dynamic options.
Pattern matching was a significant attractor for me when I was first learning FP; it definitely results in more elegant code.
Any alternative to records would need to include this to convince me make a change.
Posted by David Smith on 01 Feb 2010 at 15:56The general solution is to delete all the keys that should have new values, then insert the new key/value pairs at the head of the list. Or step through the list and see if the current key is one that has a new value and replace it….Nissan Frontier Superchager
Posted by Nissan Frontier Superchager on 30 Aug 2010 at 05:59
Add comment
Erlang on Twitter
» JohnHaugeland (John Haugeland): @ggoodale Real men would write it in C++, but this’d be pretty close to trivial in something like Erlang.
» fedorausers (Fedora Linux Users): #linux #fedora Re: erlang-doc - dubious dependencies http://dlvr.it/4cWnw
» bestform (bestform): @danielefrijia lisp und erlang habe ich beides schon beruflich eingesetzt.
» bestform (bestform): Es gibt übrigens durchaus Antworten, die ich akzeptieren würde. Lisp, Erlang, Clojure, von mir aus auch Scala. Na? Wie sieht’s aus? :)
» charpi (Nicolas Charpentier): RT @pavlobaron: Even if #erlang hasn’t been mentioned in the latest #thoughtworks report, it won’t keep us from building real cool things with it
» chrisumbel (chris umbel): the functional work i’ve done in the last 18 months (erlang & clojure) have clearly changed how i write Java & .Net code 4 the good
» grzegorzkazulak (Grzegorz Kazulak): @strzalekk erlang? nice :)
» aprimc (Andrej Primc): Reinventing the wheel. No agreeable template engine in Erlang.
» fedorausers (Fedora Linux Users): #linux #fedora erlang-doc - dubious dependencies http://dlvr.it/4cNwW
» opencrowd (OpenCrowd): Cloudant’s BigCouch is open-source. BigCouch is a set of Erlang/OTP applications for creating a cluster of CouchDBs http://bit.ly/bILJ8p
Statistics
Number of aggregated posts: 10079
Number of comments: 554
Most recent article: September 01, 2010
Latest comments
» Nissan Frontier Superchager on Erlang Doesn’t Fit The JVM: I don’t believe it is the silver bullet that fixes all the problems that required you to do your JVM tuning….Nissan Frontier Superchager
» Nissan Frontier Superchager on What to do About Erlang's Records?: The general solution is to delete all the keys that should have new values, then insert the new key/value pairs…
» videomob on Java And Threads (Jetty): Хватит спамить, накинулись