[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: The store monad
From: |
Ludovic Courtès |
Subject: |
Re: The store monad |
Date: |
Wed, 02 Oct 2013 23:45:34 +0200 |
User-agent: |
Gnus/5.130007 (Ma Gnus v0.7) Emacs/24.3 (gnu/linux) |
Today’s monadic news is that monads are “inlined”. Before, something like:
(mlet %store-monad ((x y))
(return (+ 1 y)))
would expand to:
((struct-ref %store-monad 0) y
(lambda (x)
((struct-ref %store-monad 1) x)))
With inlining, the above doesn’t expand to references to the
‘%store-monad’ record, and instead directly expands to:
(store-bind y (lambda (x) (store-return (+ 1 x))))
If in addition ‘store-bind’ and ‘store-return’ are defined with
‘define-inlinable’, then the whole shebang is inlined, allowing for
better optimizations:
--8<---------------cut here---------------start------------->8---
scheme@(guix monads)> ,expand (with-monad %identity-monad (>>= (return 2)
(lambda (x) (return (1+ x)))))
$17 = (let ((mvalue (let ((value 2)) value))
(mproc (lambda (x) (let ((value (#{1+}# x))) value))))
(mproc mvalue))
scheme@(guix monads)> ,optimize (with-monad %identity-monad (>>= (return 2)
(lambda (x) (return (1+ x)))))
$18 = 3
scheme@(guix monads)> ,optimize (mlet* %identity-monad ((x (return 1))(y
(return 2))(z (return (+ x y)))) z)
$19 = 3
[...]
scheme@(guix monads)> ,optimize (mlet* %store-monad ((x (return 1))(y (return
2))(z (return (+ x y)))) (return z))
$22 = (lambda (store) (let mresult ((store store)) 3))
--8<---------------cut here---------------end--------------->8---
This significantly reduces the cost of using bind/return all over the
place.
Ludo’.