Uniвсячина

понемножку о Linux и программировании

Реализация исключений через Continuations

Прочитал мнение, что если язык поддерживает first-class continuations, то через них можно реализовать все остальные структуры. Не знаю, как насчет всех-всех, но систему исключений реализовать вполне можно. Вот пример на Scheme:

(let ((exception-handler (lambda (exit arg)
                           (display "Outer handler") (newline)
                           (display arg) (newline)
                           (exit #f))))
  (display "Pre-A") (newline)
  (call/cc (lambda (context)
             (let ((exception-handler (lambda (exit arg)
                                        (display "Inner handler") (newline)
                                        (display arg) (newline)
                                        (exception-handler context arg))))
               (call/cc (lambda (context)
                          (display "A") (newline)
                          (exception-handler context "Exception!")
                          (display "B") (newline))))))
  (display "Post-B") (newline))

Выхлоп программы:

Pre-A
A
Inner handler
Exception!
Outer handler
Exception!
Post-B

Тут мы можем видеть два вложенных обработчика исключений. Причем внутренний обработчик передает управление внешнему. Можно было бы сделать и так, что бы внешний обработчик не вызывался:

(let ((exception-handler (lambda (exit arg)
                           (display "Outer handler") (newline)
                           (display arg) (newline)
                           (exit #f))))
  (display "Pre-A") (newline)
  (call/cc (lambda (context)
             (let ((exception-handler (lambda (exit arg)
                                        (display "Inner handler") (newline)
                                        (display arg) (newline)
                                        (exit #f))))
               (call/cc (lambda (context)
                          (display "A") (newline)
                          (exception-handler context "Exception!")
                          (display "B") (newline))))))
  (display "Post-B") (newline))

Выхлоп программы:

Pre-A
A
Inner handler
Exception!
Post-B

Ну и конечно, все это можно завернуть в красивый синтаксис а-ля try/catch, используя макросы. Но суть останется та же.

Comments