missionary 2025-04-25

I've got a bit of code that's puzzling me. Full example (copy and paste to run it, it's self-contained):

(do
    (def value-atom (atom [true 1]))
    (def  [true nil]
    (reset! continue-atom true) ; SHOULD UNSUBSCRIBE  [false 1]
    (reset! continue-atom false)
    ; EXPECT , ACTUAL [true nil]
    (reset! value-atom [false 2])
    ; ASSERT => [false 2], should NOT subscribe to 
    (cancel!))
ASSERTs are what I see in the console, EXPECT/ACTUAL is where it behaves in a way I don't think it should.

Since loop/recur reuses the stack, my expectation is that subscription on <continue-sig would be unsubscribed when recur is called.

loop/recur does reuse the current stack frame, but a new stack frame is recreated (forked) whenever a m/?< switches. If <continue-sig were unsubscribed on recur, the behavior would not be the same as if the loop was unrolled

Thanks, I'll think in terms of loop unrolling going forward.

Another oddity: (cancel!) isn't printing out the missionary.Cancelled exception like it does in other scenarios. o_0