From: Thomas Guettler
Subject: Returning from Function
Date: 
Message-ID: <amujf7$5uh$05$1@news.t-online.com>
Hi!

How can I use return with a variable?
The following does not work (Allegro 3.0.2)

(defun bigger2 (i)
   (let ((ret-bigger "bigger")
        (ret-smaller "smaller"))
     (if (> i 2)
         (return ret-bigger)
       (return ret-smaller))))


(bigger2 1) ; should return "smaller"

  thomas

From: Kaz Kylheku
Subject: Re: Returning from Function
Date: 
Message-ID: <cf333042.0209260848.5ea1d7a6@posting.google.com>
Thomas Guettler <···········@thomas-guettler.de> wrote in message news:<···············@news.t-online.com>...
> Hi!
> 
> How can I use return with a variable?
> The following does not work (Allegro 3.0.2)
> 
> (defun bigger2 (i)
>    (let ((ret-bigger "bigger")
>         (ret-smaller "smaller"))
>      (if (> i 2)
>          (return ret-bigger)
>        (return ret-smaller))))
> 
> 
> (bigger2 1) ; should return "smaller"

In this example you need not do anything special. You see both
branches of the IF form return their (possibly multiple) value, and
the IF form is the last one in the LET form, and the LET form returns
the (multiple) value of the last form. So simply write:

   (if (> i 2) ret-bigger ret-smaller)

That being said, there is a way to exit from a block in Lisp, using
the BLOCK construct. Blocks are identified by a symbol, which can be
NIL.

   (block nil
      ...  (return 42) ...)  ;; returns 42 from the
                             ;; closest enclosing NIL block

   (block :foo
      ...  (return-from :foo 42) ...) ;; returns 42 from 
                                      ;; enclosing :foo block

When you define a function using DEFUN, Lisp rewrites your code so
that it is surrounded by a BLOCK construct or equivalent. The symbol
used by that BLOCK construct is the same one as the name of your
function. So that you can write:

   (return-from bigger2 42) ;; return 42 from this function

Lastly, Lisp already has the function that you are trying to write,
and it is actually more general. Its name is MAX:

   (max 1 3 2) ==> 3

Hope this helps.
From: Pascal Costanza
Subject: Re: Returning from Function
Date: 
Message-ID: <3D92D4A4.6050707@web.de>
Thomas Guettler wrote:
> Hi!
> 
> How can I use return with a variable?
> The following does not work (Allegro 3.0.2)
> 
> (defun bigger2 (i)
>   (let ((ret-bigger "bigger")
>        (ret-smaller "smaller"))
>     (if (> i 2)
>         (return ret-bigger)
>       (return ret-smaller))))
> 
> 
> (bigger2 1) ; should return "smaller"

You don't need to use a return statement here. Just do the following:

(defun bigger2 (i)
   (let ((ret-bigger "bigger")
        (ret-smaller "smaller"))
     (if (> i 2) ret-bigger
         ret-smaller)))

or simpler:

(defun bigger2 (i)
   (if (> i 2) "bigger"
       "smaller"))

Almost all forms in Lisp have a value, and the if-form already returns 
the result of its second or third argument as a value.

If you really need to return something from the middle of a function, 
you should look at "block" and "return-from", or "catch" and "throw". 
("catch" and "throw" in Common Lisp are not for exception handling, as 
for example in Java.)

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Christian Nyb�
Subject: Re: Returning from Function
Date: 
Message-ID: <sik4rcd2igf.fsf@grace.uio.no>
Thomas Guettler <···········@thomas-guettler.de> writes:

> Hi!
> 
> How can I use return with a variable?
> The following does not work (Allegro 3.0.2)
> 
> (defun bigger2 (i)
>    (let ((ret-bigger "bigger")
>         (ret-smaller "smaller"))
>      (if (> i 2)
>          (return ret-bigger)
>        (return ret-smaller))))
> 
> 
> (bigger2 1) ; should return "smaller"
> 
>   thomas

Using return has no meaning unless there is a block surrounding the
return form.  Some forms have an implicit block named nil surrounding
the body of the form.  

See: 

