Problem 4 (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.
Hint: Consider the following test:
scm> (define x 0) ; expect x scm> ((define x (+ x 1)) 2) ; expect Error scm> 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 inscheme_eval
.
Before writing any code, unlock the tests to verify your understanding of the question:
$ python ok -q 04 -u
Once you are done unlocking, begin implementing your solution. You can check your correctness with:
$ 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