# [Openmcl-devel] compute values in place

Ron Garret ron at flownet.com
Sun Sep 30 18:02:54 UTC 2012

```On Sep 30, 2012, at 1:38 AM, Taoufik Dachraoui wrote:

> Hi
>
> I am writing a small interpreter for lambda calculus. Within an expression I have some shared expressions

Why do you have shared expressions?

> The following explains my need to compute a shared expression exactly once:
>
> (let ((a '(#1=(+ 2 3) #1#)))
>    (setf (first a) (compute (first a)))
>    a)
>
> -> I would like to see (#1=5 #1#)  == (5 5)

Again, why do you want to do this?  If you want to maintain the invariant that the first and second elements of your list are always the same, why do you need them both?

> Is there a way to compute (+ 2 3) and set the result in the same memory location of the expression

Yes, there are many ways, but in general you need to make a place to put the value, e.g.:

? (defstruct cell value)
CELL
? (setf *print-circle* nil)
NIL
? (setf l (let ((c (make-cell :value '(+ 2 3)))) (list c c)))
(#S(CELL :VALUE (+ 2 3)) #S(CELL :VALUE (+ 2 3)))
? (setf (cell-value (first l)) 5)
5
? l
(#S(CELL :VALUE 5) #S(CELL :VALUE 5))
? (setf *print-circle* t)
T
? l
(#1=#S(CELL :VALUE 5) #1#)

> I want to avoid storing the expressions in a cons

Why? You have to store your value somewhere.  Why not in a cons?

> like:
>
> (let ((a '(#1=(nil (+ 2 3)) #1#)))
>    (setf (second (first a)) (eval (second (first a)))) a)
> -> (#1=(NIL 5) #1#)

You may find it is more aesthetically pleasing to store the value in the CAR of a const cell rather than the CDR:

? (setf l '(#1=((+ 2 3)) #1#))
(#1=((+ 2 3)) #1#)
? (setf (caar l) 5)
5
? l
(#1=(5) #1#)

Note that this is exactly the same as a cell, except that the accessor for the value is CAR rather than CELL-VALUE and the constructor is CONS rather than MAKE-CELL.

rg

```