http://www.franz.com/support/documentation/6.2/ansicl/dictentr/return.htm|

I suppose the following does what the above code was inteded to do:

(defun bigger2 (i)
  (let ((ret-bigger "bigger")
	(ret-smaller "smaller"))
    (if (> i 2)	
	ret-bigger	
      ret-smaller)))


The same using an unneccessary block:

(defun bigger2 (i)
  (block bigger
    (let ((ret-bigger "bigger")
	  (ret-smaller "smaller"))
      (if (> i 2)	
	  (return-from bigger ret-bigger)
	(return-from bigger ret-smaller)))))

What was your motivation for using return?
-- 
chr
From: Raymond Wiker
Subject: Re: Returning from Function
Date: 
Message-ID: <86k7l912h3.fsf@raw.grenland.fast.no>
···@sli.uio.no (Christian Nyb�) writes:

> Thomas Guettler <···········@thomas-guettler.de> writes:
> 
> > Hi!
> > 
> > How can I use return with a variable?
> > The following does not work (Allegro 3.0.2)
> > 
> > (defun bigger2 (i)
> >    (let ((ret-bigger "bigger")
> >         (ret-smaller "smaller"))
> >      (if (> i 2)
> >          (return ret-bigger)
> >        (return ret-smaller))))
> > 
> > 
> > (bigger2 1) ; should return "smaller"
> > 
> >   thomas
> 
> Using return has no meaning unless there is a block surrounding the
> return form.  Some forms have an implicit block named nil surrounding
> the body of the form.  

        Almost :-) 

        I'd say that using "return" has no meaning unless you have a
block named nil, somewhere. "return" is equivalent to "return-from
nil"; see the HyperSpec entry for "return".

        E.g, 

(defun bigger2 (i)
   (block nil
       (if (> i 2)
           (return "bigger")
           (return "smaller"))))

        On the other hand, it is probably *much* better to use
return-from with the block named after the function, which is implicitly
created by the defun:

(defun bigger2 (i)
   (if (> i 2)
       (return-from bigger2 "bigger")
       (return-from bigger2 "smaller")))


-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Thomas Guettler
Subject: Re: Returning from Function
Date: 
Message-ID: <amup9t$f1i$02$1@news.t-online.com>
Christian Nyb� schrieb:
> Thomas Guettler <···········@thomas-guettler.de> writes:
> 
> 
>>Hi!
>>
>>How can I use return with a variable?
>>The following does not work (Allegro 3.0.2)


My example was bad. The return will
be called at several places. Here the new:

(defun bigger2 (i)
   (let ((ret-bigger "bigger")
        (ret-smaller "smaller"))

     (if *other-mathematical-universe*
         return ret-bigger)

     (if *always-smaller*
         return ret-smaller)

     (if (> i 2)
         (return ret-bigger)
       (return ret-smaller))))
(bigger2 1)


> The same using an unneccessary block:
> 
> (defun bigger2 (i)
>   (block bigger
>     (let ((ret-bigger "bigger")
> 	  (ret-smaller "smaller"))
>       (if (> i 2)	
> 	  (return-from bigger ret-bigger)
> 	(return-from bigger ret-smaller)))))

This code from you looks good. I think it solves
the problem.

  thomas
From: Julian Fondren
Subject: Re: Returning from Function
Date: 
Message-ID: <76ea4fd3.0209260751.75ad7809@posting.google.com>
Thomas Guettler <···········@thomas-guettler.de> wrote in message news:<···············@news.t-online.com>...
> My example was bad. The return will
> be called at several places. Here the new:
> 
> (defun bigger2 (i)
>    (let ((ret-bigger "bigger")
>         (ret-smaller "smaller"))
> 
>      (if *other-mathematical-universe*
>          return ret-bigger)
> 
>      (if *always-smaller*
>          return ret-smaller)
> 
>      (if (> i 2)
>          (return ret-bigger)
>        (return ret-smaller))))
> (bigger2 1)

(defun bigger3 (i)
  (cond
    (*other-mathematical-universe* "bigger")
    (*always-smaller* "smaller")
    ((> i 2) "bigger")
    (t "smaller")))
