2 ms·
Here's one small macro that I think addresses most of the pain: ;; (with f ((var val)...) body...) ;;==> (f (lambda (var...) body...) val...) (defm
by abecedarius 16y ago
Here's one small macro that I think addresses most of the pain:
;; (with f ((var val)...) body...)
;;==> (f (lambda (var...) body...) val...)
(defmacro with (f bindings &body body)
`(funcall ,f (lambda ,(mapcar #'car bindings) ,@body)
,@(mapcar #'cadr bindings)))
You use it like this, assuming you have monad functions UNIT and BIND:
(with bind ((v1 e1))
(with bind ((v2 e2))
(unit (+ v1 v2))))
If you need multiple types of monads, and you can't just give them each different function names, then use generic functions for UNIT and BIND (with two differences from Haskell: Haskell's 'return' is generic in the resulting monad type, not the argument type, and the type's resolved at compile time). When I've done this in Scheme I only needed one kind of monad, so I didn't bother.
WITH can be handy for other things; I already had it lying around when the occasion came up to use a monad in Scheme.
Oleg's written about another approach using delimited continuations.