cond - многовариантное условие

(cond ('any1 . prg1) ('any2 . prg2) ..) -> any
Если любое из условий anyN
не равно NIL
, выполняется prgN
и возвращается результат. В противном случае (все условия равны NIL
) возвращается NIL
.
См. также nond when and if if2
Пример
: (cond
((= 3 4) (println 1))
((= 3 3) (println 2))
(T (println 3)) )
2
-> 2
https://software-lab.de/doc/refC.html#cond
Третье условие T
(аналог else
) не проверяется, так как уже найдено истинное.
Аналог в JS
if (condition1) { action1(); }
else if (condition2) { action2(); }
else { actionN(); }
Код определения
(NIL "cond" _Cond)
glob.l
# (cond ('any1 . prg1) ('any2 . prg2) ..) -> any
(de _Cond (Exe) */ Принимает один аргумент Exe — список условий и действий в формате cond
(let X Exe */ Создаёт локальную копию списка условий Exe в переменной X
(loop */ Запускает бесконечный цикл (прерывается только при выполнении условия или конце списка)
(? (atom (shift X)) $Nil) */ Проверяет, является ли элемент атомом (признак конца списка), (shift X) извлекает и удаляет первый элемент из X. Если X пуст (достигнут атом), возвращает $Nil (ложь).
(let Y (car X) */ Берёт первый оставшийся элемент X (это пара (условие . действие)).
(? (not (nil? (eval (car Y)))) */ проверяет, что условие не NIL (т.е. истинно). (car Y) — извлекает условие из пары и (eval ...) — вычисляет условие.
(set $At @) */ Сохраняет результат вычисления условия в глобальную переменную $At (можно использовать позже).
(run (cdr Y)) */ Если условие истинно, выполняет действие (все выражения после условия).
) ) ) ) )
llvm~_Cond (634 "src/flow.l" llvm pico)
llvm~cond (1314 "src/lib/llvm.l" llvm pico)
pico~cond (634 "src/flow.l" llvm pico)
Особенности реализации
Рекурсия через цикл
Вместо рекурсии используетсяloop
+shift
, что эффективнее по памяти.Сохранение результата
Переменная$At
хранит последнее вычисленное условие (может быть полезно для отладки).Гибкость
Поддерживает любое количество условий и действий, включаяT
(всегда истинно). Используетeval
и динамические переменные ($At
).
Как видим, небольшой (!?) список зависимостей - not nil? loop let run cdr car shift set atom eval
P.S. Определение небольшое и я решил посмотреть как может выглядеть “полное описание“ функции. Кажется “погорячился” с комментариями в коде определения. Надо как-то по-другому сделать в следующий раз на примере другой “небольшой“ функции.
Subscribe to my newsletter
Read articles from Sergey Shishkin directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sergey Shishkin
Sergey Shishkin
Всегда чему-то учусь!