Poiché la sintassi per IF (< - HyperSpec link) è definita come:
if test-form then-form [else-form] => result*
Non esistono iniziano o marcatori finali. Esiste un ALLEGATO e non ALLORA-FORM *. PROGN è un meccanismo per definire una sequenza di moduli, in cui i moduli vengono eseguiti da sinistra a destra e vengono restituiti i valori dell'ultima forma.
avrebbe potuto essere definita in questo modo:
my-if test-form (then-form*) [(else-form*)] => result*
(defmacro my-if (test then &optional else)
(assert (and (listp then) (listp else)) (then else))
`(if ,test (progn ,@then) (progn ,@else)))
(my-if (> (random 10) 5)
((print "high")
:high)
((print "low")
:low))
bene, c'è già un costrutto che supporta molteplici forme: COND.
(cond ((> (random 10) 5)
(print "high")
:high)
(t
(print "low")
:low))
Lo stile tipico è quello di utilizzare COND quando più alternative devono essere provato e quando ci sono più then/else-forme. IF viene usato quando c'è un solo test e sia un modulo then che un altro. Per altri casi c'è WHEN e UNLESS. WHEN e UNLESS supportano solo una o THEN forme (nessuna altra forma (s)).
Immagino sia meglio avere almeno una forma condizionale (SE in questo caso) che non abbia aggiunto livelli di parentesi. Scrivere
(if (> (random 10) 5)
(progn
(print "high")
:high)
(progn
(print "low")
:low))
è quindi un piccolo prezzo da pagare. Scrivi i PROGN aggiuntivi o passa alla variante COND. Se il tuo codice trarrebbe vantaggio da IF con più moduli then e else, allora scrivi quella macro (vedi sopra). Lisp lo ha, in modo che tu possa essere il tuo designer di lingue. È importante però pensare all'introduzione di una macro: la mia macro è corretta? controlla gli errori? ne vale la pena? è leggibile (per gli altri?)?
fonte
2009-03-11 12:31:11
Ma (quando) e (tranne) non hanno altri rami. –