Escript under Windows

Escript is a tool for executing simple scripts written in Erlang. It's a nice tool, but the manual page is too much "Unix oriented":if we try to run the example script under one of the funny and exotic operating systems of the Windows family, we get something like this:

C:\temp>escript factorial.escript 5
escript: Failed to open file: C:\temp\escript.escript

Ouch! The solution to the problem comes reading the sources of escript.exe. Under Windows it takes the program name used to call it (in our example escript): if it doesn't end with the exe suffix it takes it as the name of the script, then it adds the escript suffix ant tries to run it: so it looks for as escript.escript which doesn't exist. Obviously it's a bug, but to overcome it, we can add the exe suffix to our command line:

C:\temp>escript.exe factorial.escript 5
factorial 5 = 120

Another note for Windows users: the first line cannot contain Erlang (it's the place for the Unix # line).If you try to run this script

main(Args) ->
	print_args(Args). 

print_args([]) ->
    ok;
print_args([FirstArg | Rest]) ->
    io:format("~s~n", [FirstArg]),
	print_args(Rest).

You'll get this result:

C:\temp>escript.exe x.escript Hello World
x.escript:2: syntax error before: '.'
escript: There were compilation errors.

You must add a line before the main in order to run it.

Software gestionale in Erlang?

Come forse saprete, il mio lavoro consiste nello sviluppo di software gestionale. Ultimamente, però, grazie agli amici dell'XP User Group di Milano, mi sto appassionando al linguaggio Erlang. Mi è allora venuta la balzana idea di vedere se le due cose potessero avere un punto di incontro. Sia chiaro, con questo post non sto invitando nessuno a sviluppare programmi gestionali in Erlang, cosa che ritengo piuttosto difficile, ma desidererei da un lato saggiare la duttilità del linguaggio, dall'altro cercare di imparare qualcosa riguardo ai principi di scomposizione funzionale dei problemi.

La gestione di un ordine

Durante una mia presentazione del linguaggio Scala tenutasi all'XP User Group di Bergamo, ho già affrontato la questione di scomporre "funzionalmente" un elementare problema gestionale. Gli esiti non sono stati brillantissimi in quanto a chiarezza, desidererei quindi riprovare utilizzando un diverso linguaggio.

Il problema giocattolo che vorrei affrontare è quello di effettuare dei calcoli su un ordine, rappresentato come una lista di righe d'ordine. Definisco quindi come prima cosa il record riga d'ordine:

 
-record(order_row, {description, price, qty, vat_rate = 0.2}).
 

Su questo record posso quindi definire delle banali funzioni quali il calcolo del prezzo netto, dell'IVA e del prezzo ivato:

 
net_amount(OrderRow) ->
  OrderRow#order_row.price * OrderRow#order_row.qty.
 
vat(OrderRow) ->
  net_amount(OrderRow) * OrderRow#order_row.vat_rate.
 
amount(OrderRow) ->
  net_amount(OrderRow) + vat(OrderRow).
 

Una generica elaborazione su un intero ordine si può quindi intendere come la composizione di un'operazione di aggregazione, quale la somma, e di una funzione di calcolo applicata ad ogni riga.

 
computation(Order, AggregationFunction, CalculusOnRow, StartResult) ->
  lists:foldl(fun(OrderRow, ResultSoFar) ->
                 AggregationFunction(CalculusOnRow(OrderRow), ResultSoFar)
              end, StartResult, Order).
 

Rielaborando questi mattoncini possiamo pertanto ottenere facilmente diversi tipi di computazioni:

 
total_amount(Order) ->
  computation(Order, fun erlang:'+'/2, fun amount/1, 0).
 
max_vat(Order) ->
  computation(Order, fun erlang:max/2, fun vat/1, 0).
 
min_net_amount(Order) ->
  computation(Order, fun erlang:min/2, fun net_amount/1, 0).
 

Conclusioni

La scomposizione funzionale del problema in Erlang sembra più semplice che in Scala. La sintassi Erlang per i record risulta però piuttosto "legnosa" e temo possa sfuggire presto di mano con problemi di dimensioni reali. Rimango inoltre sempre perplesso sulla tipizzazione dinamica: capire con che a parametri invocare una funzione potrebbe essere un problema. Ciò nonostante, ritengo che Erlang meriti senza dubbio un ulteriore approfondimento.

Bowling game Kata in Erlang reloaded

So my first solution to the Bowling Game Kata was wrong! Well, a good chance to learn something. ;-)

Let's try to solve the problem again.

I added the last test to my test suite, which shows the previous bug:

Then I modified the code this way

The code now is not so clear, but it passes tests! What I learned from this exercise? Well, Ron Jeffries said:

I would bet, though, that if we were to take some set of problems that can be solved in a natural fashion both recursively and iteratively, and had a bunch of programmers write both versions, they would have more trouble with the recursive ones, on the average.

My experience seems to confirm his opinion, even if I should consider that it's more than twenty-five years that I solve problems iteratively, while I came to use recursive solutions only a few times. Thus, perhaps my way of seeing problems is not accustomed to think in a recursive fashion, and it requires some more time to get into this way of thinking. So, let's do more Erlang exercises!

Bowling game Kata in Erlang

In the last meeting of the Extreme Programming (XP) User Group of Milan, Gabriele Lana, after an introduction to Erlang, guided us in doing the Fizz-Buzz kata in this language. The experience was exciting, so I tried to execute a kata on my own. I chose the Bowling game Kata by Robert C. Martin because I did it many times in Java. I wrote the same tests of Mr. Martin, adding just one to cover a corner-case of my implementation. Here there are:

I defined an include file for some macros which helped me to make the code more speaking (I hope)

And here is my solution:

This solution, like the ones proposed by Gabriele, seems simpler than the classical Java code showed by Mr. Martin.
I think that functional languages like Erlang are more suited for small algorithmic problems like this. I wonder if these languages

  • can scale for larger problems
  • can handle situations where the algorithmic component is not so preeminent, while the real issue is managing changes


My first impression on Erlang is positive: it's a great Domain Specific Language, where the domain is parallel and distributed computing. It's syntax is simple (far simper than the Scala one), even if this does not imply that writing Erlang programs should be simple. It has some negative issues too: string handling is difficult; the flat name space could be a problem for large projects; the error messages are often obscure (at least for a newbie like me); and, above all, it has no static typing, so the programs need lots of comments to explain the communication protocol between modules.
These lacks in the language are also evidenced by the presence of macros: in my humble opinion, a language that needs macros has a poor syntax. But macros could turn in a great value if they are used to expand the language in the direction of literate programming. A small example of this is the macro ?is_spare I created to make guards clauses more speaking. I'll do some explorations in this direction in the future.