[plt-scheme] units

From: Robert Bruce Findler (robby at cs.uchicago.edu)
Date: Fri Oct 25 12:28:45 EDT 2002

There's a slightly more complicated explanation that might help to
reconcile the model in the paper and the implementation in Scheme.

In Scheme, recursive definitions are really shorthand for a sequence of
assignments. As an example, this:

  (letrec ([x <x-exp>]
           [y <y-exp>])
    <body-exp>)

is the same thing as this:

  (let ([x #<undefined>]
        [y #<undefined>])
    (set! x <x-exp>)
    (set! y <y-exp>)
    <body-exp>)

In the model (and in ML, on which the model is based), only "valuable"
expressions (ie, those beginning with "lambda" or those that are
constants) are allowed on the right-hand side of a definition, so you
don't need that more complex explanation of mututal recursion.
Nevertheless, to map units to Scheme, you need to use the set! version
of recursive definitions. So, the same thing happens in the body of a
unit, and this unit:

  (unit (import ...) (export ...)
     (define x ...)
     (define y ...))

is really the same thing as this one:

   (unit (import ...) (export ...)
     (define x #<undefined>)
     (define y #<undefined>)
     (begin
       (set! x ...)
       (set! y ...)))

If you think about the units in terms of the second form, each unit
really does have a single expression where all initialization happens
(that begin expression where the set!s happen) and when you combine two
units in a compound-unit, those expressions are combined with a begin.

In your example, we'd get this:

(define A
  (unit (import x y)
        (export)
        (begin (display x)
               (display y)
               0)))

(define B
  (unit (import)
        (export x y)
        (define x #<undefined>)
        (define y #<undefined>)
        (begin (set! x 1)
               (set! y 2))))

(define C
  (compound-unit 
    (import)
    (link 
     (Sa (a (Sb x) (Sb y)))
     (Sb (B)))
    (export)))

which (by the reduction rules) is the same as:

(define C
  (unit (import) (export)
    (define x #<undefined>)
    (define y #<undefined>)
    (begin (begin (display x)
                  (display y)
                  0)
           (begin (set! x 1)
                  (set! y 2)))))

If you had this definition of C (switching the order in the link
clause):

(define C
  (compound-unit 
    (import)
    (link 
     (Sb (B))
     (Sa (a (Sb x) (Sb y))))
    (export)))

you'd get this:

(define C
  (unit
    (import)
    (export)
    (define x #<undefined>)
    (define y #<undefined>)
    (begin (begin (set! x 1)
                  (set! y 2))
           (begin (display x)
                  (display y)
                  0))))

and you'd see 1 and 2 being printed out.

One other note, if you have a more complex unit, something like this:

(unit (import) (export)
  (define x <x-exp>)
  <do-some-work>
  (define y <y-exp>)
  <do-some-more-work>)

that is treated like this:

  (unit (import) (export)
    (define x #<undefined>)
    (define y #<undefined>)
    (begin
      (set! x <x-exp>)
      <do-some-work>
      (set! y <y-exp>)
      <do-some-more-work>))

Hope that helps.

Robby


Posted on the users mailing list.