Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implenting simultaneous bindings

Tags:

lisp

scheme

I'm writing a Lisp (code at GitHub) and I want to implement local bindings. Currently I have two syntaxes:

(let <var> <val> <expr>)

for binding a single variable or function, and

(with (<var1> <val1> ... <varN> <valN>) <expr>)

to bind multiple values at once.

At present, the bindings are evaluated sequentially, and each new function binding retains a copy of the environment it was defined in, so <var2> can refer to <var1> but not vice-versa.

I would like to modify the code so that when binding multiple values at once you effectively have simultaneous binding. For example, I would like to be able to write (this is a trivial example, but it should illustrate the idea):

(define (h y)
  (with ((f x) (if (eq? x 0) #t (g (- x 1)))
         (g x) (if (eq? x 0) #f (f (- x 1))))
  (f y))

At the moment this code doesn't run - g closes over f, but not the other way around.

Is there a canonical way to implement simultaneous binding in Lisp?

like image 949
Chris Taylor Avatar asked Oct 23 '25 23:10

Chris Taylor


1 Answers

In SICP there's a section on internal definitions which covers this subject. In particular, the exercises 4.16, 4.18, 4.19 tell you how to implement different strategies for achieving simultaneous definitions.

The syntax is a bit different, but the idea in the book boils down to transforming this code:

(lambda <vars>
  (define u <e1>)
  (define v <e2>)
  <e3>)

Into this code:

(lambda <vars>
  (let ((u '*unassigned*)
        (v '*unassigned*))
    (set! u <e1>)
    (set! v <e2>)
    <e3>))

The same idea applies to your with special form. Take a look at the linked book for more implementation details.

like image 108
Óscar López Avatar answered Oct 26 '25 00:10

Óscar López



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!