[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Internal definitions as a combination of LETREC's and LET*'s.



I would like to shift the current topic of this news group to an issue
of Scheme language design: the meaning of internal definitions.  I
contrast two interpretations of internal definitions:

	[1] internal definitions as LETREC's, and
	[2] internal definitions as a combination of LETREC's and LET*'s.

R3RS describes internal definitions in Section 5.2.2.  Some Scheme
implementations permit definitions to occur at the beginning of the
syntactic entity <body>, and are simply a syntactic variation of
LETREC.  In my opinion, they are an important variation as they reduce
the number of paratheses and make programs more readable.

Let me remind readers of the definition of LETREC of Section 7.3.  It
is equivalent to the following combinations of LET's and SET!'s:

(LETREC ((<var-0> <init-0>)
              ...
         (<var-n> <init-n>))
  <body>)
         ==>
(LET ((<var-0> <undefined>)
           ...
      (<var-n> <undefined>))
  (LET ((<temp-0> <init-0>)
              ...
        (<temp-n> <init-n>))
    (SET! <var-0> <init-0>)
            ...
    (SET! <var-n> <init-n>)
    <body>))

The second LET is there to ensure the property that the init
expressions are evaluated in an arbitrary order.  That is, no init
expression can depend of the value of any other one.  Thus the
following is incorrect.

(LAMBDA (X)
  (DEFINE A 4)
  (DEFINE B (* A A))
  (+ A (* X B)))

Yet at top level, it is okay to define values in terms of other
definitions.  An obvious way of making internal definitions behave
more like top level definitions, is to specify the order in which the
init bodies are evaluated.  I call this interpretation internal
definitions as a combination of LETREC's and LET*'s; a definition
becomes equivalent to the following combinations of LET's and SET!'s:

(LET ()
  (DEFINE <var-0> <init-0>)
            ...
  (DEFINE <var-n> <init-n>)
  <body>)
         ==>
(LET ((<var-0> <undefined>)
             ...
      (<var-n> <undefined>))
  (SET! <var-0> <init-0>)		; init's must be evaluated
          ...				; in the order presented.
  (SET! <var-n> <init-n>)
  <body>)

Aside from making internal definition behave more like top level
definitions, I think this meaning of internal definitions reduces the
number of parentheses, and makes programs more readable.  What's your
opinion? 
John