6.001 Spring 1997

Exam Question Handout

We've introduced a lot of experimental material this semester. In order to help you prepare for the parts of the final exam that deal with Java, we've prepared this handout. There will be no more than two questions on the exam that deal with Java, out of about 10 questions. Please do not put an extraordinary amount of effort into studying for this part of the exam. Instead, please read this handout carefully and use it to guide your studies.

You must bring this handout with you to the exam!

You should also bring the Java text with you to the exam, and are welcome to refer to it at any time.

Java and Object-Oriented Programming

You should be able to

  1. convert straightforward object-oriented Scheme code into Java and vice versa
  2. explain any problems you encounter doing this conversion
  3. read and understand the documentation for (simple) Java classes
  4. write very simple methods in Java
  5. understand the basic ideas of classes, objects, inheritance, and access restrictions (private, protected, etc.)

Decaf Java-in-Scheme

Ben Bitdiddle and Louis Reasoner are discussing adding a new special form to Scheme, (RETURN <expression>), which is like the "return" expression in Java—it causes the current procedure to end and return the specified value. Ben points out that this is introducing a control construct into Scheme. So the metacircular evaluator will have to be rewritten using the same trick that was used to write the Decaf Java-in-Scheme interpreter—each of the evaluator’s action procedures will need to take a NEXT argument to call instead of returning a value:

(define (eval exp env next)
  (cond ((self-evaluating? exp) (next exp))
        ((quoted? exp) (next (text-of-quotation exp)))
        ((variable? exp) (lookup-variable-value exp env next))
        ...
        ((if? exp) (eval-if exp env next))
        ...
        ((application? exp) (eval-application exp env next))
        (else (error "Unknown expression type -- EVAL" exp))))

Ben points out that if you do that, Scheme’s action procedures and the action procedures in Decaf Java-in-Scheme look very similar:

(define (eval-if exp env next)
  (eval (if-predicate exp) env
    (lambda (pred)
      (if (true? pred)
          (eval (if-consequent exp) env next)
          (eval (if-alternative exp) env next)))))

(define (j-eval-if exp env next)
  (j-eval (if.predicate exp) env
    (lambda (pred)
      (cond ((eq? pred #T)
             (j-eval (if.consequent exp) env next))
            ((eq? pred #F)
             (j-eval (if.alternative exp) env next))
            (else (error "IF: Not a boolean value"))))))

Louis says that APPLY and CALL still look very different:

Scheme’s Code for Apply

(define (eval-application exp env next)
  (eval (operator exp) env
    (lambda (procedure)
      (list-of-values (operands exp) env
        (lambda (args)           
          (apply procedure args next))))))

(define (apply procedure arguments next)
  (cond ...
        ((compound-procedure? procedure)
         (eval-sequence
          (procedure-body procedure)
          (extend-environment (procedure-parameters procedure)
                              arguments
                              (procedure-environment procedure))
          next))
        (else (error "Unknown procedure type -- APPLY" procedure))))

 

Decaf Scheme-In-Java’s code for Call

(define (j-eval-call exp env next)
  (j-eval-in-order (call.operands exp) env
    (lambda (operands)
      (method-lookup (call.operator exp) (map get-type operands) env
        (lambda (method object class)

         (let ((params (method.params method))
               (signature (method.signature method))
               (labels *labels*))
           (define (done val)
             (let ((result-type-name
                    (signature.result-type signature)))
               (set! *labels* labels)
               (next
                (if (eq? 'VOID result-type-name)
                    '()
                    (coerce val (lookup-class result-type-name))))))
           (add-label! '*RETURN-LABEL* done)
           (j-eval (method.body method)
                   (j-extend-environment
                    (make-frame 'BINDINGS
                                (make-bindings
                                 (map parameter.name params)
                                 (map parameter.type params)
                                 (map coerce
                                      (map get-self operands)
                                      (map lookup-class
                                           (signature.arg-types
                                            signature)))))
                    (basic-environment
                     (if (static-method? method)
                         class
                         (coerce (object.this object) class))))
                   done)))))))

Ben says that the differences aren’t really as big as they seem. In fact, he says, with only a very small amount of work you could simply rename J-EVAL-CALL to EVAL-APPLICATION, it would work just fine, and it would have everything needed to make the new RETURN special form work! 

 

Ben is partly right (his definition of "small amount of work" is questionable). The work required is to rewrite the procedures used by J-EVAL-CALL that aren’t currently defined in M-EVAL. Ben agrees to write the hardest of these procedures:

(define (basic-environment procedure)
  (procedure-enviroment procedure))

(define (coerce value type) value)

(define (j-extend-environment frame env)
  (extend-environment (frame.names frame)
                      (frame.values frame)
                      env))

(define (get-self value) value)

(define (method.body procedure)
  ;; Decaf Java-in-Scheme expects a single expression in the body, but
  ;; Scheme allows any number of expressions.
  `(BEGIN ,@(procedure-body procedure)))

(define (object.this object) object)

(define (parameter.name param) param)

That just leaves a handful of easy ones for Louis to worry about: 

add-label!
call.operands
call.operator
get-type
j-eval
j-eval-in-order
lookup-class
make-bindings
make-frame
method.params
method.signature
parameter.type
signature.arg-types
signature.result-type
static-method?
 

Louis agrees to take a look at that (grumbling a bit because he has to implement more procedures than Ben). As he leaves, he mutters something about asking some of his friends to help him out over at the athletic center.