From: ···@orsi.com
Subject: labels and flet
Date: 
Message-ID: <865614231.23594@dejanews.com>
Assuming you don't have mutually recursive procedures,
and that for a specific set of procedures, say f,g,h,
(flet ((f ..) (g ..) (h ...)) form)
produces the same [correct] output as
(labels ((f ..) (g ..) (h ..)) form)
Is there any reason to choose one over the other?

Anyone have any good ideas for *debugging* such procedures.
My only idea is to develop all nontrivial procedures as external (so I can
trace through them) and make them labels when I'm sure they work.

-------------------==== Posted via Deja News ====-----------------------
      http://www.dejanews.com/     Search, Read, Post to Usenet

From: Barry Margolin
Subject: Re: labels and flet
Date: 
Message-ID: <5na012$msf@tools.bbnplanet.com>
In article <···············@dejanews.com>,  <···@orsi.com> wrote:
>Assuming you don't have mutually recursive procedures,
>and that for a specific set of procedures, say f,g,h,
>(flet ((f ..) (g ..) (h ...)) form)
>produces the same [correct] output as
>(labels ((f ..) (g ..) (h ..)) form)
>Is there any reason to choose one over the other?

There are arguments both ways.

I prefer FLET because I think of LABELS as providing a special feature that
I don't need if there's no recursion.  When I'm reading code and see
LABELS, it makes me think that something more complex is going on; I know
that I can understand a FLETted function without having to know its name or
the other functions being defined in the same FLET.  I also prefer it
because of the naming parallel with LET.

The argument for LABELS is that it's more like top-level definitions (which
inherently allow recursion) and you don't need to worry about whether or
not the functions are recursive when writing the code.

There are similar arguments for using SETQ vs. SETF to assign ordinary
variables (I prefer SETQ, although it may just be out of habit, since I've
been programming in Lisp since before SETF became popular).

>Anyone have any good ideas for *debugging* such procedures.
>My only idea is to develop all nontrivial procedures as external (so I can
>trace through them) and make them labels when I'm sure they work.

Some development environments provide nonstandard ways to reference
internal procedures.  For instance, on Symbolics workstations you could do:

(trace (:internal <parent-function> 0))

to trace the zeroth internal function.

But more often than not, people debug them in the old-fashioned way:
inserting PRINT statements, etc.

-- 
Barry Margolin, ······@bbnplanet.com
BBN Corporation, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
From: Henry Baker
Subject: Re: labels and flet
Date: 
Message-ID: <hbaker-0806971917200001@10.0.2.1>
> In article <···············@dejanews.com>,  <···@orsi.com> wrote:
> >Assuming you don't have mutually recursive procedures,
> >and that for a specific set of procedures, say f,g,h,
> >(flet ((f ..) (g ..) (h ...)) form)
> >produces the same [correct] output as
> >(labels ((f ..) (g ..) (h ..)) form)
> >Is there any reason to choose one over the other?

flet allows you to redefine locally a more global name, which makes it
sometimes useful for bug or performance workarounds.
From: Jeff Barnett
Subject: Re: labels and flet
Date: 
Message-ID: <EBJ5Dq.15A@gremlin.nrtc.northrop.com>
In article <···············@dejanews.com>, ···@orsi.com writes:
|> Assuming you don't have mutually recursive procedures,
|> and that for a specific set of procedures, say f,g,h,
|> (flet ((f ..) (g ..) (h ...)) form)
|> produces the same [correct] output as
|> (labels ((f ..) (g ..) (h ..)) form)
|> Is there any reason to choose one over the other?
|> 
|> Anyone have any good ideas for *debugging* such procedures.
|> My only idea is to develop all nontrivial procedures as external (so I can
|> trace through them) and make them labels when I'm sure they work.

What you are suggesting doesn't make a lot of sense to me
unless you are just trying to make the global namespace a
little less crowded.  The reson for using flet and label,
other than to make the names private, is so that your code
can see and share variable bindings.  If it is possible to
check your code out by first making it global then internal,
you aren't sharing bindings.  To make this clear, consider
the following code snipet

   (let((counter 0) ...)
     (flet((fcn (....) (incf counter) ......))
       ....)
     (do-something-with counter))

Notice that fcn and all other code lexically in the let
share the binding of counter, i.e., all that code can
read and write it.  If you try to move fcn outside, you
would need to make counter special or do some magic with
extra arguments and/or extra values.  Now we can see another
point of flet and labels: not only do we not clutter up the
global namespace with functions names -- fcn here -- but we
don't clutter it up with variable names -- counter here --
either.

What you are (attempting) to do isn't wrong and it isn't
even bad style.  However, if you have gotten to the point
of sophistication where you use flet and label, it is
time to go back to the books and learn all about the scope
rules for both variable and function names.  It is at this
point that all the wonder, magic, and power of common lisp
suddenly penetrates and makes you a better hacker.  I think
this is true because it is the exact point where you (1)
start thinking of the environment as important, (2) learn
the value of it as an explicit object, and (3) suddenly
know what and why there are closures.  In the Lisp world,
this is the Rubicon and it must be crossed.

Jeff Barnett
From: Antonio Leitao
Subject: Re: labels and flet
Date: 
Message-ID: <wok9k1tlp2.fsf@gia.ist.utl.pt>
>>>>> "Barry" =3D=3D Barry Margolin <······@bbnplanet.com> writes:

 Barry> In article <··············@gia.ist.utl.pt>,
 Barry> Antonio Leitao  <···@gia.ist.utl.pt> wrote:
 >> The labels may be less efficient than the flet because the functions
 >> defined by a labels are closed over their own names (creating
 >> closures). This does not occur in the flet.

 Barry> While the FLET isn't closed over its own name, it's closed over all=
 the
 Barry> names in the containing scope (e.g. the parameters to the function
 Barry> containing the FLET).  So both of them create closures.

Of course. When I say "This does not occur in the flet.", I'm talking
about "the functions defined by a labels are closed over their own
names", and not about "(creating closures)". My fault if it wasn't
clear.

Anyway, just to be a bit more clear, what I think is that a naive
implementation of a LABELS has an extra frame in the environment of
the defined functions, independently of the surrounding environment
which both the LABELS and the FLET will have. If the function
containing the FLET form do not establish such an environment, the
LABELed function will remain closures while the FLETed ones will not.

Since the both the FLET body and the LABELS body will have absolutely
the same environment (containing at least a frame for the defined
functions), I guess the distinction in the defined functions
environment is only useful if the defined functions are used outside
its scope. Am I right?

Thanks for the correction.

Ant=F3nio Leit=E3o.