Too many illegal datagrams from the remote computer AS400

A volte nei log di sistema dei server Windows che convivono in una subnet con un AS400 può comparire il seguente errore:

"The browser driver has received too many illegal datagrams from the remote computer YOUR_AS400_NAME to name xxxx on transport NetBT_Tcpip_{DF3149C4-A44D-493F-BD8C-BE3B. The data is the datagram. No more events will be generated until the reset frequency has expired."

Il problema può essere risolto eliminando la spunta da "Invia annunci di ricerca" dalla configurazione del NetServer in iSeries Navigator.
Illegal datagram from AS400 - Configurazione iSeries Navigator

Some problems with Microsoft SQL Server

Problem 1: changes in sqlcmd

I don't know exactly what happened, but from a certain moment the sql script I used to backup my SQL server DB stopped working. I usually ran it with this syntax:

sqlcmd  -i backup.sql

Where backup.sql contained the code to connect to my server. Suddenly the script started acting up, giving this message:

HResult 0x2, level 16, state 1
Named Pipes Provider: Could not open a connection to SQL Server [2].

After a while, I understood that for some reason, the sqlcmd utility changed its behavior, and forced the user to set the server with the -S parameter. So, in my case, I solved changing my batch script this way

sqlcmd -S lpc:.\SQLEXPRESS -i backup.sql

where lpc:.\SQLEXPRESS is the way to connect to my SQLEXPRESS instance via shared memory.

Problem 2: the wrong restore place

I also have a script that restores my db on another machine. I changed the destination PC, and, guess what, the restore script started acting up too!!! :-( This was the error message:

Msg 5133, Level 16, State 1, Line 1
Directory lookup for the file "C:\SomePathTo\myDB.mdf" failed with the operating system
error 3(The system cannot find the path specified.).

As the database was in C:\SomePathTo in the source machine and the target machine had not such directory, this stupid SQL server could not complete the restore operation!
The solution is

1) Run the command

restore filelistonly from DISK= 'C:\someDirt\myDB.bak'

If you run this from sqlcmd, redirect the output to some file with the -o option, as you can't see this large output on one line.

2) Search the results of this command for the colums "LogicalName" and substitute them in this script (here I used the names myDB_dat and myDB_log)

RESTORE DATABASE [myDB]
FROM DISK = 'c:\mfoff\mfoffdb.bak'
with
move 'myDB_dat' TO 'C:\newPath\myDB.mdf',
move 'myDB_log' To 'C:\newPath\myDB_log.ldf'

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.

I don’t like infixes

All this stuff began with a tweet of mine in response to @unclebobmartin. While Mr. Martin said "I am becoming ever more convinced that clojure is the functional language to use", I argued that Clojure is the opposite of Literate Programming as (+ 1 2) is very far from my natural way of thinking 1 + 2.

My opinion is that the prefix notation of Clojure, and the resulting parenthesis pollution, makes this language very hard to read.

Then @fogus pointed out that there is nothing literate about the infix way of representing (< a b c d e f g). That's true, if we think of a C like implementation such as:

a<b && b<c && c<d && d<e && e<f && f<g

But, fortunately, we have Scala:

 
package net.fl.clojure
 
object ClojureDemo {
 
  case class RichList (list : List[Int]) {
    def isOrderedBy(f: (Int, Int) => Boolean) : Boolean = list match {
      case Nil => true
      case x :: Nil => true
      case x :: y :: xs => f(x, y) && listConverter(y :: xs).isOrderedBy(f)
    }
 
    def isAscendingOrdered = isOrderedBy(_ < _)
  }
 
  implicit def listConverter (list: List[Int]) = new RichList(list)  
 
  def main(args : Array[String]) : Unit = {
    println(List(1, 2, 4).isOrderedBy(_ < _))
    println(List(1, 20, 4).isOrderedBy(_ < _))
 
    println(List(1, 2, 4).isAscendingOrdered)
    println(List(1, 20, 4).isAscendingOrdered)
  }
}
 

