Archive for the ‘Scala’ Category.

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(_ < _)

Presentation on Scala

I translated in English the presentation on Scala I gave to the XP User group of Bergamo:

Fantom vs Scala: semicolon inference and something more

As I said in a previous post, even if Scala is at the moment the best candidate to become the Next Big Language, I think that many things in its syntax are Byzantine and error prone. The examples in Klaus' comment are very explanatory in this sense.
In my search of the Holy Graal of the programming languages, I met Fantom (previously known as Fan), a very interesting attempt to create a language simple yet powerful.
First of all, let's have a look at a Fantom version of the semicolon inference example of my previous post. Note that, since I'm an absolute beginner in Fantom programming, the use of the language I made is far from optimal: any suggestion will be appreciated.

class GoodFantom {  

  static Int subtract1(Int a, Int b) {
    a -
    b
  }  

  static Int subtract2(Int a, Int b) {
    a
    - b
  }  

  static Void main() {
    echo(subtract1(10, 2))      //Prints 8
    echo(subtract2(10, 2))      //Prints 8 too!
  }
}

The Fantom way to handle statements ending seems pretty good. Anyway, I'm not sure that there are not drawbacks to this approach: again, any suggestion is welcome.
Now let's see how this example of creating a DSL fragment in Scala could be translated in Fantom.
So, let's define a Loop class:

class Loop {
  //Constructor that accepts a function without parameters that returns Void
  new make(|,| body)
  {
    this.body = body
  }  

  Void unless(|->Bool| cond)
  {
     body.call()
     if (!cond()) unless(cond)
  }  

  |,| body
}

Then we use it in our code:

using fanExercise::Loop  

class Main
{
  static Void main()
  {
    Int i := 10
    Loop(|,|
	{
      echo("${i--}")
    })
    .unless |->Bool| {i == 0}
  }
}

We can see that the Fantom version is slightly more verbose than the Scala one (even if, as I said, maybe a good Fantom programmer could do better), but, as the dot is mandatory in method calls, I think it's less error prone.

Italian Agile Day 2009 - Le mie impressioni

Un altro Agile Day è passato ed eccomi nuovamente a scrivere un sommario della mia esperienza.

Peter Stevens - Fixed Price Projects With Agile – It can be done!

Possiamo stimare a priori tempi e costi di un progetto agile? Possiamo applicare i metodi agili quando il costo ed il tempo sono scolpiti nella pietra? Certo, sarebbe bello poter vivere in un mondo in cui tutti i contratti fossero tagliati sul concetto di iterazione, di sviluppo incrementale. Purtroppo ci sono occasioni nelle quali dobbiamo stimare i costi, nei quali dobbiamo sapere se riusciremo a rilasciare entro una certa data, magari remota. Chi, ad esempio, sviluppa il software per gestire grandi eventi come i mondiali di calcio non può chiedere di spostare la data della finale perché lavora in un team agile e ha bisogno di una nuova iterazione per completare le storie!

Peter Stevens ritiene che lo sviluppo agile si possa adattare a queste situazioni, anzi che sia il miglior metodo da adottare. Questo perché è l'unico sistema per valutare in corso d'opera la velocità alla quale lo sviluppo si sta svolgendo.


Waterfall

Per affrontare progetti di questo tipo occorre però:

  • un cliente del quale fidarsi;
  • una pianificazione che lasci "cuscinetti" liberi nei quali compensare eventuali ritardi;
  • criteri certi (e automatizzabili) per determinare quando una funzionalità è conclusa;
  • criteri per stabilire l'importanza delle varie funzionalità per realizzare prima le storie più importanti e consegnare alla fine del progetto, quando la pressione è maggiore e le energie si esauriscono, le funzioni di minor rilievo;
  • un team esperto.
  • Maggiori dettagli sulla presentazione si trovano qui.

Alberto Brandolini - Possiamo fare di meglio

