Как временно определить условие внутри блока?

В Общий Лисп (в частности, в моем случае СБКЛ) принято определять исключения (известные как «условия») с помощью макроса определить-условие. Это определяет условие глобально в текущем пакете.

Есть ли способ определить условие локально в определенной области? Или, в качестве альтернативы, какой-то другой идиоматический способ преждевременного выхода из области видимости со значением, не загрязняя глобальное пространство имен?

(with-conditions
  (block
    (...)
    (prematurely-exit-block-with some-data)
    (...))
  (when-condition-happens (some data) ...))

Видимо то, что я ищу, это throw, catch и, возможно, block ;)

Sod Almighty 27.05.2019 19:09

Возможно, вы ищете block / return-from.

user5920214 27.05.2019 23:11

Вы почти всегда хотите лексическую область видимости (т.е. block или tagbody), а не динамическую область видимости (throw и catch)

Dan Robertson 28.05.2019 23:14
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
2
3
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Is there a way to define a condition locally, within a specific scope?

Нет.

Or, alternatively, some other idiomatic way to prematurely exit a scope with a value, without polluting the global namespace?

В Common Lisp есть несколько конструкций для такого потока управления, где возвращается одно или несколько значений: RETURN, RETURN-FROM, THROW, ...

  • RETURN возвращается от блокировать с именем NIL
  • RETURN-FROM возвращается от имени блокировать
  • THROW переходит к тегу catch, установленному через CATCH

return и return-from используют лексические блоки. catch устанавливает динамическую область для своего тега.

Ради всех, кто найдет этот ответ с помощью поиска, я хочу добавить, что все эти механизмы возвращают управление вверх по стеку, однако обычная система условий Common Lisp не раскручивает стек до тех пор, пока в обработчике не будет вызван перезапуск (хотя эта функция кажется, не тот, который искал спрашивающий в этом случае).

Dan Robertson 28.05.2019 23:18

Другие вопросы по теме