Lisp - Closures



A Closure is a fundamental key to define a first class functions. A closure is a kind of inner function bundled with its lexical environment. A closure function can remember and access the variables of the scope in which a closure is created even if scope ceases to exist.

Key Concepts

  • Lexical Scoping − LISP follows static lexical scoping which means scope of a variable is determined by the position of the variable in the source code. This is very important in case of closures to handle the correct variables.

  • First Class Functions − A List function is a first class object necessary for closure to work.

    • A function can be assigned to a variable.

    • A function can be passed as an argument to other function(s).

    • A function can be returned from a function.

  • Environment Capturing − When a function is created within a function, it can capture the variable from surrounding scope. This surrounding scope, the captured environment makes up the closure.

Usage of Closures

Closures allows to create function to maintain state. Following are few examples of closures usage.

  • Function Factory− a factory function to create other functions.

  • Callback− a function to be executed in response of an event.

  • Data encapsulation− a function to hide data within a function's scope.

Closure Function Importance in LISP

Closures are extensively used in LISP for −

  • Functional Programming

  • Event driven Programming

  • Reusable and flexible code

Example - Closure in Action

main.lisp

; define a function with a closure
(defun adder (x)
  (lambda (y) (+ x y))) ; closure function accessing parameter

; define a function to add 5 to passed value
(defvar add-five (adder 5))

; define a function to add 10 to passed value
(defvar add-ten (adder 10))

; call add-five; prints 8
(print (funcall add-five 3))
(terpri)
; call add-ten; prints 13
(print (funcall add-ten 3))

Output

When you execute the code, it returns the following result −

8
13

Explanation

  • adder function is defined with a closure function as a lambda expression. Lambda expression remembers the value of x passed from the scope in which it was created.

  • (adder 5) returns the lambda expression to add-five variable. Lambda expression remembers the value of x passed as 5 and when add-five is called with a value 3 using (funcall add-five 3), the underlying lambda expression, adds the passed value as Y to X resulting in 8.

  • (adder 10) is used in similar pattern to add 10 to passed argument.

Advertisements