[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
What should we DO?
- To: (BUG LISP) at MIT-MC, NIL at MIT-MC, (BUG LISPM) at MIT-MC
- Subject: What should we DO?
- From: KMP at MIT-MC (Kent M. Pitman)
- Date: Sun, 13 Apr 80 01:54:00 GMT
- Cc: H at MIT-MC, KMP at MIT-MC, HENRY at MIT-MC, RMS at MIT-MC
- Cc: MOON at MIT-MC
- Original-date: 12 APR 1980 2054-EST
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:
... 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.
ps - apologies for multiple copies ... i wish i knew how to make that
not happen ...