Вы можете использовать их для управления потоком. Например, в Smalltalk метод ifTrue: ifFalse: является методом для логических объектов, с различной реализацией для каждого из классов True и False. Выражение
someBoolean ifTrue: [self doSomething] ifFalse: [self doSomethingElse]
использует два замыкания - блоки в [квадратных скобках] в синтаксисе Smalltalk - одно для истинной ветви и одно для ложной ветви. Реализация «ifTrue: ifFalse:» для экземпляров класса True -
ifTrue: block1 ifFalse: block2
^ block1 value
и для класса False:
ifTrue: block1 ifFalse: block2
^ block2 value
Здесь замыкания используются для задержки оценки, чтобы можно было принять решение о потоке управления, без какого-либо специального синтаксиса вообще (кроме синтаксиса для блоков).
Haskell немного отличается, поскольку его ленивая модель оценки во многих случаях эффективно автоматически создает эффект замыканий, но в Схеме вы в конечном итоге часто используете лямбда-выражения для потока управления. Например, вот утилита для извлечения значения из списка ассоциаций, предоставляющая опционально вычисляемое значение по умолчанию в случае, если значение отсутствует:
(define (assq/default key lst default-thunk)
(cond
((null? lst) (default-thunk)) ;; actually invoke the default-value-producer
((eq? (caar lst) key) (car lst))
(else (assq/default key (cdr lst) default-thunk))))
Это будет называться так:
(assq/default 'mykey my-alist (lambda () (+ 3 4 5)))
Ключевым моментом здесь является использование лямбда-выражения для задержки вычисления значения по умолчанию до тех пор, пока оно фактически не станет обязательным.
См. Также стиль прохождения продолжения, который доводит это до крайности. Например, Javascript полагается на стиль продолжения продолжения и замыкания для выполнения всех своих операций блокировки (таких как спящий режим, ввод-вывод и т. Д.).
ETA : Там, где я говорил о замыканиях выше, я имею в виду лексически ограниченные замыкания. Часто это ключевая лексическая сфера.