Homework 3: Scheme Evaluation
- Print version, with cover page (pdf)
- Due Date: Monday, September 11
Many of these exercises are programming exercises, but you do not need to submit them electronically.
1 Symbol Mixup
Write a function (mixup x)
that takes an argument
x
, which can be any symbol or any number, and produces the
opposite type of thing, either the number 5 if x
is a
symbol, or the symbol 'num
if x
is a
number.
For example, (mixup 20)
should produce
'num
, and (mixup 'hello)
should produce
5
.
2 Building Blocks
In the C programming language, give an example of each of the following types of code fragments.
An atom (or literal)
A value that is not an atom
An expression that is not a value
A statement that does not end in a semicolon
3 Nested Quotes
When you type 5
into the interpreter, it returns
5
.
When you type (quote 5)
, it still returns the number
5
.
But when you type (quote (quote 5))
or ''5
,
it returns '5
.
What do you think is going on here? Why do you need two quotes to make the symbol 5?
(Caution: this is pretty tricky. Think about how evaluation works. Play around, experiment, discuss.)
4 Find the symbol
Write a function (has-symbol? name expr)
that
recursively searches through any quoted expression expr
and
returns true or false depending on whether that expression contains the
given symbol name
.
Note that the expression can contain nested sub-expressions!
For example, this would return #t
:
(has-symbol? 'x '(* 2 (+ x 3)))
whereas this would return #f
:
(has-symbol? 'y '(* 2 (+ x 3)))
5 Homoiconicity
The Wikipedia page on homoiconicity claims that raw machine code can be considered homoiconic, just like Scheme.
Explain what this means in a few sentences of your own.
Then tell me what properties of most homoiconic languages (like Scheme) does machine code definitely not have.
6 And Transformation
You know that there is a built-in function called and
in
Scheme. The built-in version actually takes any number of arguments, and
always returns either #t
or #f
, but for this
exercise we’ll assume that and
only takes two
arguments.
You should be able to convince yourself that every and
could be re-written as an if
. For example, consider the
following function that tests whether the number x
is a
“teen”.
(define (teen? x)
(and (>= x 13)
(< x 20)))
Well this is exactly the same as:
(define (teen? x)
(if (< x 13)
#f
(< x 20)))
Your task is to write a Scheme function
(and->if expr)
that takes a quoted and
expression and returns an equivalent quoted if
expression
that computes the same thing. (Note: the expression your code produces
might not look exactly like what I have above, but it should be
equivalent computationally.)
If you then eval
the result, it should work. For
example, the following should produce #t
:
(define x 18)
(eval (and->if '(and (>= x 13) (< x 20))))