кэширование предыдущих возвращаемых значений процедур в схеме - PullRequest
0 голосов
/ 05 апреля 2010

В главе 16 «Закаленного мошенника» авторы определяют рекурсивную процедуру «глубина», которая возвращает «пиццу, вложенную в n списков, например, (глубина 3) есть (((пицца)))». Затем они улучшают его как «deepM», который кэширует свои возвращаемые значения с помощью set! в списках Ns и Rs, которые вместе образуют справочную таблицу, поэтому вам не нужно проходить весь путь вниз, если вы достигнете возвращаемого значения, которое видели ранее. Например. Если я уже вычислил (глубину 8), когда я позже вычислю (глубина 9), я просто ищу возвращаемое значение (глубина 8) и выводит его в ноль, вместо того, чтобы возвращаться к (глубина 0).

Но затем они перемещают Ns и Rs внутри процедуры и инициализируют их нулем с помощью let. Почему это не лишает смысла кэширование возвращаемых значений? После небольшого эксперимента выясняется, что N и R переинициализируются при каждом вызове «deepM».

Я неправильно понимаю их точку зрения?

Полагаю, мой вопрос действительно такой: есть ли в Scheme способ, чтобы переменные с лексической областью сохраняли свои значения между вызовами процедуры, как вы можете сделать это в Perl 5.10 с переменными «состояния»?

1 Ответ

5 голосов
/ 05 апреля 2010

Duh. Не прочитав Seasoned Schemer, я не могу комментировать проблему памятки, если вы не предоставите здесь некоторый исходный код. Однако, что касается вопроса о том, существует ли способ, чтобы переменные с лексической областью сохраняли свое состояние между вызовами функций ... Это особенность языка Scheme, называемая "замыканиями". Рассмотрим следующий пример:

(define counter 
  (let ((number 0))
    (lambda () 
      (let ((result number))
        (set! number (+ number 1))
        result)))

Этот фрагмент кода определяет функцию счетчик, которая использует лексическую переменную (number) для отслеживания своего состояния. Каждый раз, когда вы вызываете функцию, вы получаете взамен другой номер:

> (counter)
0
> (counter)
1

и так далее. Важным моментом здесь является то, что функция, сгенерированная при выполнении выражения lambda, «закрывает» все лексически видимые переменные из окружающих областей (в данном случае только number.) читать значения или записывать новые значения в.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...