Do examples return expected result?
fonghou opened this issue · comments
Hi, nice library!
I'm not sure I understand the result from examples in README. Would you mind explain a bit more?
- I would expect this returns ::result, but got nil instead.
(handler-bind [::some-condition (fn [condition]
(invoke-restart ::some-restart))]
(restart-bind [::some-restart (fn [] ::result)]
(signal ::some-condition)))
;; nil
- Should this return ::hello? I got nil again here.
(derive ::some-condition ::parent-condition)
(handler-bind [::some-condition (fn [condition] nil)
::parent-condition (fn [condition] (invoke-restart ::some-restart))]
(restart-bind [::some-restart (fn [] ::hello)]
(signal ::some-condition)))
;; nil
- Why would (print "never reached!) never reached? I would expect it does print "never reached!" line because it's a successful restart.
(restart-case (do (invoke-restart ::some-restart)
(println "never reached!"))
(::some-restart []
(println "reached!")
::return-result))
;; => ::return-result
Thanks!
Hey, thanks for showing interest!
Yes, these are the expected results, and I'll explain why in brief shortly. All the interactions here are explained in detail in the docstrings of the functions and macros.
For the first and second examples, this is because of the use of the -bind
variants of the two macros. When a handler is invoked by signal
and returns normally, signal
will look further up the stack to find more handlers to run until one performs a non-local exit, and if all return normally, it returns nil. The -bind
variants of the macros don't introduce any non-local exits on their own, so throw
is the only way to exit without searching for more handlers.
Example three uses the restart-case
variant though, which introduces a non-local exit. When invoke-restart
is called the expression immediately performs a non-local exit to outside the expression and then runs the restart code, returning its return value.
All these behaviors are described in the Common Lisp spec, and I'll admit right now the project readme is geared towards common lispers using Clojure. I'm planning on making the readme give more and better examples in futute to motivate conditions and restarts to Clojure devs.