I am trying to implement a data structure to keep the state (variable bindings) of a program. I represent the state with association lists which are lists of key-value pairs.
An example association list is: '((x . 3) (y . (1 2)) (z . a)). In this example, key 'x has value 3, 'y has value '(1 2) and 'z has value 'a.
To manipulate the state, I have two functions:
(get-binding state var)This function returns the value symbol var is bound (assigned) to in state.
(set-binding state var val)This function returns a new state that is same as state with the exception that var is bound to val.
empty-stateThis variable corresponds to the state with no bindings. It is defined using define. Note: empty-state is not a function.
Example:
> (get-binding (set-binding (set-binding empty-state 'x 3) 'x 4) 'x)
which outputs 4.
Here is my code:
(define (enclosing-environment env) (mcdr env))
(define empty-state null)
(define (get-binding env var)
(define (env-loop env)
(define (scan vars vals)
(cond [(null? vars)
(env-loop (enclosing-environment env))]
[(eq? var (mcar vars))
(mcar vals)]
[else
(scan (mcdr vars)
(mcdr vals))]))
(if (eq? env empty-state)
(error "Unbound variable:" var)
(let ([frame (first-frame env)])
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
(define (set-binding! env var val)
(define (env-loop env)
(define (scan vars vals)
(cond [(null? vars)
(env-loop (enclosing-environment env))]
[(eq? var (mcar vars))
(set-mcar! vals val)]
[else
(scan (mcdr vars)
(mcdr vals))]))
(if (eq? env empty-state)
(error "Unbound variable -- SET!:" var)
(let ([frame (first-frame env)])
(scan (frame-variables frame)
(frame-values frame)))))
(env-loop env))
But it gives an error that says "Unbound variable -- SET!: x". How can I prevent it?
get-bindingandset-bindingare purely functional operations. - Alexis Kingset-bindingdoesn't match your implementation.set-binding!is mutating a binding if one exists (anywhere), throwing an error otherwise. That is not the same as returning "a new state that is same as state with the exception that var is bound to val". - molbdnilo