So the lispish (< a b c d e f g) becomes List(a b c d e f g).isAscendingOrdered or, if you want to be more flexible List(a b c d e f g).isOrderedBy(_ < _)

Unit testing with the Saff Squeeze

Yesterday I read an interesting post of Kent Beck about a testing technique called Saff Squeeze. The idea is that, when you have to fix a bug in your code, first of all you need to write an "high level" test (hit the bug high) that shows the problem, then, instead of stepping in your debugger looking for the bug, you try to write a test which goes deeper and deeper in the code, in-lining method calls, until you get to the root of the problem (hit the bug low). It's like the Tai Otoshi Judo throw.


Waterfall

A real world example

As I had to find a bug in my code, I decided to try this technique.

I'm working at an ERP that exports a list of tasks to Microsoft Project. If the user chooses to create a plan scheduled from the finish date, that date has to be the maximum value of the deadlines of each task. Unfortunately there was a bug in this piece of code, so I wrote this test. (Note that, for compatibility issues, I use Java 1.4 and JUnit 3 for the project.)

 
  protected void setUp() throws Exception {
    converter = new XMLConverter();
    projectBean = new ProjectBean();
  }   
 
  public void testIfScheduleFromFinishProjectFinishDateIsTheMaximumValueOfTasksDeadlines() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    projectBean.setScheduleFromStart(false);
 
    String xml = converter.toXML(projectBean);
    TestUtils.assertContains(
		xml,
        "<FinishDate>" +
			new DateProjectConverter().toString(maxDeadline) +
        "</FinishDate>"); //Fails
  }
 

This was my "high-hit" test. As converter.toXML is a full tested method that simply creates an XML from objects via reflection, I supposed that the problem was in projectBean.setScheduleFromStart, so I wrote this new test.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    projectBean.setScheduleFromStart(false);
 
    //projectBean.finishDate is now public for testing purposes
    assertEquals(maxDeadline, projectBean.finishDate);   //Fails
  }
 

The test failed: I was right. Then I tried to modify the test in-lining the code of the failing method.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    //projectBean.scheduleFromStart is now public for testing purposes,
    //and the setScheduleFromStart method is inlined
    projectBean.scheduleFromStart = false;
    if (projectBean.scheduleFromStart) {
      projectBean.finishDate = null;
    } else {
      //projectBean.maxDeadline() is now public for testing purposes
      projectBean.finishDate = projectBean.maxDeadline();
    }
 
    //projectBean.finishDate is now public for testing purposes
    assertEquals(maxDeadline, projectBean.finishDate);   //Fails
  }
 

Then I simplified the test.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    //projectBean.finishDate is set to private again
    assertEquals(maxDeadline, projectBean.maxDeadline());   //Fails
  }
 

So this was time to inline the projectBean.maxDeadline() method.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
	//projectBean.tasks is set to public
	ProjectTaskBean maxDeadlineTask =
      (ProjectTaskBean) Collections.max(projectBean.tasks, new DeadlineComparator());
 
    //projectBean.maxDeadline is set to private again
    assertEquals(maxDeadline, maxDeadlineTask.getDeadline());   //Fails
  }
 

Well, at this point I saw that the problem should be in the DeadlineComparator class, so I could get rid of the intermediate tests, rollback the changes to the ProjectTaskBean class and write a test against the buggy class (my "high-low" test).

 
  public void testDeadlineComparatorFindsMaxDeadline() {
    MyDate maxDeadline = new MyDate();
 
	Collection tasks = new ArrayList();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    tasks.add(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    tasks.add(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    tasks.add(task3);   
 
	ProjectTaskBean maxDeadlineTask =
      (ProjectTaskBean) Collections.max(tasks, new DeadlineComparator());	
 
	//All fields and methods in projectBean are set to their original visibility
	assertEquals(maxDeadline, maxDeadlineTask.getDeadline());   //Fails
  }
 

So this was time to fix-up my code! ;-)

Conclusion

Kent Beck says: "Squeezing encourages good design. If inlining creates too big a mess, back up, clean up the called method, and inline again. Even if I received no other benefits from squeezing, the design improvement would be worth it."

Well, if it's definitely true that you need a good design (or, at least, a not so bad one) for squeezing, I think that it could be difficult to refactor your code when you're doing it: after all, you have a red bar.

Anyway, it seems a nice technique to explore your code without digging in the debugger too much and, this time, it worked fine. :-)

