#### Mar 6th, 2023

Welcome back to our Racket series. In the previous post, we covered some of the basics of Racket, including data structures, functions, and control structures. In this post, we will dive deeper into Racket's functional programming capabilities, including higher-order functions and closures.

##### Higher-Order Functions

In Racket, functions are first-class citizens, which means they can be passed as arguments to other functions and returned as values from functions. Functions that take other functions as arguments or return functions as values are called higher-order functions.

Here's an example of a higher-order function that takes a function `f`

and an integer `n`

as arguments and applies `f`

to `n`

`n`

times:

(define (repeat f n) (if (= n 0) (lambda (x) x) (compose f (repeat f (- n 1))))) (define (square x) (* x x)) ((repeat square 3) 2) ; returns 256

In this example, we define a function `repeat`

that takes a function `f`

and an integer `n`

.
If `n`

is 0, `repeat`

returns the identity function (i.e., a function that returns its argument unchanged).
Otherwise, `repeat`

composes `f`

with a new function that is the result of calling `repeat`

with `f`

and `n-1`

.

We then define a function `square`

that takes a number `x`

and returns its square.
Finally, we call `repeat`

with `square`

and `3`

as arguments, and we pass `2`

to the resulting function to get the answer `256`

.

##### Closures

A closure is a function that has access to variables in its lexical scope, even after the enclosing function has returned. Closures are useful for creating functions with persistent state.

Here's an example of a closure that takes an initial value `x`

and returns a function that adds `x`

to its argument:

(define (make-adder x) (lambda (y) (+ x y))) (define add-5 (make-adder 5)) (add-5 10) ; returns 15

In this example, we define a function `make-adder`

that takes an initial value `x`

.
`make-adder`

returns a lambda function that takes an argument `y`

and returns the sum of `x`

and `y`

.

We then define a new function `add-5`

that is the result of calling `make-adder`

with `5`

.
Finally, we call `add-5`

with `10`

as an argument, and we get the answer `15`

.

##### Conclusion

In this post, we've explored Racket's functional programming capabilities, including higher-order functions and closures. We've also provided some code examples to illustrate these concepts. In the next post, we will discuss Racket's macro system and its power to extend the language.