UNB/ CS/ David Bremner/ teaching/ cs4613/ tutorials/ combinators

# Combinators

We already know 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.

• download calculus.rkt and save it as `calculus.rkt`
• start a new file `plot-example.rkt` with the following
```    #lang racket
(require plot)
(require "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
```(plot
(function
(lambda (x) (- (deriv sin x) (cos x))))
#:x-min -2pi
#:x-max 2pi)
```
• 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)))