Closed amano-kenji closed 9 months ago
For reference, macex
against recurse2
's usage of the with
macro produces the following:
(do
(def proc (os/spawn ["ls"] :p {:out :pipe}))
(do
(def _00000C
(fiber/new
(fn []
(debug/stacktrace (fiber/current) "print stack" "")
(recurse))
:ti))
(def _00000D (resume _00000C))
(:close proc)
(if (= (fiber/status _00000C) :dead)
_00000D
(propagate _00000D _00000C))))
I've cleaned it up to change <.function \(.*\)>
to \1
.
Anything introducing a new fiber will mean there is a new stack. Error handling is based upon fibers and you can't tail call between fibers (they have separate stacks).
If you want the stack information from current fiber and it's ancestors, you can use debug/lineage
and apply debug/stacktrace
to each in whatever order you please.
If you want tail calls while dealing with error handling, that's not possible. Tail calls involve a stack, but each fiber has it's own stack, so it can't possibly tail call. If you can move the call outside of the mechanism introducing a fiber, you could do a tail call, but in most cases, you're not going to do that when error handling.
Correction - recursion within the body of an error handling mechanism (not the part that handles the error, but the code that might error) is non-recursive (and can't be, since that part is in a fiber).
Yeah, this is a cannot fix, as tail calls as a concept loose contextual information, making try-catch or any kind of error catching mechanism that uses a stack not an option.
I don't know whether this is intended...