UNB/ CS/ David Bremner/ teaching/ cs2613/ labs/ Lab 7

Before the lab

Background


Review

Time
5 minutes
Activity
Group-Discussion.

Macros

In this lab, we'll discuss the construction of programs using macros. This is sometimes referred to as metaprogramming. Other prominent examples of metaprogramming include C++ templates and Reflection in Java

Some Racket forms like and and or look like function calls, but we know they are not because they support short-circuit evaluation. We can define forms that behave differently than function calls (or that look like function calls, but actually do other things as well, like the rackunit check- forms). These forms are sometimes called macros.

Single Pattern Macros: define-syntax-rule

Time
15 minutes
Activity
Demo, Group-Discussion.
#lang racket
(define-syntax-rule (And a b)
  (if b a #f))

(module+ test
  (require rackunit)
  (define (die)
    (error 'die "don't run this"))

  (check-equal? (And (die) #f) #f)
  (check-exn exn:fail? (lambda () (and (die) #f))))
(module+ test
  (define-syntax-rule (check-fail expr)
    (check-exn exn:fail? (lambda () expr)))
  (check-fail (and (die) #f))
  (check-fail (And #f (die))))

Redefining or

Time
15 minutes
Activity
Individual work
(module+ test
  (check-equal? (Or #t #t) #t)
  (check-equal? (Or #f #t) #t)
  (check-equal? (Or #t #f) #t)
  (check-equal? (Or (die) #t) #t)
  (check-fail (or (die) #t)))

Multiple patterns and recursion

Time
15 min
Activity
Demo

We have discussed the difference between let and let* a bit in the labs. It turns out that let* can be implimented in terms of let using a macro.

Let's start by reviewing let*:

(module+ test
  (check-equal? (let* ([x 5]
                       [y (- x 3)])
                      (+ y y))
                4)
  (check-equal? (let* ([x 5]
                       [y (- x 3)]
                       [y x])
                       (* y y))
                25))
#lang racket

(define-syntax Let*
  (syntax-rules ()
    [(Let* ()     ) body]
    [(Let* ([         first-val] [id val] ...) body)
     (let ([first-id          ])
       (Let* ([id    ] ...)     ))]))

(module+ test
  (require rackunit)
  (check-equal? (Let* ([x 5] [y (- x 3)]) (+ y y)) 4)
  (check-equal? (Let* ([x 5] [y (- x 3)] [y x]) (* y y)) 25))

Before you start the quiz

Commit and push the .rkt files you wrote so far today.


Quiz

I will hand out the quiz instructions on paper.