Literate Configuration per Emacs
Che cosa si intende con Literate Configuration?
Partiamo dalle definizioni. La Literate Configuration è una applicazione del concetto di Literate Programming.
E che cos’è la Literate Programming, o “programmazione letterale” se proprio vogliamo trovare una traduzione in italiano? È un paradigma di programmazione inventato da Donald Knuth dove il codice sorgente viene introdotto all’interno di un documento scritto in un linguaggio naturale e, tramite appositi software, estratto per generare il codice sorgente vero e proprio.
Possiamo vedere questo metodo come l’inverso di quanto siamo abituati a fare normalmente, ovvero scrivere il codice sorgente ed all’interno inserire i blocchi di commento che possono essere estratti per generare la documentazione.
Questo paradigma è interessante più da un punto di vista accademico che non pratico, però nel caso di brevi script o per i file di configurazione, come appunto quelli di Emacs, può essere un sistema molto valido per tenere ben organizzata la documentazione ed i sorgenti.
In ambito Emacs il tutto è faciliato da Org-mode che rende questo sistema estremamente facile da gestire.
Quando e perché usare la Literate Configuration?
Attualmente sto usando questo sistema per la gestione dei file di configurazione di Emacs che, nel corso del tempo sono diventati abbastanza lunghi con numerose funzioni personalizzate.
I classici commenti stavano cominciando a starmi stretti perché in molti casi, essendo molto prolissi visto che dovevano servire per capire i motivi di certe scelte, rendevano la lettura del codice abbastanza difficoltosa. Inoltre in alcuni casi la stessa funzionalità aveva bisogno di codice in più file distinti, rendendo ancora più difficile mettere assieme i pezzi.
Adottando la Literate Configuration ho risolto tutti i problemi che avevo perché mi sono concentrato sullo scrivere la documentazione dei parametri usati e delle funzioni. I frammenti di codice hanno dei meta dati che poi vengono usati dal generatore del sorgente per creare i singoli file distinti, ma visivamente, nella documentazione, è tutto raggruppato.
Esempio di Literate Configuration per Emacs
Partiamo dal presupposto che Org-mode sia un concetto già noto al lettore, se così non fosse rimando al sito ufficiale .
Normalmente è possibile inserire un blocco di codice con la seguente sintassi:
#+begin_src python
x = 1
if x == 1:
print ("x is 1.")
#+end_src
A differenza del linguaggio markdown, dove i blocchi di codice vengono gestiti tramite il tag ```
, in Org-mode si usano #+begin_src
e #+end_src
per identificare l’inizio e la fine del codice sorgente.
Abbiamo poi un secondo parametro, in questo esempio python
che indica il linguaggio usato. Ciò serve sia per il syntax highlight, che per l’eventuale interpretazione del codice stesso nel caso dovesse servire eseguirlo.
A questo punto la generazione del file sorgente a partire dal documento scritto in Org-mode è molto facile: basta specificare nel blocco di codice il file di destinazione in cui il codice dovrà essere inserito.
Per farlo si aggiunge il parametro :tangle
seguito dal file di destinazione.
#+begin_src emacs-lisp :tangle config.el
(with-eval-after-load 'ox (require 'ox-hugo))
#+end_src
In questo esempio il codice (with-eval-after-load 'ox (require 'ox-hugo))
verrà inserito nel file config.el
.
Per estrarre il codice sorgente e generare i file di destinazione si usa il comando org-babel-tangle
(scorciatoia predefinita: C-c C-v t
) che in sequenza prenderà tutti i blocchi di codice e li concatenerà nei rispettivi file di configurazione.
Per non dover eseguire manualmente il comando di esportazione è possibile aggiungere un hook che esegue org-babel-tangle
al salvataggio del file. Ecco il codice:
#+begin_src emacs-lisp :tangle config.el
(add-hook 'org-mode-hook
(lambda () (add-hook 'after-save-hook #'org-babel-tangle
:append :local)))
#+end_src
Perché la Literate Programming non ha preso piede?
Prima di cominciare ad usare Emacs ed Org-mode, non avevo praticamente mai sentito parlare della Literate Programming, come mai?
Il motivo è abbastanza semplice: nella stragrande maggioranza dei casi è un approccio non ottimale, soprattutto in ambito professonale.
L’idea che sta alla base di questo paradigma, seppur molto valida ed interessante, è nata in un periodo storico in cui le tecnologie di programmazione non erano evolute come oggi e quindi le necessità di documentazione del codice erano ben diverse da oggi. In poco tempo i linguaggi e le metodologie di sviluppo hanno trovato delle soluzioni decisamente più pratiche come appunto la generazione della documentazione a partire dai sorgenti (e dai commenti), rendendo di fatto obsoleta la Literate Programming.
Le esigenze stesse di programmazione, con codice modulare, plugin ecc rendono estremamente complicata l’adozione della Literate Programming che quindi non ha mai preso piede tra i programmatori.
Possibili applicazioni oltre alla configurazione di Emacs
I casi d’uso sono quindi molto ristretti. All’interno di Emacs è comodo scrivere così la configurazione e in futuro voglio fare qualche esperimento, magari quando dovrò scrivere qualche piccolo script di sistema, giusto per vedere se poi, a distanza di tempo, la documentazione sarà più chiara: partendo dalla documentazione si dovrebbe essere maggiormente stimolati a scrivere una spiegazione esaustiva del codice e maggiormente comprensibile anche a distanza di tempo.