Определите примитивное применение с чисто схемными процедурами - PullRequest
0 голосов
/ 16 января 2020

В главе SICP 3.1.1 Мутация - это просто присваивание ,

cons представлено исключительно в терминах процедур:

(define (cons x y)
  (define (dispatch m)
    (cond ((eq? m 'car) x)
          ((eq? m 'cdr) y)
          (else (error "Undefined
                 operation: CONS" m))))
  dispatch)

и в глава 4 , примитив eval определяется чисто так же, как и cons

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value exp env))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment exp env))
        ((definition? exp) (eval-definition exp env))
        ((if? exp) (eval-if exp env))
        ((lambda? exp)
         (make-procedure (lambda-parameters exp)
                         (lambda-body exp)
                         env))
        ((begin? exp) 
         (eval-sequence (begin-actions exp) env))
        ((cond? exp) (eval (cond->if exp) env))
        ((application? exp)
         (apply (eval (operator exp) env)
                (list-of-values (operands exp) env)))
        (else
         (error "Unknown expression type -- EVAL" exp))))

Однако в книге не пытались определить примитив-применение, вместо этого оберните встроенное применение as

Вместо этого мы предположили, что сохранили ссылку на базовое приложение, выполнив (define apply-in-underlying-scheme apply)

В 4.1 Metalinguistic abstraction на иллюстрации берется apply как предоставлено, а также встроенные cons, car и cdr.

Как можно определить примитив apply?

1 Ответ

2 голосов
/ 16 января 2020

Вам не нужно определять primitive-apply. Это происходит от языка, который вы используете для реализации оценщика.

В случае, если вы работаете с метакруглым оценщиком, primitive-apply входит в систему схем, которую вы используете (например, mit-схема, guile , et c предоставляет вам apply). В случае, если вы реализуете язык на каком-то другом языке, кроме схемы, такой как C, primitive-apply записывается в C.

Например, если вы добавите 2 числа на целевом языке, чтобы использовать оператор + из C для вычисления результата, primitive-apply необходимо прежде всего преобразовать представление чисел целевой язык в C -подобном представлении и после этого применить примитив + (из C) и преобразовать результат обратно в целевой язык. Этот результат будет возвращен на целевом языке primitive-apply.

Идея состоит в том, что реализация языка, сделанная в C, будет знать представление объектов на целевом языке и сможет конвертировать это представление к аналогичному представлению, которое будет распознаваться кодом C (попробуйте посмотреть, как большие числа реализованы в некоторой реализации и что происходит внутри, когда вы добавляете 2 больших числа с реализацией, которая использует gmp Lib). Посмотрите, например, как gmp реализован в emacs lisp, что происходит, когда вы оцениваете (+ a b) в emacs / gnu ...

Вам нужно определить только функцию apply в целевой язык, который вы реализуете.

С другой стороны, я не понимаю, почему вы объединили вопрос с проблемой с различными реализациями конструктора для списков.

...