1.9 Anonymous Functions

After we define a function, the name of the function can be used as a value without calling it. If you just evaluate the function name, then Plait will print something like #<procedure>.

> (define (plus-five n)
    (+ n 5))
> plus-five

- (Number -> Number)

#<procedure:plus-five>

More usefully, you might pass the function to another function that calls it. For example, the map function takes a function and a list, and it applies the function to each element of the list to produce a new list.

> (map plus-five
       '(1 2 3))

- (Listof Number)

'(6 7 8)

Sometimes, and especially with map, you need a one-off function that doesn’t need to be defined for everyone else to see, and it doesn’t even need a name. You can make an anonymous function by using lambda:

> (map (lambda (n)
         (+ n 6))
       '(1 2 3))

- (Listof Number)

'(7 8 9)

The form (lambda (n) (+ n 6)) means “the function that takes an argument n and returns (+ n 6).” You can evaluate a lambda form without passing it anywhere, although that isn’t particularly useful:

> (lambda (n)
    (+ n 7))

- (Number -> Number)

#<procedure>

Notice that the result has a function type: it’s a function that takes a Number and returns a Number.

An anonymous function created with lambda doesn’t have to stay anonymous. Since you can use a lambda form anywhere that an expression is allowed, you can use in define:

(define plus-eight : (Number -> Number)
  (lambda (n)
    (+ n 8)))

This definition is completely equivalent to the function-definition shorthand:

(define (plus-eight [n : Number]) : Number
  (+ n 8))

Another interesting property of lambda functions is that, just like any local function, the body of a lambda can see any surrounding variable binding. For example, the lambda body in the following add-to-each function can see the m that is passed to add-to-each:

> (define (add-to-each m items)
    (map (lambda (n)
           (+ n m))
         items))
> (add-to-each 7 '(1 2 3))

- (Listof Number)

'(8 9 10)

> (add-to-each 70 '(1 2 3))

- (Listof Number)

'(71 72 73)

You can declare types for lambda arguments and results similar to declaring them with define in the function-definition shorthand:

(lambda ([s : String]) : Boolean
  (> (string-length s) 10))

- (String -> Boolean)

#<procedure>