Instead of Stone Age ideas like global variables, you could create a Lisp or Javascript closure, or use a C++ functino. Do monads offer a big enough advantage over those approaches to justify the endless trouble of learning them?
Instead of Stone Age ideas like global variables, you could create a Lisp or Javascript closure, or use a C++ functino. Do monads offer a big enough advantage over those approaches to justify the endless trouble of learning them?
;; bad
(let ((s (make-state-thing)))
(defun function () ...)))
;; good
(defparameter *s* (make-state-thing))
(defun function () ...)
That defparameter might be defvar: it depends on whether you want to re-initialize the state variable when a new version of this module is loaded, or keep the old value.Speaking of which, with the let, you don't get that decision. For the defun to have its effect, the form has to be evaluated. Every evaluation of the let instantiates a new binding for s in a new lexical environment, end of story.
Even if we have the defparameter, we can redefine function while keeping the same state.
It's also easy to inspect the state. A the REPL, just evaluate its name: there it is. You don't have to whip out a closure environment inspector.
defun is a "stone age" tool anyway, which destructively overwrites a global function binding. Wrapping it with a captured lexical environment is a form of situational irony in programming (if not indeed verbal).
Regardless, you can't maintain state with closures in a pure language. You could close over some local "variable", but that variable would be immutable. In an impure language that would work, but then you're back to managing global state, even if that state is not defined at the top level (i.e. global in the sense that different closures could still have access to the same piece of state, concurrently).
[0] https://news.ycombinator.com/item?id=13965917
EDIT: just to clarify, monads manage state purely. I.e, instead of writing:
function statefulFunction(state) {
(a, state1) = f(state);
(b, state2) = g(a, state1);
(c, state3) = h(b, state2);
return (c, state3);
}
you can write: statefulFunction = do
a <- f
b <- g a
c <- h b
return c
But the resulting function is still pure, i.e. (state) => (c, state).