From: Marco Antoniotti
Subject: Re: Returning from Function
Date: 
Message-ID: <y6c65wszuol.fsf@octagon.valis.nyu.edu>
Thomas Guettler <···········@thomas-guettler.de> writes:

> Christian Nyb� schrieb:
> > Thomas Guettler <···········@thomas-guettler.de> writes:
> >
> >>Hi!
> >>
> >>How can I use return with a variable?
> >>The following does not work (Allegro 3.0.2)
> 
> 
> My example was bad. The return will
> be called at several places. Here the new:
> 
> (defun bigger2 (i)
>    (let ((ret-bigger "bigger")
>         (ret-smaller "smaller"))
> 
>      (if *other-mathematical-universe*
>          return ret-bigger)
> 
>      (if *always-smaller*
>          return ret-smaller)
> 
>      (if (> i 2)
>          (return ret-bigger)
>        (return ret-smaller))))
> (bigger2 1)

Your previous version and the above cause an error in at least one CL
implementation (CMUCL), since you are using RETURN without
establishing a NIL block (whether this is a conforming behavior, I
have not checked).

Anyway,  as others have pointed out,  in CL a "form" just "returs" its
value or its "last" value (this description is an semplification).
E.g. your code above may be rewritten in one of the following three
ways.  I'd say the first one is the best version.

(defun bigger2 (i)
  (let ((ret-bigger "bigger")
	(ret-smaller "smaller"))
    
    (cond (*other-mathematical-universe* ret-bigger)
	  (*always-smaller* ret-smaller)
	  ((> i 2) ret-bigger)
	  (t ret-smaller))))


(defun bigger2 (i)
  (let ((ret-bigger "bigger")
	(ret-smaller "smaller"))
    
    (when *other-mathematical-universe*
      (return-from bigger2 ret-bigger))

    (when *always-smaller*
      (return-from bigger2 ret-smaller))

    (if (> i 2)
	(return-from bigger2 ret-bigger)
	(return-from bigger2 ret-smaller))))


(defun bigger2 (i)
  (let ((ret-bigger "bigger")
	(ret-smaller "smaller"))
    
    (when *other-mathematical-universe*
      (return-from bigger2 ret-bigger))

    (when *always-smaller*
      (return-from bigger2 ret-smaller))

    (if (> i 2) ret-bigger ret-smaller)))


Cheers


