Sunday, January 11, 2009

Add a new language to your stack : Erlang

You know the typical good advice, learn a new programming language to improve your coding skills. Well this is never more true that when you pick a language that is totally different to the paradigm that you work in right now.

So for me, coming from a C/C++ background, it has been quite refreshing to look a one of the functional programming languages: Erlang. It really forces you to question what you think are fundamentals of programming.

Take for example your assumption of what a variable is. Given its name you might assume that it is something that can vary over time, but in Erlang it varies only once, ever: the time you first assign it.
Think C# immutable strings, that is every variable in Erlang.

…umm but wait…. so how are you going to do any form of looping ? And how do you increment variable… surely you have to at least once in a program ?

Ahh that is the kind of paradigm shift that I enjoy.

Think about how you might write some c++ code to determine the winner of  a game of Rock/Paper/Scissors

Winner CalcWinner( Attack player1, Attack player2 )
{
// check for a tie
if ( player1 == player2 )
{
return winner_tie;
}
//check all cases where player 1 wins
if ( ( player1 == rock && player2 == scissors) ||
( player1 == paper && player2 == rock ) ||
( player1 == scissors && player2 == paper ) )
{
return winner_player1;
}
//all other cases player2 wins
return winner_player2;
}



Now before you think in a functional programming way, it is hard to imagine that any language could be that different, so this is what it would look like ( well at least by someone who has been doing Erlang for a day or so )



%First check for a tie
calcWinner( {player1, Attack },{ player2, Attack} ) ->
{ tie };
%then look for all the cases where player 1 wins
calcWinner( { player1, rock }, { player2, scissors } ) ->
player1wins;
calcWinner( { player1, paper }, { player2, rock } ) ->
player1wins;
cakcWinner( { player1, scissors }, { player2, paper } ) ->
player1wins;
%all other cases are when player 2 wins
calcWinner( { player1, _ }, { player2, _ } ) ->
player2wins.


What is interesting here is that you have a method per decision, and Erlang will do pattern matching on each of the methods, in the order listed, to call the correct one, which just returns the result. The logic is really done in the definition of the methods.



Another example that challenges your normal paradigms. How, in a world where your variables can only have one value, do you represent a change of state in a service ?



An Erlang approach might be, have 2 message pumps. Pump 1 is state one, and when the appropriate states change event occurs, just skip to the second state message pump.



Its the kind of though that would not have been natural, but forced to think like that, it is beautifully clean and easy to debug. In hindsight quite OO in nature: unique classes per state.



The moral of the story, pick a language that is very different to what you know, not just a syntax change, to grow.


0 comments:

Post a Comment