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

What should we DO?



RMS - doing (PROG name () (DO ...)) seems rather inelegant --
 an idiom for achieving something conceptually different than what
 you were really asking for. Take for example:

   (PROG name
	 (DO
	  ... code that extends off page ...))

 you'd be forced to scan to the next page to see that name was referring
 really to the DO. This sort of reasoning is why we most of us use let rather
 than LAMBDA. So I certainly wouldn't advocate that DO-NAMED was redundant.

Moon - Clearly we aren't advocating making everything named -- just the
 constructs that do flow of control-hacking -- for such constructs need
 information about where to GO/RETURN to. Probably we need a DOTIMES that
 allows the capability and another flavor that doesn't -- ie, that becomes
 an invisible prog.

My personal feelings on this are that we should come up with consistent
rules about these things. Documentation is much simpler if you could
generalize in it. So I would prefer flushing old-DO in the longrun but
it's probably unworkable at present. There's no reason to leave ourselves
open to future problems of this sort by implementing something now without
thinking first -- which is why I advocated not allowing (DOTIMES n ...).
I was not advocating that (DOTIMES lab ...) be installed -- just allowing
for that contingency.

I now present my feelings on this issue of how DO/PROG could be done in order
this haggling, part of which I think comes out of the fact that these return
tags are tied up in PROG-ness and so on ... Suppose you had the following
primitives in Lisp:

(PROG-BODY ...) which evaluated all non-atomic stuff. Atoms were GO-tags.
 Returns () if you fall off the end. RETURN does not work from this form.

(PROG-RETURN-POINT form name) name is not evaluated. Form is evaluated and
 if a RETURN-FROM specifying name (or just a RETURN) were executed, control
 would pass to here. Returns the value of form if form returns normally or
 the value returned from it if a RETURN or RETURN-FROM is executed. [Note:
 this is not a [*]CATCH because it is lexical in nature and optimized out
 by the compiler. Also, a distinction between NAMED-PROG-RETURN-POINT
 and UNNAMED-PROG-RETURN-POINT might be desirable -- extrapolate for yourself
 how this would change things -- I'll just present the basic idea here.]

(ITERATE bindings test form1 form2 ...) like DO is now but doesn't allow
 return or goto. All forms are evaluated. GO does not work to get to any form
 in the iteration body.

So then we could just say that the definitions for PROG and DO might be
(ignore for now old-DO's -- they could, of course, be worked in if people
really wanted them but they have nothing to do with this argument) ...

 (PROG [ <tag> ] <bvl> . <body>)

  => (PROG-RETURN-POINT (LET <bvl> (PROG-BODY . <body>)) [ <tag> ])

 (DO [ <tag> ] <bind-specs> <tests> . <body>)

  => (PROG-RETURN-POINT (ITERATE <bind-specs> <tests> (PROG-BODY . <body>))
			[ <tag> ])

Other interesting combinations could be formed by those interested in them.
If these lower-level primitives were made available to the user, he needn't
feel tied to one of PROG/DO -- he can assemble an operator with the 
functionality he really wants. 

-kmp

ps - apologies for multiple copies ... i wish i knew how to make that
	not happen ...