> 
> 
> > The same using an unneccessary block:
> > (defun bigger2 (i)
> >   (block bigger
> >     (let ((ret-bigger "bigger")
> > 	  (ret-smaller "smaller"))
> >       (if (> i 2)	
> > 	  (return-from bigger ret-bigger)
> > 	(return-from bigger ret-smaller)))))
> 
> This code from you looks good. I think it solves
> the problem.
> 
>   thomas
> 

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group        tel. +1 - 212 - 998 3488
715 Broadway 10th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA                 http://bioinformatics.cat.nyu.edu
                    "Hello New York! We'll do what we can!"
                           Bill Murray in `Ghostbusters'.
From: Stefan Schmiedl
Subject: Re: Returning from Function
Date: 
Message-ID: <amuqip$961v0$1@ID-57631.news.dfncis.de>
On Thu, 26 Sep 2002 13:01:38 +0200,
Thomas Guettler <···········@thomas-guettler.de> wrote:
> 
> (defun bigger2 (i)
>    (let ((ret-bigger "bigger")
>         (ret-smaller "smaller"))
> 
>      (if *other-mathematical-universe*
>          return ret-bigger)
> 
>      (if *always-smaller*
>          return ret-smaller)
> 
>      (if (> i 2)
>          (return ret-bigger)
>        (return ret-smaller))))
> (bigger2 1)
> 

Thomas,

most of the time there is no need to use return.
Your use of return is twofold:
 - determine the result of the function
 - providing exit points from the function

(defun bigger2 (i)
  (let ((bigger "bigger")
        (smaller "smaller"))
    (cond (*other-mathematical-universe* bigger)
          (*always-smaller* smaller)
          ((> i 2) bigger)
          (t smaller))))

I tried it in LWL, which made me smile:
CL-USER 1 > (defun bigger2 (i) ...)
Warning: Syntactic warning for form *OTHER-MATHEMATICAL-UNIVERSE*:
   *OTHER-MATHEMATICAL-UNIVERSE* assumed special.

It's reassuring to know that an *OTHER-MATHEMATICAL-UNIVERSE* is
assumed special, isn't it?

s.
From: Frode Vatvedt Fjeld
Subject: Re: Returning from Function
Date: 
Message-ID: <2hadm59f3z.fsf@vserver.cs.uit.no>
Thomas Guettler <···········@thomas-guettler.de> writes:

> My example was bad. The return will
> be called at several places. Here the new:
>
> (defun bigger2 (i)
>    (let ((ret-bigger "bigger")
>         (ret-smaller "smaller"))
>
>      (if *other-mathematical-universe*
>          return ret-bigger)
>
>      (if *always-smaller*
>          return ret-smaller)
>
>      (if (> i 2)
>          (return ret-bigger)
>        (return ret-smaller))))
> (bigger2 1)

Perhaps you can change this slightly to use cond, which is more in the
lisp line of style:

  (defun bigger2 (i)
    (cond
     (*other-mathematical-universe*
      'bigger)
     (*always-smaller*
      'smaller)
     ((> i 2)
      'bigger)
     (t 'smaller)))

-- 
Frode Vatvedt Fjeld
From: Raffael Cavallaro
Subject: Re: Returning from Function
Date: 
Message-ID: <aeb7ff58.0209270444.64ba2398@posting.google.com>
Thomas, you might want to learn the concept of functional programming
as seen in common lisp-  functions return values - no need to
explictly return them.

You should also realize that return, return-from and block are used to
break out of the normal flow of execution. If normal control flow is
desired (as in your example) there is no need for return, return-from
and block.

If there are multiple cases, not just the two given, you should learn
cond, or case/ccase/ecase - you should certainly learn cond in any
case if you're going to be reading and writing lisp code.
From: Erik Naggum
Subject: Re: Returning from Function
Date: 
Message-ID: <3242097548127891@naggum.no>
* Thomas Guettler
| How can I use return with a variable?

  Which programming language do you really want to use while you try to write
  in Common Lisp?

| The following does not work (Allegro 3.0.2)

  That is an awfully outdated and atrocious implementation.

-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
From: Thomas Guettler
Subject: Re: Returning from Function
Date: 
Message-ID: <an1j5g$23o$02$1@news.t-online.com>
Erik Naggum schrieb:
> * Thomas Guettler
> | How can I use return with a variable?
> 
>   Which programming language do you really want to use while you try to write
>   in Common Lisp?

I must use it. I am fixing an old application. I would prefere python.

> 
> | The following does not work (Allegro 3.0.2)
> 
>   That is an awfully outdated and atrocious implementation.

I know.

Thank you all very much for helping.
The problem is solved.

Refering to the thread "this newsgroup":

I don't think comp.lang.lisp is hostile

  thomas
From: Erik Naggum
Subject: Re: Returning from Function
Date: 
Message-ID: <3242145587127020@naggum.no>
* Thomas Guettler
| I must use it.  I am fixing an old application.  I would prefere python.

  I strongly suggest that you become good at what you have to do.  The person
  who has to fix /your/ code will hate you and will want to kill you if you
  keep writing in a different language than you are using.  Be humble before
  your task and let it direct you.  Despite how you feel, you are /not/ more
  important than your task.  Many practitioners in the IT industry feel that
  they are more important than their jobs and therefore let their preferences
  get between them and doing a good job as seen from whoever pays them.  We
  have an IT winter right now, and my guess is that it finally dawned on the
  managers that IT people were undisciplined and uncontrollable and had become
  extremely arrogant and decided to hell with them and their "solutions".

  If someone asked you to fix something, they expected you to be able to do
  it.  Take that trust to heart and reward those who trusted you by /wanting/
  to write in Common Lisp when the application is in Common Lisp.

  We'll be here to help you if you want to learn Common Lisp.
  
-- 
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.