Динамические нелокальные выходы в Common Lisp - PullRequest
0 голосов
/ 09 июня 2018

В соответствии с Динамическими нелокальными выходами секции Common Lisp the Language, 2-е издание ,

Промежуточные выходыпокинуты, как только начинается передача контроля;в случае броска это происходит в начале «второго прохода», упомянутого в примечании к реализации.Ошибка при попытке передачи управления на выход, динамический экстент которого закончился.

Однако в SBCL 1.3.4:

(catch 'a
  (catch 'b
    (unwind-protect
         (throw 'a "returning from protected")
      (throw 'b "returning from unwind"))))
;; => "returning from unwind"

Это кажется неверным.Не следует ли завершить точку выхода 'b между выполнением защищенной формы и формы очистки, что делает вышеуказанное незаконным?Пример гребли на лодке на той же странице предполагает то же самое.

Поведение SBCL вместо этого, кажется, соответствует альтернативному предложению:

... отказ от выходов должен быть сосредоточен нас оценкой unwind-protect пунктов очистки и отменой динамических привязок и тегов перехвата, выполняющих все в обратном порядке создания.

Является ли это просто тем, что CLtL2 отличается от окончательной спецификации?

1 Ответ

0 голосов
/ 09 июня 2018

Как объяснил jkiiski, поведение в ANSI Common Lisp не определено.Пример цитируется в разделе UNWIND-PROTECT в CLHS:

;;; The following has undefined consequences because the catch of B is 
;;; passed over by the first THROW, hence portable programs must assume 
;;; its dynamic extent is terminated.  The binding of the catch tag is not
;;; yet disestablished and therefore it is the target of the second throw.
 (catch 'a
   (catch 'b
     (unwind-protect (throw 'a 1)
       (throw 'b 2))))
...