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

RETURN-FROM inside a FINALLY



    Date: Fri, 15 Sep 89 20:56 EDT
    From: Barry Margolin <barmar@Think.COM>

	Date: Fri, 15 Sep 89 10:21 PDT
	From: Siskind.pa@xerox.com

	This is a CommonLisp question not necessarily a
	Symbolics question.

	I have code which looks something like:

	(loop named outer
	      collect (foo) into x
	      finally (loop for y in x
			    when (bar y)
			      do (return-from outer x))
		      (return nil))

	The idea is that the outer loop does some work and builds a
	list. When it is finished, the second loop in the finally
	clause munges over that result. If a certain criteria is met
	for any of the elements of the list, then the whole list is
	returned by the return-from. Otherwise the, outer loop returns
	nil. This works fine on both the L/G-machine and Ivory. When
	I compile this in Lucid I get an error telling me that
	there is no block named NIL when compiling (return-from outer x).
	I can get arround this by doing:

	(block outer
	 (loop collect (foo) into x
	       finally (loop for y in x
			     when (bar y)
			       do (return-from outer x))
		       (return nil)))

	which works fine but I don't know whether the first example is
	incorrect CommonLisp code or whether it is a problem with Lucid.
		Jeff
	-------

    First of all, Common Lisp (as defined by CLtL) doesn't include the fancy
    LOOP syntax; ANSI Common Lisp is expected to, though.

    What appears to be happening is that the NAMED clause is specifying the
    name for the BLOCK that LOOP creates, and this is overriding the default
    name of NIL; when leaving a named loop, you must use (RETURN-FROM <name>
    <val>).  Genera, however, creates a block named NIL *and* a block with
    the specified name, so that either (RETURN <val>) or (RETURN-FROM <name>
    <val>) will work.

    Your workaround seems OK.  You could also change the second (RETURN NIL)
    form to (RETURN-FROM OUTER NIL).

Yes, this is the preferred course.  In general to get around this
disparity, (1) don't use RETURN (or RETURN-FROM a block name of NIL) to
return from an unnamed LOOP when within any LOOP nesting, and (2) don't
assume that RETURN will return you from the innermost loop if it is
named.

    The draft ANSI LOOP spec isn't very clear about this.  In several places
    it says that a RETURN <val> clause is equivalent to DO (RETURN <val>),
    which implies that there should always be a block named NIL.  Lucid is
    pretty tricky about this -- if the loop is named, it translates a RETURN
    clause into the appropriate RETURN-FROM form.  I'm copying this response
    to the X3J13 Iteration Subcommittee to alert them to this ambiguity in
    the draft.

						    barmar


I did a little poking around at some source code and old documentation,
and it is clear that there was a divergence of sorts back in 1983 or
earlier, for which I may be partly to blame.  I will be following this
up with the appropriate parties.