Subject: Lack of EXITFOR

From: [email-masked] (Rob Thomas 890-7033 Mathematical Sciences Dept., Univ. of Alabama-Huntsville)
Date: Mon, 10 May 1993 13:38:05 -0700

Um, in situations where I don't want to spin through a whole loop after I've found the match I was looking for, I just put my loop in a separate this-none-this
verb with "return nsec;" or whatever inside the if structure. Yes it is 
inelegant programming technique, but the "return" does act, for all practical
purposes, like an exitfor in that case.

'Zat what you were looking for?
==== Rob.

---

From: Kent Pitman <[email-masked]>
Date: Mon, 10 May 1993 14:17:28 -0700

Date: 	Mon, 10 May 1993 13:38:05 PDT
   From: [email-masked] (Rob Thomas)

   Um, in situations where I don't want to spin through a whole loop after
   I've found the match I was looking for, I just put my loop in a separate 
   this-none-this verb with "return nsec;" or whatever inside the if structure. 
   Yes it is inelegant programming technique, but the "return" does act, 
   for all practical purposes, like an exitfor in that case.

Thanks for the suggestion.  As it happens, I knew I could do this, and
wasn't really looking for a solution so much as to be on record that
the current situation is a loser, in hopes that one day Pavel will see
fit to fix it.  A separate verb is what I'd do if the loop were very
long or sufficiently purposeful to deserve its own name.  I do't
expect this particular one to be; I just think it's exemplary of a
problem that wants a graceful solution.

I was told that Pavel had given in to people who purported to represent
"goodness and purity of essence" in language design and who had claimed
that EXITFOR was the Devil's work, and that he had bought into that 
religion.  On the assumption that this was so, I was providing counterpoint.

As a language designer myself, I'm sensitive to the issue of "what the
language should provide" and "what the user should be able to do on
his own".  As a technical matter, anything above a Turing Machine
could be lumped in the latter category, but I like to have higher standards.
Nearly every well-thought-out language I can think of (e.g., Lisp, Teco, 
and HyperTalk--just to name a few) gets this right; MOO should, too.

---

From: Pavel Curtis <[email-masked]>
Date: Mon, 10 May 1993 15:35:00 -0700

> Date:	Mon, 10 May 1993 14:17:28 -0700
> From:	Kent Pitman <[email-masked]>
> 
> religion.

You were told wrongly; in fact, I attempted on this list some time ago to get
some help in designing a good such construct but was unsuccessful.  Take a look
in the archives (parcftp.xerox.com:pub/MOO/mail/MOO-Cows-199*.mail) for the
discussion of BREAK and CONTINUE, probably in 1992.

	Pavel

---

From: [email-masked] (H. Peter Anvin N9ITP)
Date: Mon, 10 May 1993 20:25:50 -0700

> discussion of BREAK and CONTINUE, probably in 1992.

How about an extended C-style:

	break <n>;
	continue <n>;

Where <n> marks the # of loops to break out of, may they be for, while
or repeat loops (defaults to 1).

>From what I heard from people, this construction would be a Good
Thing.

Also, a in-db comment statement would definitively be nice.

	/hpa

For the benefit of the uninitiated:

Break equals an unconditional jump to just after <n> loop termination
statements (net, i.e. minus any new loop initiation statements).

Continue equals an unconditional jump to just *before* the <n>:th net
loop termination statement.

-- 
INTERNET:  [email-masked]    FINGER:    [email-masked]
BITNET:    HPA@NUACC      IBM MAIL:  36073 at IBMX400
HAM RADIO: N9ITP, SM4TKN  NeXTMAIL:  [email-masked]
Most inappropriatly named startup command, winner:  Microsoft Windows

---

From: Greg Hudson <[email-masked]>
Date: Mon, 10 May 1993 22:38:21 -0700

> You were told wrongly; in fact, I attempted on this list some time
> ago to get some help in designing a good such construct but was
> unsuccessful.

I read through some of the archives on parcftp, and was quite
interested to read this discussion and other discussions related to
the language.  They reminded me of several things I need to adjust or
add in Coldmud.  I disagreed sharply with some of the writers on how
to resolve some of the flaws in the C syntax (for instance, rather
than rename the '=' and '==' operators, I prefer to eliminate the
assignment expression in favor of an assignment statement), but it was
still valuble reading.  It alerted me, for instance, that I'll have to
think about break and continue in combination with forked tasks, and
that text dumps of the database should be fully parenthesized.

