Completed
Details
Assignee
Stuart HallowayStuart HallowayReporter
Alan MalloyAlan MalloyApproval
OkPatch
Code and TestPriority
MinorFix versions
Details
Details
Assignee
Stuart Halloway
Stuart HallowayReporter
Alan Malloy
Alan MalloyApproval
Ok
Patch
Code and Test
Priority
Fix versions
Created March 6, 2013 at 9:06 PM
Updated August 15, 2013 at 12:13 AM
Resolved August 15, 2013 at 12:13 AM
Delays get into a corrupt state if an exception is thrown, allowing deref to behave differently on subsequent calls.
This can manifest in multiple ways, depending on the expression being delayed:
Cause:
clojure.core/delay
creates a^:once
function, promising to call it only once, so that the compiler can do locals-clearing on its lexical closure. However, when an exception is thrown the Delay object is left thinking it has never called the function, so when it is forced again it calls the function again, breaking its promise to the compiler and causing the function to run after its locals have been cleared.Solution: Make
Delay
remember the first exception that was thrown, and rethrow it on subsequent force attempts. This makes sense, in a way: the "result" of the expression was this exception e being thrown, and so this should happen every time.Patch:
delayed-exceptions.patch