Charlie Harvey

Erlang — Day One

Bruce Tate introduces Erlang as making "hard things easy and easy things hard". Which isn't entirely fair I guess, given that the things it makes hard are hard for good reason. Mutability is hard, but something to be avoided in concurrent systems, which is the area where Erlang's sweet spot is located. He also compares Erlang to Agent Smith from the Matrix. I think its maybe a little early in my Erlang coding career to say much about that …

First impressions

I started of with the day one excercises just before work this morning. And I found the whole thing a lot less painful than Scala, and perhaps slightly less alien than Prolog. Partly this was due to the excellent Erlang documentation. Note to language designers, terse manuals with no examples make people like me struggle with your languages. I’ve not worked through learn you some Erlang or the 4 day Erlang course yet, but good introductory tutorials are another big plus for a beginner in any language.

I got a bit baffled by the Prolog-ness at first, but Erlang felt easier having tackled Prolog. I enjoyed playing with the examples and didn't find them too taxing, even adding some extra features for the hell of it! The experience was actually kind of fun, I was relieved not to end up fighting against static types like I had with Scala, or end up staring at my monitor in baffled incomprehension like I did when I first had a play with Prolog.

word_count.erl

Write a function that uses recursion to return the number of words in a string.

I found this task a bit more difficult than task one. Once I decomposed it into two sub problems things got easier, plus I ended up with a generic list item counting function. I daresay there is one already, but rolling your own can be a good way to learn. So, I tokenize the string into a list in word_count, then count the items in the list in list_count. I guess that if I were to change anything in this it'd probably be the naming word_count:word_count seems repetitious. -module(word_count). -export([word_count/1]). -export([list_count/1]). % count the number of items in a list % base case, empty list list_count([]) -> 0; % normal case. non-empty list, pop head, increment counter, recurse on tail list_count(Words) -> [_|T] = Words, 1 + list_count(T). % tokenize the string into a list. call list_count on that, print the return of list_count word_count(WordString) -> io:format("~p~n", [ list_count(string:tokens(WordString, " ")) ]). % I used the tokens function to tokenize WordString: % http://www.erlang.org/doc/man/string.html

Let's see that in (Shakespearean) action. 19> c(word_count). {ok,word_count} 20> word_count:word_count("O gentlemen, the time of life is short! 20> To spend that shortness basely were too long, 20> If life did ride upon a dial's point, 20> Still ending at the arrival of an hour. 20> An if we live, we live to tread on kings; 20> If die, brave death, when princes die with us! 20> Now, for our consciences, the arms are fair, 20> When the intent of bearing them is just."). 60 ok Well that looks OK then. Its scene 2 of Henry IV part 1 in case you were wondering. I very much aspire to living to tread on kings!

count.erl

Write a function that uses recursion to count to ten

Nothing too radical here, though my implementation does more than the spec in that it can count up to an arbitrary number. Note though the use of the guard in the N,Max variant of the function. I imagine that in a proper implementation you'd return N or maybe accumulate a list of N integers. Again the name count isn't great. -module(count). -export([count_to/2]). % uses a "guard" of Max count_to(N,Max) when N < Max -> io:format("~p~n", [N]), count_to(N+1, Max); count_to(N,N) -> io:format("~p~n", [N]), N.

So now we can say 15> c(count). {ok,count} 16> count:count_to(1,10). 1 2 3 4 5 6 7 8 9 10 10 but also things like 17> count:count_to(5,10). 5 6 7 8 9 10 10 18> count:count_to(0,3). 0 1 2 3 3

msg.erl

Write a function that uses matching to selectively[sic] print "success" or "error: message" given input of the form {error: Message} or success.

My original implementation didn't catch typos and such, and I use {err: Message} instead of error. I feel like I may have cheated a little in only using an explicit guard to match a Msg of "success". But hey, I learned a bit so its all cool. Note that the error message goes to STDERR and that typos are handled.-module(msg). -export([print/1]). print({err, Msg}) -> io:format(standard_error, "!! Error: ~s~n", [Msg]); print({_, Msg}) -> io:format(standard_error, "!! Can't deal with: ~s~n", [Msg]); print(Msg) when Msg == "success" -> io:format("Yay! ~s~n", [Msg]); print(Msg) -> io:format("Can't deal with msg: ~s~n", [Msg]).

A quick run to see it work. 21> c(msg). {ok,msg} 22> msg:print({err, "Tech #Fail"}). !! Error: Tech #Fail ok 23> msg:print({errr, "Tech #Fail"}). !! Can't deal with: Tech #Fail ok 24> msg:print("Tech #Fail"). Can't deal with msg: Tech #Fail ok 25> msg:print("success"). Yay! success ok


Comments

  • Be respectful. You may want to read the comment guidelines before posting.
  • You can use Markdown syntax to format your comments. You can only use level 5 and 6 headings.
  • You can add class="your language" to code blocks to help highlight.js highlight them correctly.

Privacy note: This form will forward your IP address, user agent and referrer to the Akismet, StopForumSpam and Botscout spam filtering services. I don’t log these details. Those services will. I do log everything you type into the form. Full privacy statement.