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:56
Add comment
Erlang on Twitter
» jkvor (Jacob Vorreuter): Erlang target systems and release handling http://jkvor.com/release-handling
» REDDITSPAMMOR (REDDITSPAMMOR): #reddit Joe Armstrong, the father of Erlang, finally publishes his library of Erlang code!: submitted by p… http://bit.ly/bfBhWR
#rulez
» rmdrimmie (Rob Drimmie): @JamieBeach And by wide variety I mean different syntaxes, conventions. Not c, c++ and obj-c, but c, ruby, lisp or php, python, erlang, etc.
» monadic (alexis richardson): @roidrage and at erlang factory ...
» tm_interesting (Thomas Buck): How Much Has Scala Influenced Erlang? http://functional-orbitz.blogspot.com/2010/03/how-much-has-scala-affected-erlang.html
» YCHackerNews (YC Hacker News): How Much Has Scala Influenced Erlang?: http: Comments: http:
» kicauan (kicauan): How Much Has Scala Influenced Erlang? - http://su.pr/81fsWx
» hntweets (Hacker News): How Much Has Scala Influenced Erlang?: http://bit.ly/9tE1uy Comments: http://bit.ly/darEqv
» hkrnws (hkrnws): How Much Has Scala Influenced Erlang? http://bit.ly/aiEnK5
» darachennis (darachennis): joearms elib1 - get it on github now #erlang
Statistics
Number of aggregated posts: 9911
Number of comments: 380
Most recent article: March 11, 2010
Latest comments
» Jens on Eleven Years of Erlang: Hi, The link to how you started with Erlang is broken. Regards, Jens
» Jeff Martens on It Made Sense in 1978: I agree that word size is machine specific, but it becomes language-specific once it’s in a language definition. In Java an …
» Adley on XP Day Suisse 2009: What a great post. What an inspiration for everyone who is asking ‘Where is all this stuff I’ve asked for?’ and …