2014-10-24 2 views
2

Если я сталкиваюсь с примитивной процедурой, всегда ли использую базовую схему?Можно ли переопределить «применить» в схеме?

Предполагая, что я это сделаю, как бы я мог повторно применить применение интерпретатора схемы для интерпретации себя?

(define apply-1 

    (lambda (proc args) 

    (cond ((primitive? proc) 
      (apply proc args)) <-- How would I reimplement this 
      ((eq? (car proc) 'closure) 
      (eval (cadr (cadr proc)) 
        (bind (car (cdr proc)) args (caddr proc)))) 
      (else error)))) 

ответ

1

Primitive-apply - это клей между тем, как примитив в вашем интерпретаторе реализован с базовой реализацией. Использование хостов apply для применения примитивов, которые действительно являются процедурами в хост-системе, - это трюк. Вы не можете сделать хост apply, но вы можете сделать примитив interpreter по-разному, что делает меньше или поддерживает другие способы пакетных примитивов. Например.

;; define representations for primitives 
(define prim-cons (list 'cons)) ; system unique 
(define prim-car (list 'car)) 
... 

;; define primitive? 
(define (primitive? proc) 
    (or (eq? proc prim-cons) 
     (eq? proc prim-car) 
     ...)) 

;; define primitive apply 
(define (primitive-apply proc args) 
    (cond ((eq? proc prim-cons) args) 
     ((eq? proc prim-car) (caar args)) 
     ...)) 

;; boot environment 
(define primitive-environment 
    (list (cons #t prim-true) 
     (cons #f prim-false) 
     (cons '() prim-null) 
     (cons 'cons prim-cons) 
     (cond 'car prim-car) 
     ...)) 

Факт использование apply просто упрощение, так как фактическая примитивная процедура разрешенного объект. Это не всегда должно быть так. Представьте себе, мы стараемся оптимизировать его немного:

;; define representations for primitives 
(define prim-cons (list 'cons)) ; system unique 
(define prim-car (list 'car)) 

;; make a list of primitives and their implementation 
(define primitives 
    (list (cons prim-cons values) 
     (cons prim-car caar))) 

;; define primitive? 
(define (primitive? proc) 
    (assq proc primitives)) 

;; make apply-primitive 
(define (apply-primitive proc args) 
    ((cdr (primitive? proc)) args)) 

Еще много шаблонного .. Почему бы не переместить весь примитив-лист в окружающую среду.

;; make tags 
(define *primitive* (list 'primitive)) 
(define *constant* (list 'constant)) 

;; make a list of primitives and their implementation 
(define boot-env 
    (list (list* 'cons *primitive* values) 
     (list* 'cons *primitive* caar) 
     ... 
     (list* #f *constant* #f) 
     (list* #t *constant* #t))) 

;; verify type 
(define (is-type? x type) 
    (and (pair? proc) 
     (eq? (car proc) type))) 

;; define primitive? 
(define (primitive? proc) 
    (is-type proc *primitive*)) 

(define (constant? x) 
    (is-type x *constant*)) 

;; make apply-primitive 
(define (apply-primitive proc args) 
    ((cdr proc) args)) 

Теперь. Для составных процедур у нас есть только аналогичный тег. eval сам становится очень маленьким, так как вы можете даже иметь *special-form* в своей среде, что делает что-то подобное, делая ваш eval просто анализ случаев между типами значений, которые вы оцениваете, а не особыми случаями.

Одна из моих соображений о apply заключалась в том, что я хотел, чтобы мой apply был вызван, когда вы вызываете процедуру apply из интерпретатора. Вы можете использовать apply, но apply действительно нужно обрабатывать apply. Вы встретите ту же странную вещь, когда попытаетесь применить также eval.

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