Exercise 6. Develop the macro where, which is a kind of backward let that has an expression followed by a binding that can be used by the expression. The binding is evaluated before the expression (even though it appears later). For example,
(where (+ my-favorite-number 2) [my-favorite-number 8])produces 10.After you have where with a single binding working, generalize it to support multiple bindings. With that generalization,produces 100.Now implement where*, which is a backwards let* that evaluates its clauses and binds in reverse order:produces the same values as (list 7 3 1).
Exercise 7. Develop the macro and/v, which is like and except that it binds the result of its first expression to a variable written => identifier. For example,evaluates to 2, butevaluates to #f. You can use #:literals in syntax-parse, since => is already bound (assuming you think that binding’s reuse is appropriate).
Exercise 8. Modify the definition of split-ct from lecture so that it can also deal with specifications that do not provide literal constants for start and end. When a non-literal start or end is provided, the rage check should happen at run time.Here is the code from lecture:
#lang racket (require (for-syntax syntax/parse)) (begin-for-syntax (define-syntax-class byte (pattern b:nat #:fail-unless (< (syntax-e #'b) 256) "not a byte"))) ; SYNTAX ; (split-ct tags start end [name:id step (~optional convert)] ...) ; computes the values of the fields name... by successively extracting ; bytes from tags, beginning at start to maximally end (define-syntax (split-ct stx) (syntax-parse stx [(_ tags start:integer end:byte [name step:byte (~optional convert)] ...) ; — — — — — — — — — — — ; the static error checking #:do [(define end-int (syntax-e #'end)) (define step-int (sum #'(step ...)))] #:fail-unless (< step-int end-int) "index out of range" ; — — — — — — — — — — — #`(let ([i start]) (let*-values ([(i name) (values (+ i step) (extract tags i (+ i step -1)))] ...) (values ((~? convert values) name) ...)))])) ; [Listof [Syntax Number]] -> Number ; compute the sum of the numbers hidden in syntax (define-for-syntax (sum list-of-syntax-numbers) (apply + (map syntax-e (syntax->list list-of-syntax-numbers))))Start by copying and pasting this code into your DrRacket.
Exercise 9. Start with the code from lecture and add the following pre-defined, arity-checked functions:
plus, which takes two number arguments and adds them;
minus, which takes two number arguments and adds them; and
string+, which takes two srting arguments and concatenates them.Add these without using define-function.
For example, (function-app plus 1 2) should produce 3, but your implementation should not include (define-function (plus x y) ***).
These primitives must work with the protocol from lecture. If you fancy adding other pre-defined function, please feel free to do so.
Expression = .... | (++ Expression)A (++ Expression) form produces a number 1 larger than the value of Expression.
Exercise 11. Develop a macro that consumes an identifier x and generates a definition for x that initializes it to how many such definitions (including the one for x) have been created so far in the whole program. For example, if your macro is called define-as-next, then
(define-as-next x) (define-as-next y) (define-as-next z)defines x as 1, y as 2, and z as 3.
When you have a solution, try this:What values do x, one-y, and another-y get? Explain. Try adding (define-as-next z) to the end again and check the value of z.Next, encapsulate the definition of the compile time function in a module named server and the uses of the function in a module called client. Your Definitions window will look like this:Does your solution still work? If not, fix it.
Now duplicate client, use client2 for the second one. Run your program. What do you see? Explain.
Please fill out today’s post-day survey.