[cl-stm-devel] Binding variables
Hoan Ton-That
hoan at ton-that.org
Sat Jul 1 11:22:52 UTC 2006
Hey everyone,
Today, I added `tlet' a
There is a slight problem with our previous higher-order
function:
(deftransaction sleep-after (seconds transaction)
transaction
(trans (sleep seconds)))
The return value of the new transaction is not the
same as the return value of the input transaction.
Instead what `sleep-after' does is always return
NIL, because `sleep' returns NIL. What we need
is a way to bind the value of `transaction' to a
variable. Hence `tlet'. Here is how we could write
`sleep-after' correctly:
(deftransaction sleep-after (seconds transaction)
(tlet ((val transaction))
(trans (sleep seconds))
(trans val)))
Now if you looked through the debugging output
when typing `(perform (sleep-after 2 (increment *c*)))',
with both versions, you will see a line looking like:
20:33 STM-LOGGER/+DRIBBLE+: Transaction finished executing with: 6
or, with the old version:
20:33 STM-LOGGER/+DRIBBLE+: Transaction finished executing with: NIL
If you were very observant, you would have noticed
that the `tlet' in `sleep-after' could be replaced with
a `prog1'-like construct. We can define `progt1' in
terms of `tlet':
(defmacro progt1 (&body body)
(with-unique-names (val)
`(tlet ((,val (trans ,(car body))))
,@(cdr body)
(trans ,val))))
And thus `sleep-after' becomes:
(deftransaction sleep-after (seconds transaction)
(progt1 transaction
(trans (sleep seconds))))
which is much nicer. However, we quickly run into a
problem. We now have to define a whole slew of
transactional equivalents of `prog2', `multiple-value-prog1',
and so on. When translating an the MVar example from
Haskell to Common Lisp, I even had to write a new version
of `if'!
The next step is to write a code-walker that converts
Common Lisp forms into the transactional equivalent.
Hoan
More information about the Cl-stm-devel
mailing list