Problem 5 (200pts): define
@1
The define
special form (spec) in Scheme can be used either to assign a name to the value of a given expression or to create a procedure and bind it to a name:
scm> (define a (+ 2 3)) ; Binds the name a to the value of (+ 2 3)
a
scm> (define (foo x) x) ; Creates a procedure and binds it to the name foo
foo
The type of the first operand tells us what is being defined:
- If it is a symbol, e.g.
a
, then the expression is defining a name - If it is a list, e.g.
(foo x)
, then the expression is defining a procedure.
The do_define_form
function in scheme_forms.py
evaluates (define ...)
expressions. There are two missing parts in this function. For this problem, implement just the first part, which evaluates the second operand to obtain a value and binds the first operand, a symbol, to that value. Then, do_define_form
returns the symbol that was bound.
Use Ok to unlock and test your code:
python ok -q 04 -u
python ok -q 04
You should now be able to give names to values and evaluate the resulting symbols.
scm> (define x 15)
x
scm> (define y (* 2 x))
y
scm> y
30
scm> (+ y (* y 2) 1)
91
scm> (define x 20)
x
scm> x
20
Consider the following test:
(define x 0)
; expect x
((define x (+ x 1)) 2)
; expect Error
x
; expect 1
Here, an Error is raised because the operator does not evaluate to a procedure. However, if the operator is evaluated multiple times before raising an error, x
will be bound to 2 instead of 1, causing the test to fail. Therefore, if your interpreter fails this test, you'll want to make sure you only evaluate the operator once in scheme_eval
.