As for break and continue, I implemented them in Coldmud as they exist
in C.  There's no built-in way to break out of two loops at once.  If
I were to allow this, I'd probably go along with Stephen White and
just give break and continue a count argument, since it's the simplest
way.  I'm loathe to do so, though.  I've written perhaps 40,000
debugged lines of C code, and I've never yet used a goto to break out
of two loops at once.  In fact, it seems like MOO programmers have
done quite a bit of work without a 'break' or a 'continue' at all,
even if they don't like it.

--GBH

---

From: Mike O'Brien <[email-masked]>
Date: Mon, 10 May 1993 23:34:34 -0700

>even if they don't like it.

<Creak, snap, pop!>  This makes me feel reeeeely old, but:
BCPL, the predecessor language to C, which was used extensively
for application and system programming (especially at Xerox PARC),
defines "break" with a count argument.  So, historically at least,
it work just fine.

Mike O'Brien

---

From: Pavel Curtis <[email-masked]>
Date: Tue, 11 May 1993 16:01:13 -0700

> Date:	Mon, 10 May 1993 20:25:50 -0700
> From:	[email-masked] (H. Peter Anvin N9ITP)
> 

I have never liked this idea because it's so error-prone.  Once I add this, I
can no longer wrap an arbitrary piece of code in another layer of looping
without going through and adjusting the counts on all of the contained break
and continue statements.  I know that this was a problem for BCPL programmers
who used this construct.

> Also, a in-db comment statement would definitively be nice.

It doesn't seem to me that there's any problem with just using `string
statements':

		"This is a comment.";

	Pavel

---

From: Roger Crew <[email-masked]>
Date: Tue, 11 May 1993 17:25:09 -0700

Problems that I have with `break n' where n is an integer:

(a) I hate counting; silicon is much better at this than I am...

(b) I have, on occasion, changed the outer control structure of a loop
    (such things as changing a for into a while or changing a singly
    nested loop into a doubly nested loop, ...).  It bothers me that in
    such a situation a `break n' can silently change its meaning.  

    If the break were somehow implicitly tied to a particular loop statement 
    (via a label or iteration variable name (*)) then this wouldn't happen
     --- at worst, I'd get an error of some sort if I were to 
    blow away the loop statement.

>> In fact, it seems like MOO programmers have done quite a bit of
>> work without a `break' or a `continue' at all, even if they don't
>> like it.

This is true.  It's also true that the plain C `break' would take care
of about 90-95% of the cases where I've been unhappy.  For that
matter, it's also true that once we get an exception handling
mechanism (which I have reason to believe is also on the agenda), 
we won't need `break' at all (assuming you're not totally disgusted 
by the idea of raising an exception just to get out of a loop...
--- I myself consider that worse than using a 'return').

One can also argue that we've also gotten along quite nicely without
multiple inheritance.  I'm not sure what conclusions to draw from this,
however...

(*) Just to elaborate on this: with for loops, the iteration variable
serves as a perfectly good label (if you've got nested loops having 
the same iteration variable you're almost certainly doing something
wrong).  Using this for break statements solves the problem of having
to count:

   for i in ...
     for j in ...
       ...
       if (...)
         break i;
       endif
     endfor
   endfor

My point is that if one actually is going to go to the trouble of 
implementing `break n', one may as well do it this way instead and 
get something much less error-prone.

Making this work for while loops unfortunately requires more syntax,
though we can use something similar to the fork statement:

  while outer (pred)
    ...
    if (pred2)
      break outer;
    endif
    ...
  endwhile

Alternatively, we punt on adding new while syntax and force people 
to write things like

  for outer in [1..1000000000]
    if (!pred)
      break outer;
    endif 
    ...
    if (pred2)
      break outer;
    endif
    ...
  endfor

if they want multiple loop exits.  However, if one actually wants to go 
this route, I'd insist on having 
   for outer in [1..]
as a synonym for
   for outer in [1..$maxint]

--
Roger Crew
Internet:   [email-masked]
LambdaMOO:  Rog