Re: What should 'do' do?

From: Erik Ostrom <eostrom_at_ccs.neu.edu>
Date: Thu, 02 Mar 95 12:36:31 -0500

> (do ((x 5 (+ x 1)))
> ((> x 10) x)
> (if (= x 7) (define uu 88))
> (if (= x 8) (define uu 33))
> (if (= x 9) (display uu) (newline)))

It seems to me (after peering at R4RS a little) that this
expression is invalid. `define' may appear only at top level
or at the beginning of a <body> (section 5.2, "Definitions").
The consequent of an `if' isn't one. So it seems like the right
thing to do is to signal an error.

It would be valid to do something like
    (if (= x 7) ((lambda ()
                   (define uu 88))))
but that would make the question moot, since uu wouldn't be
visible from outside that lambda.

More likely, you would put the whole `do' expression in an
environment where UU is already defined (or define it as one
of the iteration values), and then use set! to assign to it.

This makes a lot of sense; the purpose of define is essentially
to declare a variable. Either the variable is bound in a given
environment or it isn't; that isn't dependent on program execution.
(This tends to be false at top level, since variables are declared
as their definitions are read in sequentially.)

Enough blather. If you WERE going to allow definitions inside
arbitrary expressions:

> Stk seems to return 89, whcih makes no sense to me. Two other
> interpreters take both the obvious posibilities, one complains of UU
> being redefined & prints out 33 and returns 11, the other simply
> errors on the 'display' claiming UU is an unbound variable.

89 seems indicative of a bug. 33/11 seems reasonable at first, but
if you look at the "Formal Semantics" section of R4RS (7.3) you'll
find `do' defined in terms of `letrec', in a way that I _think_
indicates UU should be unbound. Each time through the loop, it seems,
the previous iteration's environment goes away.

> Are there any documents more precise than R4RS? (Am I the only one who
> thinks this document is incredibly vague most of the time? For example,
> what does a '(BEGIN <definitions> ...)' actually look like?).

The formal syntax and semantics, while difficult (I've been writing
this message for nearly an hour now--it's been a good learning
experience), are not very vague, and can clear up a lot of this kind
of confusion. Unfortunately, I can't really find a complete answer
to this one. I THINK the intent is to allow you to sequence
definitions, like

  (begin
    (define i 2)
    (define j (* 2 i)))

... because otherwise internal definitions are defined in terms of
letrec, and the expressions can't refer to the variables.
Received on Thu Mar 02 1995 - 19:14:16 CET

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST