Lisp – una libreria per i pathnames – 1

b1lPortabile, dice Peter, ho tolto l’aggettivo nel titolo ma sì, certo.
L’astrazione fornita da Common Lisp per i pathnames è vecchia, troppo generica e allora eccone una nuova, non è difficile farla, pronti? via!

L’API

Le operazioni base della libreria saranno di determinare la lista dei files in una directory e determinare se un file o una directory esiste. Si passerà poi a percorrere ricorsivamente una directory, chiamando una funzione per ogni pathname nell’albero.

In teoria queste funzioni già ci sono, sono le funzioni standard directory e probe-file. Ma noi faremo di meglio 😉

*features* e read-time conditionalization

Prima di passare all’implementazione di questa API dobbiamo vedere il meccanismo per scrivere codice implementation-specific.

Nota: il solito problema mio con le traduzioni dei termini tecnici. Siccome questi post hanno pochissime visite non mi preoccupo più di tanto. Lo scopo principale è che pubblicando quanto leggo sono costretto a chiarirmi le cose. Poi c’è sempre la versione originale. E devo proprio compralo il libro di carta 😀

C’è il solito problema che qualunque codice portabile avrà bisogno di alcune parti specifiche per l’implementazione corrente. Per permettere ciò il Common Lisp fornisce un meccanismo chiamato read-time conditionalization che consente di includere codice condizionalmente.

Il meccanismo consiste di una variabile *features* e due aggiunte extra alla sintassi del Lisp reader. *features* è una lista di simboli ognuno dei quali rappresenta una caratteristica che è presente nell’implementazione o nella sottostante piattaforma.

l15-0

Questi simboli sono usati in feature expressions che ritornano vero o falso a seconda della loro presenza o meno nella lista. L’espressione più semplice è un singolo simbolo; l’espressione è vera se il simbolo c’è, falsa altrimenti. Altre espressioni sono costruite con gli operatori not, and e or. Per esempio se si vuol condizionare qualche codice alla presenza di foo e bar si scrive la feature expression (and foo bar).

La lista iniziale di *features* è dipendente dall’implementazione come pure che funzionalità sono presenti. Tuttavia ogni implementazione include almeno un simbolo che identifica l’implementazione. Per esempio Allegro Common Lisp include il simbolo :allegro, CLISP include :clisp, SLBC (il mio) e CMUCL includono :cmu. Verifico:

l15-1

Per evitare dipendenze nei packages (non ancora visti) che possono essere presenti o meno i simboli in *features* sono usualmente keywords e il reader collega *package* alla keyword package quando legge le espressioni di feature. Quindi un nome senza qualificazione di package sarà letto come simbolo. Così si può scrivere una funzione che si comporta in modo leggermente diverso per ognuna delle implementazioni menzionate, così:

(defun foo ()
  #+allegro (do-one-thing)
  #+sbcl (do-another-thing)
  #+clisp (something-else)
  #+cmu (yet-another-version)
  #-(or allegro sbcl clisp cmu) (error "Not implemented"))

In Allegro il codice sarà letto come se fosse stato scritto così:

(defun foo ()
  (do-one-thing))

mentre per SBCL:

(defun foo ()
  (do-another-thing))

Per un’implementazione non specificatamente menzionata risulterà:

(defun foo ()
  (error "Not implemented"))

Poiché la conditionalization (condizionalizzazione) avviene nel reader, il compilatore non vede le espressioni che sono state saltate. Questo vuol dire che a runtime non c’è differenza ad avere diverse implementazioni. E anche, quando il reader salta le espressioni condizionalizzate non si preoccupa dei simboli dipendenti dalle altre implementazioni (circa, pasticcio mio qui).

Qui Peter mette un box relativo al suo package (com.gigamonkeys.pathnames). Lo salto, non sono ancora arrivato ai packages. Ci tornerò se sorgeranno problemi :mrgreen:

Pausa 😀

Posta un commento o usa questo indirizzo per il trackback.

Trackback

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: