CPS 343/543 Lecture notes: Statements and side effects



Coverage: [EOPL] §3.9 (pp. 120-123)


Make our language statement-oriented

  • so far our language has been expression-oriented meaning it works by returning values
  • we instrument our interpreter define a statement-oriented language meaning a program is a statement and works by side effect (printing values)
  • all else is same as previous language
  • retain
      denoted value = ref(expressed value)
      expressed value = number + procval
  • see new grammar and abstract-syntax in Fig. 3.23 on p. 121
  • see examples of blocks on p. 120
  • see execute-program and execute-statement in Fig. 3.24 on p. 123


Notables

  • uses Scheme for-each to implement compound statements
  • uses named let to implement while statement
  • (let name ((var val) ...)
       exp_1 exp_2 ...)
    
    is semantically equivalent to
    ((letrec ((name (lambda (var ...) exp_1 exp_2 ...)))
       name) val ...)
    
    for example,
    (let ((n 0))
      (let loop ()
        (if (< n 10)
            (begin
              (display n)
              (newline)
              (set! n (+ n 1))
              (loop)))))
    
    (newline)
    
    (let ((n 0))
      (letrec ((loop (lambda ()
                       (if (< n 10)
                           (begin
                             (display n)
                             (newline)
                             (set! n (+ n 1))
                             (loop))))))
        (loop)))
    
    both outer let's have the same effect; this code prints the numbers from 0 to 9 (one per line) twice with a newline in between

    see [TSPL] Chapter 5, §5.4, p. 100 for more information

    therefore,
    (while-statement (exp statement)
       ;; called the "named let"
       (let loop ()
          ;; one-armed if helps us avoid returning an arbitrary value
          (if (true-value? (eval-expression exp env))
             (begin
                (execute-statement statement env)
                   (loop)))))
    
    is equivalent to
    (while-statement (exp statement)
       ((letrec ((loop (lambda ()
          (if (true-value? (eval-expression exp env))
             (begin
                (execute-statement statement env)
                   (loop))))))
          loop)))
    
  • implementation of while statement also uses the one-armed if to avoid returning an arbitrary value


eval/apply in Scheme

    eval and apply are the heart of any interpreter.

    eval is the Scheme primitive analog of eval-expression procedure in your interpreter. eval takes an expression and environment as arguments.
    ;; (define f (lambda (x) (cons x ())))
    (define f (list 'lambda '(x) (list cons 'x '())))
    ((eval f) 5)
    
    eval enables meta-programming (i.e., the ability to write programs which write and evaluate other programs).

    apply is the Scheme primitive analog of the family of apply-* eval-expression procedures in your interpreter (e.g., apply-primitive, apply-procval, and so on). apply takes a procedure and its arguments as arguments.
    (apply + '(1 2 3))
    



    (regenerated from [SICP] Fig. 4.1, p. 364)


References

    [EOPL] D.P. Friedman, M. Wand, and C.T. Haynes. Essentials of Programming Languages. MIT Press, Cambridge, MA, Second edition, 2001.
    [SICP] H. Abelson and G.J. Sussman. Structure and Interpretation of Computer Programs. MIT Press, Cambridge, MA, Second edition, 1996.

Return Home