< 6. Conditionals | 8. Recursion > |
7. First-Class Functions
So far, we've been treating the creation of functions as making entities different from numbers and strings.
We've passed functions to for-each
, so we've seen that functions are valid arguments to other functions.
In addition, a function can make new functions and have them returned. The fact that functions can be created by other functions and passed around like values make them first-class citizens in Scheme.
The lambda
special form
lambda
is a special form that creates a function, as an alternative to the (define (function-name arguments) ...)
construction. In effect, the evaluated value of a lambda
expression is an anonymous function (a function without a name).
In ancient Scheme texts, the construction (define function-name (lambda (argument) body))
was used instead of (define (function-name argument) body)
.
Both methods are valid and result in two named functions with the same behavior. Let's test this hypothesis:
(define (add-one x) (+ x 1)) (add-one 2)
(define alt-add-one (lambda (x) (+ x 1))) (alt-add-one 2)
A function that returns another function
You might never need to create a factory that produces functions, but this technique is very simple in Scheme.
Consider having to draw circles of various sizes, but without having to repeatedly pass the radius as an argument to draw one. What we'll make is a function that accepts the desired radius, and returns a circle-drawing function that only requires the x
and y
coordinates of the center:
(define (make-sized-circle-fn radius) (lambda (x y) (circle x y radius)))
The (x y)
list after lambda
is the parameter list, that is, the values that will be filled in by the caller of the function.
To use a function created by this factory, we have to somehow identify it. We use the (define name value)
construction to do so:
(define small-circle (make-sized-circle-fn 20)) (define large-circle (make-sized-circle-fn 70))
To test these functions, we will put small circles on the left half, and large circles on the right half:
(small-circle -150 50) (small-circle -100 -20) (small-circle -90 -80) (large-circle 120 60) (large-circle 80 20) (large-circle 90 -55)
< 6. Conditionals | 8. Recursion > |