Un motivo per cui le lingue basate su Algol incoraggiano le parentesi sulla propria linea è di incoraggiare l'aggiunta di più linee tra le parentesi delimitanti senza dover spostare le parentesi. Cioè, se uno inizia con
if (pred)
{
printf("yes");
}
è facile venire avanti e aggiungere un'altra istruzione tra parentesi:
if (pred)
{
printf("yes");
++yes_votes;
}
La forma originale era stata
if (pred)
{ printf("yes"); }
quindi dovremmo avere "spostato" due parentesi, ma il mio esempio è più interessato a quest'ultimo. Qui, le parentesi stanno delimitando cosa si intende per una sequenza di istruzioni , principalmente invocata per effetto collaterale.
Al contrario, Lisp manca di dichiarazioni; ogni forma è espressione , dando qualche valore, anche se in alcuni rari casi (pensando a Common Lisp), quel valore viene scelto deliberatamente come "nessun valore" tramite un (values)
modulo. È meno comune trovare sequenze di espressioni , al contrario di espressioni nidificate . Il desiderio di "aprire una sequenza di passaggi fino al delimitatore di chiusura" non si pone più spesso, perché quando le dichiarazioni scompaiono e i valori restituiti diventano una valuta più comune, è più raro ignorare il valore di ritorno di un'espressione, e quindi più raro valutare una sequenza di espressioni solo per effetto collaterale.
In Common Lisp, il modulo progn
è un'eccezione (come lo sono i suoi fratelli ):
(progn
(exp-ignored-return-1)
(exp-ignored-return-2)
(exp-taken-return))
Qui, progn
valuta le tre espressioni in ordine, ma scarta i valori di ritorno dei primi due. Potresti immaginare di scrivere quell'ultima parentesi chiusa sulla propria linea, ma nota nuovamente che poiché l'ultima forma è speciale qui (non nel senso comune di Lisp di essere speciale , però), con un trattamento distinto, è più probabile che si aggiungano nuove espressioni nel mezzo della sequenza, piuttosto che solo "aggiungendo un altro alla fine", poiché i chiamanti sarebbero quindi interessati non solo da nuovi effetti collaterali, ma piuttosto da un probabile cambiamento nel valore di ritorno.
Facendo una semplificazione grossolana, le parentesi nella maggior parte delle parti di un programma Lisp stanno delimitando gli argomenti passati alle funzioni, proprio come nei linguaggi di tipo C, e non che delimitano i blocchi di istruzioni. Per gli stessi motivi tendiamo a mantenere le parentesi che delimitano una chiamata di funzione in C vicino agli argomenti, così facciamo lo stesso in Lisp, con meno motivazione a deviare da quel raggruppamento chiuso.
La chiusura delle parentesi è molto meno importata della rientranza del modulo in cui si aprono. Col tempo, si impara a ignorare le parentesi e si scrive e si legge per forma, proprio come fanno i programmatori Python. Tuttavia, non lasciare che questa analogia ti porti a pensare che rimuovere le parentesi sarebbe valso la pena. No, si tratta di una discussione salvata per comp.lang.lisp
.