Le nostre competenze a vostra disposizione sul blog
Amiamo il nostro lavoro e vogliamo condividerlo con voi! Tenetevi aggiornati su tutte le news e le tecnologie con le quali lavoriamo e di cui potreste avere bisogno! Seguite il nostro blog.
×

Error message

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.
mattia.minotti's picture

In informatica, la stragrande maggioranza dei linguaggi di programmazione è general-purpose, questo perchè sono progettati in modo da permettere di scrivere software per ogni genere di dominio applicativo. In alternativa, in alcuni contesti, esistono linguaggi cosiddetti domain-specific che sacrificano la loro generalità in cambio di una maggior espressività. I linguaggi di questa seconda categoria, tra i quali ne troviamo di particolarmente famosi come HTML o SQL, hanno il grande vantaggio di permettere al programmatore di progettare le sue soluzioni con astrazioni che sono più vicine al dominio del problema che deve risolvere.

Linguaggi Domain Specific

Sebbene i linguaggi domain-specific siano sempre esistiti nel panorama informatico, essi sono sempre stati confinati a domini di specificità e dimensioni macroscopiche. Fino a qualche tempo fa non era auspicabile investire tempo nella creazione di un linguaggio se non se ne prevedeva un utilizzo stabile o duraturo da un insieme consistente di programmatori, altrimenti il gioco non valeva la candela. Recentemente, però, nuove correnti dell’ingegneria del software, supportate da tecnologie emergenti in questo settore, hanno permesso di ridurre l’impatto che la creazione di un nuovo linguaggio può avere sull’economia di un progetto. Questo ha reso la creazione di linguaggi domain-specific uno strumento molto potente, se utilizzato con criterio.

Dal punto di vista concettuale, creare un linguaggio per uno specifico dominio applicativo, coincide con la determinazione di un modello informatico che sia astrazione delle entità che costituiscono quel dominio. Proviamo a fare un esempio estremamente semplificato: prendiamo in considerazione un dominio applicativo come quello di una fattoria di animali, un suo modello minimale potrebbe essere composto da:

  • Il fattore, gestore della fattoria.
  • Uno o più animali, più nel dettaglio maiali, pecore e galline.
  • Uno o più recinti in cui vivono diversi animali.

La descrizione a parole di cui sopra non è altro che una rappresentazione informale di un modello. Un’alternativa potrebbe essere la seguente:

Model :
    farmhouse=Farmhouse;

Farmhouse:
    ‘farmer’ ‘:’ Farmer
    ‘fences’ ‘[‘ (fences += Fence)* ‘]’
 
Farmer:
    STRING

Fence:
    ‘fence’ ‘{‘ (animals += Animal)* ‘}’

Animal:
    Pig | Sheep | Hen;

Pig: ‘pig’

Sheep: ‘sheep’

Hen: ‘hen’

Quanto scritto sopra è invece la definizione di un linguaggio che fa riferimento allo stesso modello espresso in precedenza (per la precisione, si tratta di una definizione formale di una grammatica scritta per la tecnologia Xtext di Eclipse). Un esempio di istanza di questo linguaggio, e quindi di un’istanza di questo modello, è il seguente:

farmer: ‘Mr Smith’
fences: [
    fence { pig pig pig }
    fence { sheep sheep sheep sheep hen hen hen }
    fence { hen hen hen hen hen }
]

In esso si definisce una fattoria del fattore Mr Smith, con tre recinti: il primo con 3 maiali, il secondo con 4 pecore e 3 galline, il terzo con 5 galline.

La connessione tra linguaggio e modello è fondamentale perchè permette di capire che la definizione di un linguaggio domain-specific per un determinato ambito applicativo equivale ad individuare un suo modello, che è uno degli obbiettivi (o forse l’obbiettivo principale) del processo di analisi dell’ingegneria del software. Ciò che un linguaggio domain-specific offre, inoltre, è la possibilità di definire altre istanze del problema in maniera agile e “rigorosa”.

Generazione di Codice

In TwinLogix abbiamo da sempre apprezzato la filosofia dei linguaggi domain-specific, ma abbiamo anche cercato di fare un passo ulteriore e capire come conciliarla con un approccio più pragmatico, orientato alle esigenze e ai tempi aziendali. A questo scopo, abbiamo sperimentato l’utilizzo di due tecnologie, sviluppate inizialmente come Eclipse Project e poi distribuite all’interno dell’Eclipse Modeling Framework, per la definizione di linguaggi e la generazione di codice: Xtext e Xtend.
Questi due framework forniscono tutte le funzionalità per la creazione di un proprio linguaggio e la definizione delle regole di generazione per trasformare le frasi della propria grammatica in un qualsiasi linguaggio general purpose come Java, Objective C, C++, ecc. In questo modo, il passaggio tra la definizione del problema nel linguaggio domain-specific e l’implementazione del linguaggio target è sostanzialmente automatico e preso in carico dal generatore di codice che viene sviluppato una volta sola.
Eclipse, inoltre, permette di generare i plugin necessari all’integrazione delle funzionalità sviluppate con Xtext ed Xpand direttamente nel suo IDE, rendendone l’utilizzo semplice e veloce. A integrazione completata, è possibile creare nei propri progetti uno o più file con istanze del modello Xtext e, automaticamente, Eclipse genera i relativi sorgenti nel linguaggio target.

L’approccio a generazione di codice, secondo la nostra esperienza, fornisce una serie di vantaggi apprezzabili:

  • Riduzione del tempo di sviluppo di componenti software ricorrenti, con una struttura generalizzabile.
  • Minor probabilità di errore sulle porzioni di codice generato: una volta costruito il sistema, gli errori sulle parti generate automaticamente diventato sostanzialmente nulli.
  • Uniformità del codice: la porzione di codice generata è ovviamente sempre conforme al generatore e quindi ad uno standard predefinito.
  • Modifiche e i bugfix al codice, se applicate al generatore, vengono propagate automaticamente alla successiva generazione.
  • Possibilità di scrivere componenti comuni a parti del sistema in diversi linguaggi, definendole una sola volta e riducendo notevolemente i tempi di sviluppo. Ad esempio la definizione di un’entità in Java, iOs, C++ può essere fatta scrivendola una sola volta nel linguaggio domain-specific e generando le varie versioni.
  • Minor frustrazione per sviluppi ripetitivi (mai da trascurare, perchè gli sviluppatori son pur sempre persone!).

Per concludere, aggiungerei un paio di dati di esempio che possono essere utili a dare un’idea della portata dei concetti di cui sopra.
La nostra normale implementazione di un servizio REST di media complessità, in linguaggio Java e sviluppato tramite il framework Spring MVC 3.2, conta circa 4100 linee di codice. Attualmente, sfruttando al massimo la generazione di codice, siamo arrivati a generarne automaticamente più di 3850, definendo un modello di circa 240 linee e dovendo comunque scrivere alcune parti specifiche a mano, circa 250 linee di codice. Siamo passati in pratica dall’implementare 4100 linee di codice ad appena 500, circa un 88% in meno!

Aggiungi un commento

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.