This is a homework question.
Question

My attempt (the whole file): http://pastebin.com/TS6mByEj
If you search let var = exp1 in body, that’s the function I need to extend according to the question.
When I test the sample code above, I get an error apply-env: No binding for y
(eval “let x = 30
in let x = -(x,1)
y = -(x,2)
in -(x,y)”)
; The following is execution log
The-next-two-lines-shows-var-and-exp1
(x)
(#(struct:const-exp 30))
diff-exp
#(struct:var-exp x)
#(struct:const-exp 1)
diff-exp
#(struct:var-exp x)
#(struct:const-exp 2)
The-next-two-lines-shows-var-and-exp1
(x y)
(#(struct:diff-exp #(struct:var-exp x) #(struct:const-exp 1)) #(struct:diff-exp #(struct:var-exp x) #(struct:const-exp 2)))
diff-exp
#(struct:var-exp x)
#(struct:var-exp y)
I know this is really long language, but if anyone can kindly lead me to the right direction would be really really nice.
Thank you!
UPDATE
Right before I evaluate and hit the error, the new environment env1 is like this
(#(struct:extend-env x #(struct:num-val 29) #(struct:extend-env x #(struct:num-val 30) #(struct:extend-env i #(struct:num-val 1) #(struct:extend-env v #(struct:num-val 5) #(struct:extend-env x #(struct:num-val 10) #(struct:empty-env))))))
#(struct:extend-env y #(struct:num-val 28) #(struct:extend-env x #(struct:num-val 30) #(struct:extend-env i #(struct:num-val 1) #(struct:extend-env v #(struct:num-val 5) #(struct:extend-env x #(struct:num-val 10) #(struct:empty-env)))))))
One of them is #(struct:extend-env y #(struct:num-val 28). So y exists in the environment which it is going to be evaluated, except it is not part of the car env1. It is in cdr env1
Yet, my code relies on car env1….
You’ve got your finger on the problem, but your language suggests some conceptual problems. In particular,
env1is not an environment, it’s a list of environments. Why are you usingmap? What are you taking thecarof the result? What happens if you run your interpreter on"let in 5"(ie, no variable bindings)?Your use of
mapandcarsuggests to me that you’re attempting to code on autopilot (“I have a list…mapdoes stuff with lists!”). Either that or you’re thinking thatextend-envchanges (mutates) the environment andmapis a way of mutating it several times. But that’s wrong.My advice: think about what you want the environment to contain. Make a separate helper function for computing the new environment. Make it a simple recursive function: no higher-order helpers like
map(yet). Write test cases for it. Once you get it working (ie, tested), see if it fits a pattern that you can use a higher-order function to simplify.