13 Lab Practice with Macros
Goals |
— |
Exercise 23. Develop the compile-time function disjunction2 (without using or). The function deals with binary disjunctions of the shape(disjunction2 lhs:expr rhs:expr)
Stop—
before anyone continues, let’s discuss Now generalize the function to disjunction, which deals with at least two but possibly an arbitrary number of expressions.
Exercise 24. Develop the compile-time function block (without using let*). The function implements syntax of the shape(block ((x1:id rhs1:expr) (x2:id rhs2:expr) ... (x3:id rhs3:expr)) body:expr)
The identifier x1 is visible in rhs2, but not vice versa, and so on. All x1 thru x3 are visible in body.The evaluation initializes x1 to rhs1, x2 to rhs2, and so on. Once all identifiers are initialized, body is evaluated.
Exercise 25. Develop the compile-time function for-loop. It realizes the following syntax trees as bounded loops over integers:(for-loop ([i e0 limit]) body)
or(for-loop ([i e0 limit stride]) body)
First, classify each piece of the input tree.
Second, develop the implementation for the second version only.
Third, add the first variant.
Fourth, explore what kind of error messages your implementation yields if the input tree does not match either pattern.
Exercise 26. Develop the compile-time function while, which adds while-do loops to Racket. Create your favorite syntax.
(dispatch e (s1 e1) ... (s2 e2) (default e-def)) into code that evaluates the expression e. If it is not a symbol, e-def is evaluated. If it is a symbol and if this symbol is any of s1 ... s2, the corresponding expression e1 ... e2 is executed. If there is more than one match, the first expression is picked. If there is no match, again e-def is run.Here is a sample use:
(define (next-state-of-traffic-light current) (dispatch current [red 'yellow-red] [yellow-red 'green] [green 'yellow] [yellow 'red] [default (if (symbol? current) 'blinking-red (error "really bad things happened"))])) Of course, the expression in the clauses do not have to be symbols; they could be proper expressions.
(defun (f:id x:id) e:expr)
to Racket where f becomes the identifier of a function, x its argument, and f the function body.
Exercise 29. Develop a compile-time function that implements a variant of like if that reacts only to #true and #false in the test position.
Note In a dynamically typed language, it makes some sense to use all values except for #false as equivalents to #true. But some people are offended and this is a first step toward fixing this wart.