Поскольку синтаксис для IF (<- ссылка HyperSpec) определен как: </p>
if test-form then-form [else-form] => result*
Нет маркеров начала и конца. Существует THEN-FORM, а не THEN-FORM *.
PROGN - это механизм для определения последовательности форм, где формы выполняются слева направо и возвращаются значения последней формы.
Это можно было бы определить так:
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))
Ну, уже есть конструкция, которая поддерживает несколько форм: COND.
(cond ((> (random 10) 5)
(print "high")
:high)
(t
(print "low")
:low))
Типичным стилем является использование COND, когда нужно попробовать несколько альтернатив и когда есть несколько тогда / else-форм. IF используется, когда есть только один тест, а также форма then и else. Для других случаев есть WHEN и UNLESS. WHEN и UNLESS поддерживают только одну или ТО одну форму (никакие другие формы).
Полагаю, хорошо иметь хотя бы одну условную форму (если в этом случае), которая не содержит слоев скобок. Запись
(if (> (random 10) 5)
(progn
(print "high")
:high)
(progn
(print "low")
:low))
- это небольшая цена, которую нужно заплатить. Либо напишите дополнительные PROGN, либо переключитесь на вариант COND.
Если ваш код действительно выиграл бы от IF с множественными формами then и else, просто напишите этот макрос (см. Выше). В Лиспе он есть, так что вы можете быть вашим собственным языковым дизайнером. Важно подумать о введении макроса: мой макрос правильный? это проверяет ошибки? стоит ли оно того? это читабельно (для других?)?