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.

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