# Background

# Part I: Point free style

- Time
- 25 minutes
- Activity
- Small groups / individuals

We already learned about *higher order functions*, functions which
take other functions as arguments. Certain higher order functions
return other functions; these are sometimes called *combinators*,
especially when the "combine" two or more functions.

- start a new file
`~/fcshome/cs2613/L07/plot-example.rkt`

with the following

```
#lang racket
(require plot)
(require "../L06/calculus.rkt")
```

- Suppose we want to make lots of plots comparing two functions (e.g. to see how closely they match). The core of one solution to the previous part looks like

```
(lambda (x) (- (deriv sin x) (cos x)))
```

- In order to promote code re-use, abstract out the two numerical functions of x, call them
`f`

and`g`

. Fill in the defintion for the combinator`fsub`

so that the given tests pass.

```
(define (fsub f g)
(lambda (x) ( ))
(module+ test
(require rackunit)
(define (sin2 x) (integrate cos x))
(define (cos2 x) (deriv sin x))
(define epsilon 0.001)
(define test-points (build-list 20 (lambda (x) (* 2 pi (random)))))
(for ([x test-points])
(check-= ((fsub cos cos2) x) 0 epsilon)
(check-= ((fsub sin sin2) x) 0 epsilon)))
```

- A first attempt attempt to use
`fsub`

for plotting reveals a flaw; namely that`deriv`

is not a combinator, but rather returns a number. The forces us to add some`lambda`

boilerplate.

```
(plot (function (fsub (lambda (x) (deriv sin x)) cos) -2pi 2pi))
```

- We can abstract away some more boilerplate and define a function
`fderiv`

which*is*a combinator.

```
(define (fderiv f)
(lambda (x) (deriv f x)))
(plot (function (fsub (fderiv sin) cos) -2pi 2pi))
```

This last expression

`(fsub (fderiv sin) cos)`

is sometimes called*point-free style*.If we think a bit about the function

`fsub`

, the role of`-`

is easy to abstract: it's just a function with two arguments. So we can define a function "factory" that makes combinators like`fderiv`

. Fill in definition of`binop->fbinop`

below.

```
(define (binop->fbinop op)
(lambda (f g)
(lambda (x) )))
(define fsub2 (binop->fbinop -))
(plot (function (fsub2 (fderiv sin) cos) -2pi 2pi)))
(define fadd (binop->fbinop +))
(plot (function (fadd sin cos) -2pi 2pi))
```

# Part II Combinator Discussion

- Time
- 10 minutes
- Activity
- Group discussion

- Can you think of Java analogues of a combinators?
- Do these seem more or less exotic than combinators?
- What are potential advantages of this "point-free style"?
- How about disadvantages?

# Part III Currying

- Time
- 15 minutes
- Activity
- Demo

- The operation that transformed
`deriv`

into`fderiv`

is itself a combinator. We can take the definition of`fderiv`

and abstract out the definition of`deriv`

; let's call it`g`

.

```
(define (mogrify g f)
(lambda (x) (g f x)))
(define (fderiv2 f) (mogrify deriv f))
(plot (function (fsub (fderiv2 sin) cos) -2pi 2pi))
```

- In the spirit of the discussion above, the argument
`f`

to`mogrify`

is kind of useless. We can hide it inside a new combinator:

```
(define (currify g)
(lambda (f) (lambda (x) (g f x))))
(define fderiv3 (currify deriv))
(module+ test
(for ([x test-points])
(check-= (cos x) ((fderiv3 sin) x) epsilon)))
```

The combinator

`currify`

is common enough to be built into the racket library under the name curryYou can verify that

`curry`

is a drop replacement for the function`currify`

; if you read the documentation you can see that it's actually more general.

# Macros

- Time
- 20 minutes
- Activity
- Small Groups/individual

In the first half of the lab we discussed a method of building
programs at runtime using *combinators*. In the second half, we'll
discuss the construction of programs at *compile time* using what are
called *macros*.

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*.

start a new file

`~/fcshome/cs2613/labs/L07/short-circuit.rkt`

for the second half of the lab.The simplest way of defining a macro in racket is to use define-syntax-rule. As a first approximation, you can think of these syntax rules as functions that don't evaluate their arguments.

Let's start by defining

`And`

, which is just like the lower case version except the short-circuit evaluation is from the right.

```
#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))))
```

- Notice the use of
`lambda`

to delay evaluation in`check-exn`

; that's exactly the kind of boilerplate we can eliminate with a syntax rule:

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

- Define
`Or`

in terms of`if`

in a similar way to`And`

. You should pass the following tests

```
(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)))
```

# Macro Discussion

- Time
- 5 minutes
- Activity
- Group discussion

We could define functions somewhat like

`And`

and`Or`

if we protect the arguments from evaluation. How would we do that?Macros are a key part of the implimentation strategy of racket. What's an example of some syntax we saw already that is (probably) implimented as a macro?

# Recursive Macros

- Time
- 20 min
- Activity
- Demo

You will probably not be surprised to learn that macros in racket can be recursive. This is the usual way of handling variable numbers of "arguments".

Start a new file `~fcshome/cs2613/labs/L07/let-macros.rkt`

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))
```

]

- The key insight is that
`let*`

behaves like a nested set of`let`

s. Let us transform the examples about according to this idea:

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

- That's more cumbersome to write, of course, but that's why
`let*`

exists. So how can we formulate this recursively? Well, racket syntax already looks like a list, so lets turn this into a recursive problem on lists. Run the following in the macro stepper.

```
(require (for-syntax racket/list))
(define-syntax (Let* stx)
(let ([lst (syntax->datum stx)])
(let ([bindings (second lst)]
[body (third lst)])
(datum->syntax
stx
(cond
[(empty? bindings) body]
[else
(list 'let (list (first bindings))
(list 'Let* (rest bindings) body))])))))
(Let* ([x 5]
[y (- x 3)]
[y x])
(* y y))
```

So what are the new features here?

`for-syntax`

is so that we can use things not in`racket/base`

in our macro definition. We have`syntax->datum`

to go from "syntax objects" (roughly speaking, parsed racket) to regular lists, and`datum-syntax`

to go the other way.This is called a

*syntax transformer*, and we essentially just extended the racket compiler.There is a lot of support for writing macros in a nicer way. If we use more language features, then we can write it more compactly (but probably more mysteriously):

```
(define-syntax (Let* stx)
(syntax-case stx ()
[(Let* () body) #'body]
[(Let* ((first-id first-val) (id val) ...) body)
#'(let ([first-id first-val])
(Let* [(id val) ...] body))]))
(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))
```