From: Jim Cheng
Subject: return-from in Lisp?
Date: 
Message-ID: <39A0A454.5B8BD318@yahoo.com>
 Could anyone told me the useage of return-from in lisp ? for example,

(defun func_name1(

   .....

   (return-from func_name2 expression)
)

Is it necessary that func_name2  the same as func_name1 ?

If I just use
   (return expression)
or (expression)
what is the difference between return  and return-from ?

Thanks!

Jim

From: Erik Naggum
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <3175845293162035@naggum.net>
* Jim Cheng <·······@yahoo.com>
| Could anyone told me the useage of return-from in lisp?

  Please see the Common Lisp Standard.  A browsable version is at
  <URL:http://www.xanalys.com/software_tools/reference/HyperSpec/>

#:Erik
-- 
  If this is not what you expected, please alter your expectations.
From: Coby Beck
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <966878529203@NewsSIEVE.cs.bonn.edu>
Jim Cheng <·······@yahoo.com> wrote in message ······················@yahoo.com...
|
|  Could anyone told me the useage of return-from in lisp ? for example,
|
| (defun func_name1(
|
|    .....
|
|    (return-from func_name2 expression)
| )
|
| Is it necessary that func_name2  the same as func_name1 ?
|
| If I just use
|    (return expression)
| or (expression)
| what is the difference between return  and return-from ?
|

I find that return-from is rarely a desirable thing to use and it most often indicates
a misunderstanding of the basic fact of lisp that every form already returns something
in lisp.

eg:
(defun foo(arg)
    (let ((answer nil))
        (setf answer (* 2 arg))
        (return-from 'foo answer)))

is a typically non-lisp way of thinking and is functionally equivalent to:
(defun foo(arg)
    (* 2 arg))

Not to say there are no legitimate uses, but are you sure you need it?  If so, Eric has
already pointed you to the HyperSpec.

Coby
From: Coby Beck
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <966887903847@NewsSIEVE.cs.bonn.edu>
Coby Beck <·····@mercury.bc.ca> wrote in message
·················@NewsSIEVE.cs.bonn.edu...
|
| Not to say there are no legitimate uses, but are you sure you need it?  If so, Eric
has
| already pointed you to the HyperSpec.
|
| Coby

Sorry, that should, of course, be "Erik".....
From: Frode Vatvedt Fjeld
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <2hya1qla6d.fsf@dslab7.cs.uit.no>
Jim Cheng <·······@yahoo.com> writes:

> Could anyone told me the useage of return-from in lisp ?

I find it sometimes useful to end a search conditionally, something
like this (not tested, nor useful):

(defun find-here-or-there (item here there)
  "Find ITEM in a list HERE or THERE, or return NIL if
ITEM is not found either HERE or THERE."
  (loop for i in here
     when (equal i item)
     do (return-from find-here-or-there here))
  (loop for i in there
     when (equal i item)
     return there
     finally (return nil)))

> what is the difference between return and return-from ?

RETURN returns from the closest block named nil. In the above example
you can see that the first RETURN-FROM returns from the named
function. The last RETURN returns from the nil-named block set up by
the enclosing LOOP, which -- it being the last form in the function --
becomes the return-value of the function also.

-- 
Frode Vatvedt Fjeld
From: Raffael Cavallaro
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <raffael-769D57.00483222082000@news.ne.mediaone.net>
In article <··············@dslab7.cs.uit.no>, Frode Vatvedt Fjeld 
<······@acm.org> wrote:

>> Could anyone told me the useage of return-from in lisp ?
>
>I find it sometimes useful to end a search conditionally, something
>like this (not tested, nor useful):


Here's an example where you use return-from to break out of an inner 
loop when a condition is met and the rest of the loop range doesn't need 
to be processes (i.e., you've already found what you're looking for).

(defun primes(start end)
  (loop for i from start to end do
        (block inner-loop
          (loop for j from 2 to i do
                (cond ((and (= (mod i j) 0) (/= i j)) (progn
                                                        (format t "~A is 
~A times ~A.~%" i j (/ i j))
                                                        (return-from 
inner-loop)))
                      ((= i j) (format t "~A is a prime number.~%" 
i)))))))





? (primes 1 10)
2 is a prime number.
3 is a prime number.
4 is 2 times 2.
5 is a prime number.
6 is 2 times 3.
7 is a prime number.
8 is 2 times 4.
9 is 3 times 3.
10 is 2 times 5.
nil
?

-- 

Raffael Cavallaro, Ph.D.
·······@mediaone.net
From: Tim Bradshaw
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <ey3aee51rw3.fsf@cley.com>
* Raffael Cavallaro wrote:

> Here's an example where you use return-from to break out of an inner 
> loop when a condition is met and the rest of the loop range doesn't need 
> to be processes (i.e., you've already found what you're looking for).

Something I also do is this:

 (defun escape (escaper &optional value)
   (funcall escaper value))

 (defmacro with-escape ((ev) &body body)
   (let ((name (gensym)))
     `(block ,name
	(let ((,ev #'(lambda (val)
		       (return-from ,name val))))
	  (declare (dynamic-extent ,ev))
	  ,@body))))

 (defun search-it (x)
   (with-escape (e)
     (searchit-1 x e)))

 (defun search-it-1 (x e)
   ... 
   (search-it-1 ...)
   ...
   (when x
     (escape e))
   ...)

Which is quite a nice way of escaping from a deep recursion.  THROW
and CATCH is a more conventional way, of course: I kind of like this
way but I'm not sure why.

--tim
From: Steven M. Haflich
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <39A2A17D.82B57FB7@pacbell.net>
Tim Bradshaw wrote:
> ... 
> Which is quite a nice way of escaping from a deep recursion.  THROW
> and CATCH is a more conventional way, of course: I kind of like this
> way but I'm not sure why.

I don't know where you got the information that CATCH/THROW are
more conventional than BLOCK/RETURN-FROM, unless you are describing
your own practice.  Anyway, both are used on your behalf in the
expansions of standard CL macros.

The simple difference between these constructs (as Tim surely knows)
is that CATCH/THROW are dynamic constructs while BLOCK/RETURN-FROM
are lexical constructs.  It is good practice to use lexical constructs
where possible, since dynamic constructs violate referential
transparency (the code refers to things that aren't visible to a
walker or reader of the code).  Violating referential transparency
means the compiler might not be able to do as good a job optimizing,
and a human might have a harder time understanding, debugging, and
maintaining the code.  Both human and compiler can find the target
BLOCK of a RETURN-FROM merely by scanning outwards through surrounding
lexical contours.  Neither human nor compiler can necessarily find
the innermost CATCH because that CATCH my be wrapped by code in another
file or system, or which might not even have been written yet, or
which is not apparent because the CATCH/THROW tag values may be
computed at run time.
From: Tim Bradshaw
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <ey37l991b3n.fsf@cley.com>
* Steven M Haflich wrote:

> I don't know where you got the information that CATCH/THROW are
> more conventional than BLOCK/RETURN-FROM, unless you are describing
> your own practice.  Anyway, both are used on your behalf in the
> expansions of standard CL macros.

I was thinking of the trick of using a closure to capture the lexical
context of the RETURN-FROM, so it can be used anywhere inside the
*dynamic* scope of the form, in a way that I think CATCH/THROW would
more normally be used.  But as you say I may be wrong about that...

--tim
From: Kent M Pitman
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <sfwya1pyyrf.fsf@world.std.com>
Tim Bradshaw <···@cley.com> writes:

> * Steven M Haflich wrote:
> 
> > I don't know where you got the information that CATCH/THROW are
> > more conventional than BLOCK/RETURN-FROM, unless you are describing
> > your own practice.  Anyway, both are used on your behalf in the
> > expansions of standard CL macros.
> 
> I was thinking of the trick of using a closure to capture the lexical
> context of the RETURN-FROM, so it can be used anywhere inside the
> *dynamic* scope of the form, in a way that I think CATCH/THROW would
> more normally be used.  But as you say I may be wrong about that...

I think a survey of usage practice is probably the wrong thing to worry
about.

Lexical scoping (i.e., block/return-from) is generally safer than catch/throw
because it's easier to show it can't fall victim to accidental shadowing.

I would not encourage someone to use catch-throw unless they really had a
situation in which caller and callee are written by different people, or, 
at least, for uncoordinated purposes so that the two cannot be coordinated
by use of block/return-from.  

(There may also be some efficiency reasons for choosing CATCH/THROW but that
would depend greatly on the implementation and on the cost of the setup
and the cost of the throw and the probability of the throw actually being
done.  I could see the block setup taking longer, and perhaps even cosing
in some cases, though that's not a certainty by any means.  As with most
efficiency issues, the uses of one implementation or the other should be
hidden in a macro so it can be changed easily without affecting the main 
textual body of code.)
From: Steve Long
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <39ACB6D1.E5DD3213@isomedia.com>
Loop-finish inside a Loop is great for the more trivial cases.

sl
From: Lieven Marchand
Subject: Re: return-from in Lisp?
Date: 
Message-ID: <m3wvh95iws.fsf@localhost.localdomain>
Raffael Cavallaro <·······@mediaone.net> writes:

> Here's an example where you use return-from to break out of an inner 
> loop when a condition is met and the rest of the loop range doesn't need 
> to be processes (i.e., you've already found what you're looking for).
> 
> (defun primes(start end)
>   (loop for i from start to end do
>         (block inner-loop
>           (loop for j from 2 to i do
>                 (cond ((and (= (mod i j) 0) (/= i j)) (progn
>                                                         (format t "~A is 
> ~A times ~A.~%" i j (/ i j))
>                                                         (return-from 
> inner-loop)))
>                       ((= i j) (format t "~A is a prime number.~%" 
> i)))))))

I wrote something similar just yesterday.

It can be shortened a bit by the NAMED option of LOOP.
(loop named inner ... (return-from inner) ....)

-- 
Lieven Marchand <···@bewoner.dma.be>
Lambda calculus - Call us a mad club