views:

157

answers:

2

Python loop statements may have an else clause which is executed if and only if the loop is not terminated by a break. In other words, when the condition becomes False (with while) or when the iterator is exhausted (with for).

Does this loop-else construct originate from another language (either theoretical or actually implemented)? Has it been taken up in any newer language?

Maybe I should ask the former of Guido, but surely he is too busy for such a futile inquiry. ;-)

Related discussion and examples: Pythonic ways to use ‘else’ in a for loop

+4  A: 

A similar feature is found in Common Lisp's LOOP macro, described here by Peter Seibel:

...LOOP provides two keywords, initially and finally, that introduce code to be run outside the loop's main body.

After the initially or finally, these clauses consist of all the Lisp forms up to the start of the next loop clause or the end of the loop. All the initially forms are combined into a single prologue, which runs once, immediately after all the local loop variables are initialized and before the body of the loop. The finally forms are similarly combined into a epilogue to be run after the last iteration of the loop body. Both the prologue and epilogue code can refer to local loop variables.

The prologue is always run, even if the loop body iterates zero times. The loop can return without running the epilogue if any of the following happens:

  • A return clause executes.
  • RETURN , RETURN-FROM, or another transfer of control construct is called from within a Lisp form within the body...

For example, part of a Python sample found in the linked question:

for v in known_variables:
    if self.bindings[v] is cell:
        return v
else:
    raise CannotSimplify

might look something like this:

(loop for v in known-variables
  when (eq (gethash v (slot-value self bindings)) cell)
  do (return v)
  finally (signal cannot-simplify))

Another observation:

Common Lisp's condition system is also unique. Someone, once, asked where it came from and was pointed to Kent Pitman's paper, where he says got it from Maclisp. Similarly, Common Lisp's weird-looking FORMAT function apparently came from Multics via Dan Weinreb.

The common thread is that language features don't tend to follow from the ancestor language that most inspired this language, but are taken by individuals who loved them to whatever new language they're working on. So if you want to find out the actual source of Python's for-else, I'd look for who added it, and see what language they worked on prior to that.

Ken
+3  A: 

I just came across a pretty good lead buried in the comments of this far more general question. User ΤΖΩΤΖΙΟΥ wrote:

Anyone remember the FOR var … NEXT var … END FOR var of Sinclair QL's SuperBasic? Everything between NEXT and END FOR would execute at the end of the loop, unless an EXIT FOR was issued. That syntax was cleaner :)

An OCR rendition of Sinclair QL User Guide happens to float on the internet. It reads:

A NEXT statement may be placed in a loop. It causes control to go to the statement which is just after the opening keyword FOR or REPeat. It should be considered as a kind of opposite to the EXIT statement. By a curious coincidence, the two words NEXT and EXIT both contain EXT. Think of an EXTension to loops and:

  • N means "Now start again"
  • I means "It's ended"

A fascinating example follows:

The sheriff has a gun loaded with six bullets and he is to fire at the bandit but two more conditions apply:

  1. If he hits the bandit he stops firing and returns to Dodge City.

  2. If he runs out of bullets before he hits the bandit, he tells his partner to watch the bandit while he (sheriff) returns to Dodge City.

100 REMark Western FOR with Epilogue
110 FOR bullets = 1 TO 6
120   PRINT "Take aim"
130   PRINT "FIRE A SHOT"
140   LET hit= RND(0 TO 1)
150   IF hit = 1 THEN EXIT bullets
160 NEXT bullets
170   PRINT "Watch Bandit"
180 END FOR bullets
190 PRINT "Return to Dodge City"

So, under a different (and arguably less disturbing) syntax, it's exactly the same semantics.

Wikipedia tells us that the Sinclair QL launched in February 1984 as the successor to the Sinclair ZX Spectrum, but failed to achieve commercial success.

Aristide
+1 a gem of a post
I. J. Kennedy