From: David Steuber
Subject: FLET vs LABELS
Date: 
Message-ID: <878y6vlkht.fsf@david-steuber.com>
FLET and LABELS are both special operators.  They both do the same
thing except that, "labels is equivalent to flet except that the scope
of the defined function names for labels encompasses the function
definitions themselves as well as the body."

So why would FLET be used in preference to LABELS?

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1

From: Trent Buck
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <20050115093918.46ce4f04@harpo.marx>
Up spake David Steuber:
> FLET and LABELS are both special operators.  They both do the same
> thing except that, "labels is equivalent to flet except that the scope
> of the defined function names for labels encompasses the function
> definitions themselves as well as the body."
> 
> So why would FLET be used in preference to LABELS?

IIUC, this means that a function named via flet cannot refer to itself
-- because its name is outside its scope.  For example

  (defun f (x y z)    ;; add three positive integers
    (labels ((g (x y) ;; add two positive integers
		(if (zerop x)
		    y
		    (g (- 1 x) (+ 1 y)))))
      (g x (g y z))))

... G cannot be defined by flet.

This brings up another question that occured to me recently: how does
one define a recursive, anonymous function?

-- 
-trent
When your IQ reaches 50, *sell*.  You will make a profit.
 -- Bob Silverman
From: Alex Mizrahi
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <34r2ekF4ev4tqU1@individual.net>
(message (Hello 'Trent)
(you :wrote  :on '(Fri, 14 Jan 2005 22:39:00 GMT))
(

 TB> This brings up another question that occured to me recently: how does
 TB> one define a recursive, anonymous function?

using Y operator, for example:

(defun Y (f)
   (  (lambda (g) (lambda (h) (funcall (funcall f (funcall g g)) h)))
      (lambda (g) (lambda (h) (funcall (funcall f (funcall g g)) h)))))

(funcall (Y (lambda (myself) (lambda (n) (if (zerop n) 1 (* n (funcall
myself (- X 1))))))) 10)

or if you don't mind using labels and macros, there are other ways..
see discussion http://tinyurl.com/4ufwo

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
(prin1 "People, who lust for the Feel of keys on their fingertips (c)
Inity"))
From: Jim Newton
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <41E90CE3.20402@rdrop.com>
Here is my attempt at a lambda which allows recursive
calls.  Inkeeping with the way CALL-NEXT-METHOD
works, the macro constructs a CALL-SELF (suggest a better
name please) which makes a recursive call.

The macro contructs a closure which encloses the
lambda function in a lexical variable and inserts
an FLET inside the (lambda ...) to allow the user
provided body to call CALL-SELF.

Anyone have any feedback?

(defmacro recursive-lambda ( lambda-list &rest body)
   (let (( fun (gensym)))
     `(let ( ,fun)
       (setf ,fun (lambda  ,lambda-list
		   (flet (( call-self (&rest args) (apply ,fun args)))
		     ,@body))))))

And when I call the function...


CL-USER> (funcall (recursive-lambda ( x y)
	       (format t "x=~A y=~A~%" x y)
	       (+ y (if (plusp x)
			(call-self (1- x) y)
			0)))

	 3 2)
x=3 y=2
x=2 y=2
x=1 y=2
x=0 y=2
8
CL-USER>


Alex Mizrahi wrote:
> (message (Hello 'Trent)
> (you :wrote  :on '(Fri, 14 Jan 2005 22:39:00 GMT))
> (
> 
>  TB> This brings up another question that occured to me recently: how does
>  TB> one define a recursive, anonymous function?
> 
> using Y operator, for example:
> 
> (defun Y (f)
>    (  (lambda (g) (lambda (h) (funcall (funcall f (funcall g g)) h)))
>       (lambda (g) (lambda (h) (funcall (funcall f (funcall g g)) h)))))
> 
> (funcall (Y (lambda (myself) (lambda (n) (if (zerop n) 1 (* n (funcall
> myself (- X 1))))))) 10)
> 
> or if you don't mind using labels and macros, there are other ways..
> see discussion http://tinyurl.com/4ufwo
> 
> )
> (With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
> (prin1 "People, who lust for the Feel of keys on their fingertips (c)
> Inity"))
> 
> 
From: Thomas F. Burdick
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <xcvbrbpj333.fsf@conquest.OCF.Berkeley.EDU>
Jim Newton <·····@rdrop.com> writes:

> Here is my attempt at a lambda which allows recursive
> calls.  Inkeeping with the way CALL-NEXT-METHOD
> works, the macro constructs a CALL-SELF (suggest a better
> name please) which makes a recursive call.
> 
> The macro contructs a closure which encloses the
> lambda function in a lexical variable and inserts
> an FLET inside the (lambda ...) to allow the user
> provided body to call CALL-SELF.
> 
> Anyone have any feedback?
> 
> (defmacro recursive-lambda ( lambda-list &rest body)
>    (let (( fun (gensym)))
>      `(let ( ,fun)
>        (setf ,fun (lambda  ,lambda-list
> 		   (flet (( call-self (&rest args) (apply ,fun args)))
> 		     ,@body))))))

I would do this a bit differently:

  (defmacro alambda (llist &body body)
    "Anaphoric lambda"
    `(labels ((self ,llist ,@body))
       #'self))

or maybe:

  (defmacro named-lambda (name llist &body body)
    `(labels ((,name ,llist ,@body))
       #',name))
From: David Sletten
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <gZ%Fd.68905$gd.44660@twister.socal.rr.com>
Trent Buck wrote:
> Up spake David Steuber:
> 
>>FLET and LABELS are both special operators.  They both do the same
>>thing except that, "labels is equivalent to flet except that the scope
>>of the defined function names for labels encompasses the function
>>definitions themselves as well as the body."
>>
>>So why would FLET be used in preference to LABELS?
> 
> 
> IIUC, this means that a function named via flet cannot refer to itself
> -- because its name is outside its scope.  For example
> 
>   (defun f (x y z)    ;; add three positive integers
>     (labels ((g (x y) ;; add two positive integers
> 		(if (zerop x)
> 		    y
> 		    (g (- 1 x) (+ 1 y)))))
>       (g x (g y z))))
> 
> ... G cannot be defined by flet.
> 
> This brings up another question that occured to me recently: how does
> one define a recursive, anonymous function?
> 
As Alex pointed out, you can use the Y Combinator. (See ch. 9 of 
_The_Little_Lisper_ or _The_Little_Schemer_).

Or you can do something like this:
(defun make-subst (new old)
   (labels ((my-subst (obj)
              (cond ((eql old obj) new)
                    ((atom obj) obj)
                    (t (cons (my-subst (car obj))
                             (my-subst (cdr obj)))) )))
     #'my-subst))

(funcall (make-subst 'foo 'pung) '(is (this (not)) pung)) =>(IS (THIS 
(NOT)) FOO)

The function is not completely anonymous since it temporarily has a 
name, but you get the idea...

David Sletten
From: David Steuber
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <87vf9y35so.fsf@david-steuber.com>
Trent Buck <·········@tznvy.pbz> writes:

> This brings up another question that occured to me recently: how does
> one define a recursive, anonymous function?

The simplest solution I know is to just use LABELS:

CL-USER> (funcall (lambda (x)
                    (labels ((fac (x)
                               (if (< x 1)
                                   1
                                   (progn
                                     (print x)
                                     (* x (fac (1- x)))))))
                      (fac x))) 6)

6 
5 
4 
3 
2 
1 

720
CL-USER> 

Based on answerers here, it does seem that FLET has its uses.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Harald Hanche-Olsen
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <pcod5w7vait.fsf@shuttle.math.ntnu.no>
+ David Steuber <·····@david-steuber.com>:

| So why would FLET be used in preference to LABELS?

Some people have already mentioned the case where a local function
needs to call an outer function by the same name, and stuff like
that.

But I think another reason to use flet is as a signal to a human
reader of the program: It says these local functions don't call each
other, or call themselves recursively; so don't even bother looking
for such calls.  Conversely, the use of labels signals the existence
of such calls, alerting the reader to go look for them.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Barry Margolin
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <barmar-A8120B.20204314012005@comcast.dca.giganews.com>
In article <···············@shuttle.math.ntnu.no>,
 Harald Hanche-Olsen <······@math.ntnu.no> wrote:

> + David Steuber <·····@david-steuber.com>:
> 
> | So why would FLET be used in preference to LABELS?
> 
> Some people have already mentioned the case where a local function
> needs to call an outer function by the same name, and stuff like
> that.
> 
> But I think another reason to use flet is as a signal to a human
> reader of the program: It says these local functions don't call each
> other, or call themselves recursively; so don't even bother looking
> for such calls.  Conversely, the use of labels signals the existence
> of such calls, alerting the reader to go look for them.

FLET might also be useful in macro expansions, where the function body 
is supplied by the caller.  By using FLET, you don't have to worry about 
whether the name you give to the local function is also the name of a 
function that's called by the body, which would result in an unwanted 
recursive call.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Alex Mizrahi
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <34r2lvF4f64l6U1@individual.net>
(message (Hello 'David)
(you :wrote  :on '(14 Jan 2005 17:21:50 -0500))
(

 DS> FLET and LABELS are both special operators.  They both do the same
 DS> thing except that, "labels is equivalent to flet except that the scope
 DS> of the defined function names for labels encompasses the function
 DS> definitions themselves as well as the body."

 DS> So why would FLET be used in preference to LABELS?

you cannot do stuff like

(flet ((+ (x y) (print (+ x y)))) (+ 3 4))

with labels.
there are situations when you really need to access outer function
definition, however i don't think they are very frequent.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
(prin1 "People, who lust for the Feel of keys on their fingertips (c)
Inity"))
From: Peter Seibel
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <m3sm5360xr.fsf@javamonkey.com>
"Alex Mizrahi" <········@hotmail.com> writes:

> (message (Hello 'David)
> (you :wrote  :on '(14 Jan 2005 17:21:50 -0500))
> (
>
>  DS> FLET and LABELS are both special operators.  They both do the same
>  DS> thing except that, "labels is equivalent to flet except that the scope
>  DS> of the defined function names for labels encompasses the function
>  DS> definitions themselves as well as the body."
>
>  DS> So why would FLET be used in preference to LABELS?
>
> you cannot do stuff like
>
> (flet ((+ (x y) (print (+ x y)))) (+ 3 4))
>
> with labels. there are situations when you really need to access
> outer function definition, however i don't think they are very
> frequent.

Of course you can't do that with FLET either, in conforming code,
assuming by + you meant CL:+. But your point is otherwise correct.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Paul F. Dietz
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <0MOdnYipUqmciHTcRVn-rw@dls.net>
David Steuber wrote:
> FLET and LABELS are both special operators.  They both do the same
> thing except that, "labels is equivalent to flet except that the scope
> of the defined function names for labels encompasses the function
> definitions themselves as well as the body."
> 
> So why would FLET be used in preference to LABELS?

In addition to the other reasons given, FLET can be a bit
more efficient in some implementations.

	Paul
From: Jeff
Subject: Re: FLET vs LABELS
Date: 
Message-ID: <o19Gd.6417$ox3.2439@attbi_s04>
Paul F. Dietz wrote:

> David Steuber wrote:
>
> > So why would FLET be used in preference to LABELS?
> 
> In addition to the other reasons given, FLET can be a bit
> more efficient in some implementations.

I haven't followed this thread completely, but for myself, when I see
an FLET, it instantly lets me know that there is no recursion going on.
When I see a LABELS my first thought is to look for the recursion. This
can make a huge readability and maintainability improvement.

Jeff M.

-- 
http://www.retrobyte.org
··············@gmail.com