Wizard
Wizard

Reputation: 22083

Define a primitive apply with purely scheme procedures

In SICP's chapter 3.1.1 Mutation is just assignment,

the cons is represented purely in terms of procedures:

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

and in chapter 4, a primitive eval is defined purely as well as 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))))

However, the book did not try to define a primitive-apply, instead wrap the builtin apply as

We have assumed instead that we have saved a reference to the underlying apply by doing (define apply-in-underlying-scheme apply)

In the 4.1 Metalinguistic abstraction, the illustration take apply as granted as well as the builtin cons, car and cdr.

How could define a primitive apply ?

Upvotes: 0

Views: 241

Answers (1)

alinsoar
alinsoar

Reputation: 15793

You do not need to define a primitive-apply. This comes from the language that you use to implement the evaluator.

In case you work with a meta-circular evaluator the primitive-apply comes inside the scheme system that you use (for example, mit-scheme, guile, etc provides you an apply). In case that you implement a language in some other language apart from scheme, like C, the primitive-apply comes written in C.

For example, if you add 2 numbers in the target language, to use the + operator from C to compute the result, the primitive-apply needs first of all to convert the representation of numbers of target language in C-like representation and after that to apply the primitive + (from C) and to convert the result back to target language. This result will be returned in the target language by the primitive-apply.

The idea is that the implementation of the language made in C will know the representation of objects in target language and will be able to convert that representation to a similar representation that will be recognized by the C code (try to see how big numbers are implemented in some implementation and what happens internally when you add 2 big numbers with an implementation that uses gmp lib). See for example how gmp is implemented in emacs lisp, what happens when you evaluate (+ a b) in emacs/gnu...

You need to define only the apply function in the target language, that you implement.

On the other hand I do not understand why you combined the question with the issue with different implementations of the constructor for lists.

Upvotes: 2

Related Questions