La presentazione mattutina di Alberto Brandolini è partita da una serie di provocazioni ad effetto sui seguenti temi.

  • Spesso si rompe il rapporto di fiducia tra il software e chi lo usa, sia egli un utente finale o chi fa parte dello stesso team di sviluppo. Scatta allora il meccanismo della "complessità compensativa", cioè degli strani trucchi per aggirare i comportamenti errati dei sistemi.
  • A volte gli sviluppatori accettano passivamente i requisiti che sono dati loro: ma chi dà questi requisiti è il vero esperto del problema, o, se lo è veramente, ha avuto modo di pensare ai requisiti in maniera critica? I requisiti non sono in alcuni casi semplicemente la mummificazione di un processo che potrebbe essere invece migliorato?
  • Nei progetti software può nascere quello che è stato definito "technical debt". Brandolini suggerisce una metafora più calzante per questa progressiva deriva nella qualità del codice: inquinamento, ovverosia un processo estremamente dannoso, difficilmente reversibile e con un tempo di riparazione incalcolabile.
  • A volte lo sviluppatore non ha abbastanza umiltà per capire di dover approfondire il dominio da un punto di vista non semplicemente informatico.

Dopo aver introdotto questi spunti di discussione, Brandolni ha lasciato la parola all'uditorio. L'esito di questo esperimento di "terapia di gruppo" a mio avviso non è però stato brillantissimo: purtroppo non è emerso molto di interessante, se non una collezione di aneddoti sul nostro lavoro.

Pietro Brambati - ASP.NET MVC: Programming & Testing

Dato che prima del pranzo non mi sembrava vi fossero relazioni degne d'interesse, mi sono infilato nell'auletta dedicata alla presentazione dell'ambiente di test creato per .NET MVC. Io odio gli strumenti di sviluppo Microsoft!!! Questo mio sentimento nacque anni fa quando Visual Basic 6, con un fantastico "Il controllo OCX non è registrato correttamente", mi fece affogare in un oceano marrone nel bel mezzo di una demo ad un centinaio di persone. Nonostante questo, mi è sembrato che il supporto di Microsoft ai test unitari sia discreto e che l'oratore, molto preparato, sia riuscito a dare a i colleghi della sponda Microsoft un buon numero di informazioni utili su come scrivere codice in modo più efficace. L'impressione comunque è che con questo prodotto Microsoft stia svolgendo un diligente compitino per conquistarsi la medaglietta "agile" e la relativa fetta di sviluppatori.

Alberto Quario - Scenario testing

Questo è forse stato l'intervento più interessante della giornata. All'Agile Day si è molto parlato di processi, ma ci si è un poco scordati del codice. Alberto Quario ci ha riportati nel cuore del problema, citando le parole di Gerard Meszaros: I test possono diventare il collo di bottiglia dei processi agili. (Ma allora non le sparavo così grosse quando parlavo dei test come palle al piede!). Uno dei principi da seguire per evitare che i nostri test divengano dei mostri incomprensibili, difficili da scrivere, leggere e manutenere è il seguente: nel corpo del test deve andare tutto e solo quanto è strettamente necessario per la sua comprensione.

Alcuni consigli sono quindi:

  • radunare in metodi dal nome esplicito (operational methods) i dettagli di inizializzazione dello scenario del test
  • se il test prevede, come nel caso si utilizzi DBUnit l'uso di file di inizializzazione, magari in XML, parametrizzarne la creazione rendendone chiaro l'intento all'interno del test

Francesco Mondora: vivere in un angolo proattivo

Francesco Mondora nel corso della sua presentazione ha detto di apprezzare eventuali riscontri da parte del pubblico. Ecco quindi il mio, che è purtroppo negativo. Il tema trattato mi è apparso fumoso, ed il tono ieratico utilizzato era probabilmente fuori luogo. Ma forse il problema è solo mio che non sono riuscito a capire cosa si volesse comunicare...

Alberto Brandolini - Introduzione al Domain Driven Design

Ecco un'altra gran bella sessione, nella quale Brandolini ha descritto con abilità e preparazione i principi del Domain Driven Design.