Il sofista

E' da qualche giorno che sulla lista italiana di "Exteme programming" infuoca una polemica su cosa sia XP, chi abbia il diritto di darne una definizione e quale definizione se ne debba dare. Non so perch, ma tutte queste discussioni mi fanno tornare in mente un brano dell'Apologia di Socrate. Ecco cosa Platone fa dire a Socrate.

E se qualcuno vi ha ancora detto che io faccio leducatore e che ne ricavo gran guadagno, neppure questo vero. Riconosco certo che bello essere capace di educare gli uomini, come un Gorgia Leontino, un Prodico di Ceo, o un Ippia di Elide. A costoro concesso, o Ateniesi, di andare di citt in citt e di attirare al loro insegnamento i giovani, i quali invece potrebbero benissimo, senza spendere nulla, frequentare linsegnamento di quei concittadini che volessero scegliersi; quelli invece sanno persuaderli ad allontanarsi da questi e a venire loro, a pagarli profumatamente e a mostrare anche la dovuta gratitudine. Che dico? E venuto qui fra noi un sapiente uomo, un cittadino di Paro, come ho potuto apprendere per avere io parlato con uno che con i Sofisti ha speso pi denaro che tutti gli altri messi insieme, Callia precisamente, il figlio dIpponico. Voi sapete che egli ha due figli; ebbene io ho voluto interrogarlo:
-Callia [...] A chi dunque bene affidare [i giovani]? Chi abile a sviluppare in loro le virt proprie delluomo e del cittadino? Suppongo che tu ci abbia molto riflettuto, poich hai dei figli. C qualcuno che ne sia capace o no?
-Certamente, mi rispose.
-E chi costui, chiesi, e di quale paese , e che prezzo chiede per il suo insegnamento?
-E Evno di Paro, o Socrate, mi rispose, e chiede cinque mine.
-Felice Evno, pensai io, se veramente possiede questarte e linsegna a cos modico prezzo! Anchio mi sentirei fiero e felice se sapessi fare altrettanto; ma io non so, o Ateniesi.

Anche noi, come gli Ateniesi di oltre due millenni fa, ci troviamo nelle condizioni di dover distinguere gli insegnamenti dei sofisti da quelli dei socratici. Alcuni indizi potrebbero forse aiutarci.

  • Il sofista colui interessato pi al guadagno che alla ricerca della verit.
  • Il sofista annuncia agli altri di conoscere la verit, il socratico dichiara solo di ricercarla.
  • Il sofista vuole imporre la propria autorit, al socratico l'autorevolezza data dagli altri.

In base a questi criteri, in me molti dubbi sorgono su alcuni presunti "guru"....

A TDD side effect

All you know that TDD has god side effects. One of them is testing your application :-) Another one is to force you to write less verbose code.
Sometimes (only sometimes ;-) ) when you write production code not writing tests (oh, well I do not do that, ehm) you accept that the code is not as concise and "speaking" as it should be: after all you are writing code that does its dirty work (maybe), that's enough!!! But when you write tests, you know that the goal of test code is to speak to other people. In other words, my attitude when I write production code is to write code that speaks to the machine, while when I write test code I'm trying to speak to people, and you know, when you're speaking to human beings you can't bore them. So your writing must be clear and concise. In order to do that, sometimes you're forced to write some helper classes that, after a short while, you'll find useful on the production side too.