2017-01-09 1 views
0

Я пытаюсь понять код схемы процедуры счетчика. Это процедура более высокого порядка (процедура выдает другую процедуру), и я застрял с ней.Почему процедура make-counter содержит два определения лямбда?

(define make-counter 
    (lambda (n) 
    (lambda() 
     (set! n (+ n 1)) 
     n))) 

(define ca (make-counter 0)) 
(ca) 
(ca) 

Это выдает 1 и 2 соответственно, как ожидалось. Зачем нам здесь 2 вложенных процедуры? Каковы их функции индивидуально?

Я был бы признателен, если кто-то объяснит подробности. Спасибо, теперь.

ответ

5

отступом правильно, это:

(define make-counter 
    (lambda (n) 
    (lambda() 
     (set! n (+ n 1)) 
     n))) 

Кстати, вы можете использовать другой синтаксис:

(define (make-counter n) 
    (lambda() 
    (set! n (+ n 1)) 
    n)) 

make-counter это функция, которая принимает число n и возвращает объект под названием замыкание, которое действует как функция, но содержит состояние. Различные вызовы make-counter будут производить различные замыкания, даже если в аргументе указывается тот же n. Закрытие можно вызвать с помощью синтаксиса функции-вызова, как вы экспериментировали.

Когда вы вызываете замыкание, выполняется код, который содержится внутри. В вашем примере закрытие принимает нулевые аргументы и изменяет переменную с именем n. Опять же, привязка от n к значению является локальной для замыкания и различной для всех экземпляров счетчиков. Но внутри конкретного счетчика n всегда ссылаются на ту же ячейку памяти.

Звонок функции set! меняет то, что n оценивает и заменяет предыдущее значение (+ n 1), увеличивая локальную переменную счетчика.

+0

'set!' Не возвращает новое значение (по крайней мере, на Chicken. Я не уверен, работают ли другие схемы по-разному). – jkiiski

+0

@jkiiski Вы правы, я не видел 'n' в исходном вопросе и ошибочно полагал, что' set! 'Вернул значение. Благодаря! – coredump

+0

Спасибо! Это очень помогло. Я забыл, что объекты похожи на процедуры в схеме и теперь поняты. – ErenL

Смежные вопросы