Entrare nel dettaglio di quanto visto è molto difficile, data la mole di informazioni trasmesse. Mi piacerebbe comunque segnalare il concetto di Bounded context, ossia il limite entro il quale il significato di un'astrazione del dominio è non ambigua, o, per usare una visione più orientata al codice, il limite di applicabilità di un gruppo di classi del sistema. Mi sono imbattuto in questo problema quando, nella mia presentazione su Scala, ho parlato di oggetti che ingrassano a dismisura. Da quanto ho capito, anche nel DDD ci si occupa di questo problema, ma da una prospettiva "sistemica": occorre definire l'ambito entro il quale è opportuno riutilizzare il codice che definisce un'astrazione. All'esterno di tale ambito è meno costoso riscrivere parte delle astrazioni ed accettare una certa duplicazione nei sistemi. Il tema, interessante e complesso, è alla base del fallimento di grandi utopie Object Oriented come il progetto San Francisco di IBM. Anzi, a mio avviso mette in discussione tutti i miti dell'Object Orientation a partire dalla riusabilità, ma forse converrà parlarne in un'altra occasione.

Conclusioni

Anche quest'anno l'Italian Agile Day non ha deluso le aspettative: relazioni quasi tutte di altissimo livello, con l'apprezzabile idea di aprire a contributi internazionali. Se proprio si vuole fare un piccolo appunto, si dovrebbe parlare di un'eccessiva enfasi posta sugli aspetti di processo a scapito delle sessioni "pratiche", anche se, come avete potuto leggere, i "puri" sviluppatori come me non hanno avuto occasione di annoiarsi.

Grazie a Marco Abis ed ai ragazzi dell'XPUG Bologna per l'enorme e riuscitissimo sforzo organizzativo.
(Ah, avete già donato qualcosa all'Agile Day? ;-) )

Presentazione su Scala caricata su Slideshare

Ho deciso di provare il servizio di Slideshare pubblicando la presentazione su Scala che avevo tenuto presso l' XP-UG di bergamo qualche mese fa.

Implicit conversions in Scala are cool

Andy Warhol – Dollar sign

Sometimes I hear sentences like Domain Specific Languages (DSL) can be generated effectively only using dynamic languages, or This super-cool feature could not be possible in a static typed language. More and more, some people would transmit the idea that dynamic languages are agile and cool, while static ones are rigid and old. I strongly disagree! I think that in static languages lots of unit tests are generated and maintained automatically by the compiler, while in dynamic ones the programmer should create and maintain these tests. So static languages have lots more unit tests: isn't this agile programming? And what about cool features? Well, what do you think about a language in which you can write something like this?

 
(5.0 USD) + (2.0 USD) == (7.0 USD)

Cool DSL, isn't it? Sure, and I will show you that this is possible (and very easy) using a language with a strong and static type system: Scala.

As we are going to write yet another money example, we could begin with the definition of currencies.

 
abstract class Currency {
  def name: String;
  override def toString = name
}    
 
object Euro extends Currency {
  def name ="EUR"
}    
 
object Dollar extends Currency {
  def name = "USD"
}

Not very exciting. We simply define an abstract Currency class and two singleton objects that extend this class. Note that these objects are instances of anonymous subclasses of Currency. This does matter, as we'll see in a moment.

Now let's define money.

 
case class Money[C &lt;: Currency](amount: Double, currency: C) {
  def + (otherMoney: Money[C]) = {
    new Money(amount + otherMoney.amount, currency)
  }
  override def toString = amount + " " + currency
}

Our class is parametric in the type C, and we tell to the compiler that it must be a subclass of Currency. This way we have the nice consequence that the + operator can add only money of the same currency, and this test is done by the compiler before our code is running.

It's time to get to the cool feature: implicit conversion. So, in the same file Money.scala in which we defined the Money class, we create a Money object, which has the responsibility to convert doubles, let me say, "annotated" with a currency, into Money.

 
object Money {
  implicit def doubleConverter(d: Double) = new {
    def EUR = {
      new Money(d, Euro)
    }    
 
    def USD = {
      new Money(d, Dollar)
    }
  }
}

Uhm, it sounds a bit strange. How we can use it? Let's see an example.

 
import Money._    
 
object MoneyMainProgram extends Application {    
 
  val tenDollars = (4.0 USD) + (6.0 USD)     
 
  println(tenDollars)
}

Now some explanations are required.

In the first line we import the Money object. We can see it as a kind of static import, that, among other things, adds to the scope of our code all the implicit conversions defined in that object.

When we write 4.0 USD, we try to invoke the USD method on the 4.0 object, which is a double. Obviously there isn't such a method in the Double class, but the compiler, before giving up and throwing an error, tries to see if there is some way to convert the 4.0 in an object that does understand the USD method. Luckily we have imported the doubleConverter which takes a Double and transforms it in an instance of an anonymous class with a USD method: bingo! So the compiler transforms our code in something like this:

 
  doubleConverter(4.0).USD()

But what is the result of this expression? Well, it's an instance of the Money class expressed in Dollar. This class has the + method that we can use to add another Money in the same currency. Cool!

Let's take a look to our work. We needed to add some features to the Double class. In some dynamic languages we could monkey patch this class. In Scala we did it using a dynamic conversion from Double to a class with the methods we need, so we reached the same purpose in a static and safer way.

And so, an old fashioned static language could have such cool features? It seems....

Presentazione su Scala all’XP User Group di Bergamo

Ieri, 29 maggio 2009, ho tenuto una breve presentazione sul linguaggio Scala alla riunione dell'XP User Group di Bergamo. Parlare con delle persone brillanti come gli amici dell'XP-UG-BG è stato veramente una bella esperienza. L'unico mio rammarico è quello di non essere stato in grado di creare una presentazione sufficientemente chiara. Come sempre, la cosa più complessa è essere semplici! Il principio KISS è il più difficile da seguire. Spero comunque di poter fare meglio la prossima volta.

Ruby in Scala

Ok, il titolo del post è volutamente iperbolico, ma dovete sapete che amo gli eccessi! ;-)
Comunque tutto nasce da un post sulla lista dello Scala User Group italiano.
Partendo da un articolo su Scala di Daniel Spiewak, si mettono a confronto un frammento di codice Scala

 
  def fillColor_=(fillColor:Color) = {
    if (!fillColor.equals(Color.RED)) {
      theFillColor = fillColor
    } else {
      throw new IllegalArgumentException("Color cannot be red")
    }
  }

