- Write a function, curry-skip, with the following behavior:
> ((curry-skip 0) 'foo)
foo
> (((curry-skip 1) 'foo) 'bar)
bar
> ((((curry-skip 2) 'foo) 'bar) 'baz)
baz
>
- Write make-lookup-function which takes as arguments: 1) A symbol,
target; and 2) An s-expression, sexpr, to be searched.
make-lookup-function returns a function composed of
car's and cdr's that will fetch target out of
sexpr. If target is not found in sexpr,
make-lookup-function returns #f. If
target appears more than once, the returned function should
access the first occurence of target (as printed).
> (define foo (make-lookup-function 'd '(a (b c (d e) f g) h)))
> (foo '(a (b c (d e) f g) h))
d
> (foo '(1 (2 3 (4 5) 6 7) 8))
4
> (define bar (make-lookup-function 'j '(a (b c (d e) f g) h)))
#f
> (define baz (make-lookup-function 'b 'b))
> (baz 'b)
b
> (baz 6)
6
>
- Declare a macro with keyword and, which may take any
number of subexpressions. If called with no subexpressions, it evaluates to #t.
If all of its subexpressions are not #f, it evaluates to the last one;
otherwise it is #f.
- Many Scheme's have a special form called named-let
which has the following abstract syntax:
(let <name> ((<var1> <val1>)...(<varN> <valN>))
<expr1>
.
.
.
<exprM>)
=>
((letrec
((<name>
(lambda (<var1>...<varN>)
<expr1>
.
.
.
<exprM>)))
<name>) <val1>...<valN>)
The named-let special form can be used as follows:
>(let loop ((x 4) (acc 1))
(if (= x 1)
acc
(loop (- x 1) (* x acc))))
24
>
Use define-macro to define named-let.
- In the while special form, an expression is evaluated
repeatedly as long as a given condition is true. We can achieve this
effect in Scheme, without special syntax, as illustrated by the
following program, which sums the numbers from 1 to 100:
(let ((n 100) (sum 0))
(letrec
((loop
(lambda ()
(if (positive? n)
(begin
(set! sum (+ sum n))
(set! n (sub1 n))
(loop))))))
(loop)
sum))
However, for convenience, we would like to add a while special
form, which would allow us to write the above program as:
(let ((n 100) (sum 0))
(while (positive? n)
(set! sum (+ sum n))
(set! n (sub1 n)))
sum)
and which has the following abstract syntax:
(while <test> <expr1>...<exprN>)
=>
(letrec
((loop
(lambda ()
(if <test>
(begin
<expr1>
.
.
.
exprN>
(loop))))))
(loop))
Define while using define-macro. Your definition must
take into account the potential variable capturing that is caused when
the variable loop occurs free in test
or expression.
- Using the stream library defined in class, define the infinite
stream of increasingly accurate Taylor series
approximations for e:
e(0) = 1/0! e(1) = 1/0! + 1/1! e(2) =
1/0! + 1/1! + 1/2! e(3) = 1/0! + 1/1! + 1/2! + 1/3!...
- The positive rational numbers, which are ratios of two positive
integers, a/b, can be enumerated by listing them in order of
increasing sums a+b, with those numbers having the same sum listed in
order of increasing numerator a. Those fractions that are not in
lowest terms are omitted from the enumeration. Thus, the enumeration
begins with 1/1, 1/2, 2/1, 1/3, 3/1,... Define a stream,
positive-rationals, that contains all of the positive rational numbers
with numerator and denominator having no common divisor greater than
one. Represent the rational number a/b as a list (a b) and use the
Scheme procedure gcd to test whether a/b is in lowest terms. Test your
program by listing the first twenty elements of the stream.