[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