-
Notifications
You must be signed in to change notification settings - Fork 179
Description
Currently, Carp doesn't support altering state in closures. As stated in DynamicSemantics, a closure's environment is captured in its entirety at creation time and prevents mutation of captured variables. This makes the definition of some classic functions impossible, such as this example from Let Over Lambda:
(let ((counter 0))
(lambda () (incf counter)))This function increments a value every time it is called. So, it successively returns 1, 2, 3....
The corresponding function in Carp always returns 1 instead of incrementing the value on each call:
(defn adder []
(let [x 0]
(fn [] (inc x))))Stateful closures are a technique I find useful. I don't think Carp needs to support them--and in fact it might make more sense not to depending on the language's overall semantics, but I am wondering whether we have a canonical way to likewise perform some ad-hoc capturing of state or a drop in replacement for places in which we'd use some stateful closure.
As an example case, mapping over a Stream sumtype is significantly easier with stateful closures.
Is the solution simply to allocate and pass around structs whenever one needs to keep track of some state?