con un (quasi) equivalente Ruby

 
  def fill_color=(color)
    raise "Color cannot be red" if color == Color::RED  
 
    @fill_color = color
  end

che è sicuramente più piacevole da leggere.

Ricordiamoci però che uno degli aspetti più interessanti di Scala è la facilità con cui è possibile creare DSL. Vediamo come possiamo in qualche modo mimare la sintassi del raise Ruby.

Definiamo prima l'oggetto RubySyntax (va bene, va bene, il nome è un po' pretenzioso, ma a me piace scherzare, dai...)

 
object RubySyntax {   
 
  def raise(exceptionText: String)(condition: => Boolean): Unit = {
    if (condition) {
      throw new IllegalArgumentException(exceptionText);
    }
  }   
 
}

Quindi lo possiamo usare in una qualsiasi altra parte del nosto codice:

 
import RubySyntax._   
 
object RubySyntaxTest {   
 
  def main(args:Array[String]) = {
    val language = "Ruby"   
 
    raise ("Language cannot be Ruby") { language.equals("Ruby") }
  }   
 
}

Certo, ci sono delle parentesi in più, ma abbiamo eliminato l'if. E poi sono convinto che voi sapreste fare di meglio! (Ovviamente in Scala).
Ancora dubbiosi su quale linguaggio scegliere? ;-)

Pleasures of boilerplate code

In a very interesting interview, Martin Odersky said that Scala could be a little more difficult than Java for newcomers because in it you have not to write boilerplate code, but you have to think at your problem just from the first line of code. In some way, boilerplate code could be a kind of "warming up" for beginners. Writing some code, even if it's only syntactic noise, could give confidence to the programmer, generating a feeling of accomplishment.

But, is there a way to warm up without writing silly code? The best way of doing this is with unit testing. In TDD by example , Kent Beck describes "Starting tests": Start by testing a variant of an operation that doesn't do anything. Using these tests, not only you can start exploring your design, but you can also break the "white sheet syndrome".

Nasce lo Scala User Group italiano

Su iniziativa di Lorenzo Bolzani, nasce lo Scala User Group italiano. Era ora! Per il momento il gruppo gravita su Milano, speriamo comunque che cresca e dia buoni frutti.