A Pythonista's Impressions of Erlang

I am planning to write a poker server in Erlang . Why? A couple of reasons. First off, I have heard that the concurrency support in it is excellent. Secondly, A quick glance gave me the impression that it was, at least, not brain-dead. Third, it's been a long time since I learned a new language, so I'm planning to do it for kicks.

As such, for the last few days, I've been playing around with the language, and I have begun to form my opinions on it. Since I've been pretty busy, I haven't had too much time to play with it, and as such my opinions are half-baked. Since that never stopped me from writing before, here they are.

If I'm wrong somewhere (and I'm sure I am) drop me a comment, and I'll fix it.

The Good

Interpreter : Erlang has a shell that is very similar to Python's. I am totally addicted to the Python shell, so this makes experimentation quite a bit easier. It features some comforting functions: m(module_name). lists the functions exported by module_name, and length([1,2,3]). returns 3.

: Erlang has a shell that is very similar to Python's. I am totally addicted to the Python shell, so this makes experimentation quite a bit easier. It features some comforting functions: m(module_name). lists the functions exported by module_name, and length([1,2,3]). returns 3. Pattern Matching : I *love* this feature. If I were to make a serious switch to Erlang, pattern matching would be a large reason. I'm not sure how well it works in large applications yet, but it certainly feels elegant to me. With pattern matching, you can define one function multiple times, and Erlang will pick the appropriate function based on its signature. Perhaps an example will help; you can define your basic factorial function like so: fact(0) -> 1; fact(N) -> N * fact(N-1). Erlang will automatically call the first function when the argument is zero, and the second one otherwise.

: I *love* this feature. If I were to make a serious switch to Erlang, pattern matching would be a large reason. I'm not sure how well it works in large applications yet, but it certainly feels elegant to me. Guards : Similar to pattern matching, guards help Erlang figure out which function to call by setting a basic precondition for one or more parameters. Thus, we could revise our factorial function in a silly way to use guards: fact(N) when N > 0 -> N * fact(N-1); fact(0) -> 1. As you can see, this is a silly way to use guards, but I think it gives a good quick indication of what they do.

: Similar to pattern matching, guards help Erlang figure out which function to call by setting a basic precondition for one or more parameters. Thus, we could revise our factorial function in a silly way to use guards: Data Structures : Erlang, for the most part, has a good, rich set of data structures. Lists are as powerful as they should be, and it has list comprehensions (which have quickly become one of my favorite Python features). Tuples work nearly the same as they do in Python as well. Unlike Python, Erlang features atoms. Atoms, which have no Python equivalent, consist of any identifier which starts with a lower-case letter or any single-quoted string. It seems that Erlang's idiom for dictionaries uses tuples and atoms: Mydict = {{anatom, 12}, {'atom w space', 15}, {atomsarekeys, 12}}. Erlang does (obviously) have variables, but they must start with a capital letter to be distinguished from atoms. There is also a record type, but I do not have a good enough understanding of it yet to explain it.

: Erlang, for the most part, has a good, rich set of data structures. Lists are as powerful as they should be, and it has list comprehensions (which have quickly become one of my favorite Python features). Tuples work nearly the same as they do in Python as well. The Philosophy: The most abstract point here, I think that Erlang seems to encourage good, readable code. After just a few hours in the language, I feel comfortable enough to dive into the Erlang httpd server and try to understand what's going on. Considering that other functional languages have only given me frustration in this respect, I think it bodes very well for Erlang to be good in this regard.

The Not-Sure-If-It's-Good-Or-Not

Variable Binding : Variables, once bound in a scope, cannot be reassigned to another value in the same scope. I really like Python's binding scheme, where variables are just names, and may be assigned to refer to anything. However, I can imagine the variable binding restriction catching a bunch of silly errors. I haven't used it enough (read: at all) to make a judgment on whether it's worthwhile or not. On the upside, it does seem to encourage short functions, which I think is a good thing. Erlang in general seems to encourage short functions which are used by other objects; I am in the process of studying the Erlang idiom of supervisors and workers.

: Variables, once bound in a scope, cannot be reassigned to another value in the same scope. I really like Python's binding scheme, where variables are just names, and may be assigned to refer to anything. However, I can imagine the variable binding restriction catching a bunch of silly errors. I haven't used it enough (read: at all) to make a judgment on whether it's worthwhile or not. Concurrency: Although it looks neat, I've yet to get in and play with Erlang's concurrency, so I don't want to render a decision on it.

The Bad

No String Type : Let me repeat this for emphasis: There Is No String Type In Erlang. Arrrggggh! Why would you do this? A string is treated, you guessed it, as a sequence of ASCII codes in a list. It's C all over again. The shell tries to "guess" when a list is actually a string, which is a pain if a list you create just happens to contain values in the printable ASCII range.

: Let me repeat this for emphasis: There Is No String Type In Erlang. Arrrggggh! Why would you do this? Error messages : Erlang's error messages are totally undecipherable for a newbie. Here's what happens when you call a function with the wrong number of arguments: ** exited: {undef,[{shell_default,length,[[1,2,3],12]}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** Got it?

: Erlang's error messages are totally undecipherable for a newbie. Here's what happens when you call a function with the wrong number of arguments: Documentation : Most of the links to documentation on erlang.org are broken. When you finally do get to the docs (mysteriously at erlang.se instead of erlang.org), there are some real gems. When you click on "Complete List of BIFs" (BIF = built-in function) in the reference manual, you get "For a complete list of BIFs, their arguments and return values, refer to erlang(3).". The kicker? When I downloaded and installed Erlang, the man pages either weren't installed or weren't put in the right place. So, as a newbie, I am left digging away from the main erlang site just to find out what the f$%$ing built-in functions are. Not a good sign.

: Most of the links to documentation on erlang.org are broken. When you finally do get to the docs (mysteriously at erlang.se instead of erlang.org), there are some real gems. When you click on "Complete List of BIFs" (BIF = built-in function) in the reference manual, you get "For a complete list of BIFs, their arguments and return values, refer to erlang(3).". The; Punctuation. Is, Weird ->: Maybe this is one of the not sure things, but I'm pretty sure I don't like some of Erlang's punctuation. I don't mind the '->', but I oftentimes have to look at the docs to figure out whether I should be using a ';' or a '.' to end a statement. Furthermore, the error messages, as I've already shown, are less than helpful in guiding you to the source of the syntax error.

Well, that's it for now. I'm sure I left some stuff out, and I'm sure you disagree with some of what I've said, so leave me a comment with what you think or drop me an email.

Overall, I think Erlang has some neat features - especially pattern matching and guards. Furthermore, if what everyone says is true, its concurrency is fast and well-designed. Although the lack of proper documentation is a turn-off, I feel like I'll be able to learn what I need to know from reading the very readily available code. I'm still going to give it a shot, which is a good sign.