Существует ли интерпретатор Схемы, который использует оценку Нормального порядка?

Я медленно прокладывал себе путь хотя упражнения в Структуре и Интерпретация Компьютерных программ. Разделите 1.1.5 переговоров о применимом по сравнению с оценкой нормального порядка, и тема подходила несколько раз в тексте позже. Так как интерпретатор использует оценку применимого порядка, легко просто вставить display операторы отладки в Вашем коде для наблюдения точно, как это работает. Это помогло бы моему пониманию смочь сделать то же самое для оценки нормального порядка.

Кто-либо знает Схемы (или Lisp) интерпретатор, это реализовало оценку нормального порядка использования вместо применимого порядка?

Обновление:

Вот короткий пример, измененный от один данный в SICP. Я определю свое собственное add процедура, чтобы распечатать аргументы и использовать square процедура из книги.

(define (add x y)
  (display x)
  (display y)
  (newline)
  (+ x y))

(define (square x) (* x x))

Теперь, если я запускаю короткую программу (square (add 1 2)) с помощью оценки применимого порядка, результата (add 1 2) будет только вычислен когда-то затем передал square процедура. Операнды 12 должен быть распечатан однажды конечный результат. Мы можем просто выполнить это в интерпретаторе, чтобы проверить, что это - то, что происходит.

> (square (add 1 2))
12
9

Используя оценку нормального порядка, тем не менее, единственный операнд (add 1 2) должен быть скопирован в square процедура, которая оценила бы как (* (add 1 2) (add 1 2)). Операнды 12 должен быть распечатан дважды перед конечным результатом.

Я хотел бы смочь выполнить это в интерпретаторе, который делает оценку нормального порядка, чтобы проверить, что это действительно, как она работает.

9
задан Bill the Lizard 9 July 2010 в 14:29
поделиться

2 ответа

Racket имеет ленивый язык . Это лучше, чем просто интерпретатор, поскольку вы можете писать программы, состоящие из простых модулей рэкет и ленивых.

Что касается отладки с использованием распечаток - вы можете сделать это на этом ленивом языке, и вы получите что-то похожее на небезопасный ввод-вывод в Haskell. Хотя иногда это все еще может сбивать с толку. (И если вы хотите, чтобы интерпретатор вставлял в него распечатки, это также сбивало с толку, потому что это следует за ленивым вычислением ...)

6
ответ дан 2 November 2019 в 23:58
поделиться

Оказывается, в Scheme уже есть оценщик нормального порядка. Это те легендарные макросы, о которых вы, наверное, так много слышали, и мы можем переписать примеры из разделов 1.1.4–1.1.5, чтобы довольно легко использовать расширение макроса вместо применения процедуры:

(define (print . items)
  (for-each display items))

(define-macro (add x y)
  `(begin (print "[ADD " ',x " " ',y "]")
          (+ ,x ,y)))

(define-macro (mul x y)
  `(begin (print "[MUL " ',x " " ',y "]")
          (* ,x ,y)))

(define-macro (square x)
  `(begin (print "[SQUARE " ',x "]")
          (mul ,x ,x)))

(define-macro (sum-of-squares x y)
  `(begin (print "[SUM-OF-SQUARES " ',x " " ',y "]")
          (add (square ,x) (square ,y))))

(define-macro (f a)
  `(begin (print "[F " ',a "]")
          (sum-of-squares (add ,a 1) (mul ,a 2))))

Игнорируйте PRINT, их логика немного выходит за рамки того, где вы находитесь в тексте, но они просто сокращение для множества ДИСПЛЕЕЙ. Фактически, вы могли бы полностью отказаться от трассировки путем печати в пользу использования функции макрорасширения системы. но это зависит от реализации (например, в Ypsilon вы должны использовать (macro-expand '(f 5)) ).

Если вы загрузите эти определения (с оговоркой, что DEFINE-MACRO нестандартен, но на практике это не должно быть проблемой, так как большинство схем предоставляют его), то выполняется оценка (f 5) как и книга, будет распечатана (конечно, я ее немного приподнял):

[F 5]
[SUM-OF-SQUARES (add 5 1) (mul 5 2)]
[ADD (square (add 5 1))         (square (mul 5 2))]
     [SQUARE (add 5 1)]
     [MUL (add 5 1) (add 5 1)]
          [ADD 5 1]
                    [ADD 5 1]
                                [SQUARE (mul 5 2)]
                                [MUL (mul 5 2) (mul 5 2)]
                                     [MUL 5 2]
                                               [MUL 5 2]
136

Что более или менее похоже на то, что книга иллюстрирует этот процесс.


Написание макросов такого типа в основном похоже на написание обычной процедуры, за исключением того, что

  • Вместо DEFINE вы используете DEFINE-MACRO.
  • В теле нет неявного BEGIN, поэтому вам нужно указать свое собственное, если у вас несколько выражений.
  • Выражение всего тела начинается с серьезного акцента.
  • Все экземпляры параметров начинаются с запятой.

Это Написание макросов схемы 101.

В общем, это немного глупо - устанавливать макросы на кого-то только в первой главе SICP.Но если вы говорите, что вам непомерно сложно модифицировать Racket для выполнения того, что вы хотите (а есть те, кто вообще не использует Racket), то вот альтернатива.

6
ответ дан 2 November 2019 в 23:58
поделиться