Scrivere funzioni newLisp auto-commentate

11 07 2009

google_translate.gif Translate To English!

Introduzione

Una cosa che mi piacque molto quando studiai per la prima volta Rebol (un bellissimo linguaggio di programmazione funzionale, creato da Carl Sassenrath), è che si potevano inserire dei commenti all’interno delle funzioni stesse. Cercherò di essere un pò più chiaro. Normalmente, se scrivo un programma in Java (ma anche in C, Pascal, Basic, etc…) scrivo i commenti alle funzioni in un modo simile al seguente:

/* Questo è il commento alla mia  bellissima funzione */
function miaFunzione() {
   faccioQualcosa();
}

Il commento (quello in mezzo ai simboli /*  */ ), anche se posto sopra alla funzione stessa, è però staccato, indipendente da essa, sotto ogni punto di vista. Solo utilizzando programmi esterni (come javadoc) si può allora generare della documentazione che “colleghi” il commento alla funzione. Inoltre, se spostassi la funzione, o la mettessi in un altro programma, potrei anche dimenticare di copiare il suo commento. Nei linguaggi funzionali come newLisp e Rebol, possiamo però sfruttare la loro omoiconicità per inserire il commento all’interno della funzione stessa. Questo ci porterà notevoli vantaggi:

  1. Se copio / sposto la funzione, il commento verrà copiato con essa, sempre.
  2. Molti linguaggi di scripting (compreso newLisp) hanno una comoda console per impartire i comandi. Questo significa che, si possono realizzare dei comandi ad-hoc, per leggere tali commenti, direttamente dalla funzione stessa, e senza ricorrere a programmi esterni (simili a javadoc).
  3. Il commento (e la documentazione in genere), non essendo necessario estrarlo con tools esterni, sarà sempre aggiornato (non rischio di avere una funzione X ma con un commento estratto Y – più vecchio della funzione stessa, solo perchè non ho rilanciato il comando di aggiornamento della documentazione).
Passiamo alla pratica

Ora che ho chiarito (spero!) un pò meglio la mia idea, cerchiamo di capire come metterlo in pratica usando il nostro newLisp. Prima di tutto scriviamo una funzione molto semplice:

(define (somma-valori argValore1 argValore2)
   (println (+ argValore1 argValore2) )
)
>> (somma-valori 10 20)
30

Bene, ora che ho la funzione, inseriamo un breve commento per spiegare il suo funzionamento. Lo possiamo fare in diversi modi, in base al numero di informazioni (e al tipo) da mettere. Il sistema più semplice è inserire una stringa che contenga il commento (ma newLisp ci permetterà di fare ben altro!):

(define (somma-valori argValore1 argValore2)
   "Questa funzione addiziona due numeri interi."
   (println (+ argValore1 argValore2) )
)

La possibilità unica nel suo genere che hanno i linguaggi omoiconici è che il codice (il programma vero e proprio) e i dati sono in realtà la stessa cosa, quindi newLisp non si “scandalizza” se, nel bel mezzo di un programma, inseriamo una stringa, senza chiamare funzioni, senza assegnazioni! Ma ora arriva la parte più interessante: proprio perchè in newLisp i dati sono codice, ed il codice sono dati, possiamo manipolare la nostra funzione come una lista qualunque, quindi:

>> (nth 1 somma-valori)
"Questa funzione addiziona due numeri interi."

Meraviglioso! Abbiamo potuto estrarre il commento dalla funzione! Ora guardate qui… create nel vostro ambiente newLisp (dalla console) questa funzione:

(define (helpme argFunction)
   (nth 1 argFunction)
)

Ora provate a digitare:

>> (helpme somma-valori)
"Questa funzione addiziona due numeri interi."

Fantastico! Basta quindi stabilire uno standard ed avremo, gratis (  :-)  ) , un comodo sistema di help online! Ma allora, perchè fermarci qui? Proviamo in questo modo:

(define (somma-valori argValore1 argValore2)
   (
      (comment "Questa funzione addiziona due numeri interi.")
      (version 1.1)
      (last-update "2009-07-01")
   )
   (println (+ argValore1 argValore2) )
)

Il nostro semplice commento, scritto sottoforma di stringa, ora è diventato una lista, contenente dei “tag” (comment / version / last-update) rileggibili dalla nostra funzione di help:

(define (helpme argFunction)
   ( println "DESCRIPTION: " (lookup 'comment (nth 1 argFunction)) )
   ( println "VERSION    : " (lookup 'version (nth 1 argFunction)) )
   ( println "LAST-UPDATE: " (lookup 'last-update (nth 1 argFunction)) "\n" )
)

>> (helpme somma-valori)
DESCRIPTION: Questa funzione addiziona due numeri interi.
VERSION    : 1.1
LAST-UPDATE: 2009-07-01

I vantaggi di un metodo simile sono evidenti: se aggiungessimo anche una funzione per indicizzare le funzioni scritte (quindi potendo anche cercarle scrivendo solo una parte del loro nome), allora avremo un ambiente di sviluppo e test di prim’ordine!

Anche stavolta siamo quasi alla fine. Spero che l’articolo possa fornirvi spunti utili al vostro lavoro e divertimento!

A presto!


Azioni

Informazione

Lascia un commento