From: Dvd Avins
Subject: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <1142735679.677129.210960@j33g2000cwa.googlegroups.com>
I'd like to have a value with a default that can be changed at any of a
few levels. I think it would be better not to keep changing the
variable name. But this doesn't work:

(defun test1 (&optional (text "default 1"))

    (defun test2 (&optional (text text))
        text))

When I run test 1 and then test 2 with no values supplied, I get NIL.
But if I change the inner function to use a different variable name, it
works:

(defun test1 (&optional (text "default 1"))

    (defun test2 (&optional (text2 text))
        text2))

Now when I run everything in order, I get "default 1".

Is there any circumstance in which this behavior is desirable? And
what's the best way around it?

From: Jonathon McKitrick
Subject: How do interior functions differ from flet?
Date: 
Message-ID: <1142738417.699787.13250@g10g2000cwb.googlegroups.com>
I just started using flet.  How does flet differ from interior
functions?
From: David Sletten
Subject: Re: How do interior functions differ from flet?
Date: 
Message-ID: <9p4Tf.3696$WK1.3190@tornado.socal.rr.com>
Jonathon McKitrick wrote:

> I just started using flet.  How does flet differ from interior
> functions?
> 
DEFUN creates a global function definition. FLET (and LABELS) creates 
local function definitions. Compare:
(defun f (x) 

   (+ x 1))

(defun g (y)
   (flet ((f (x)
            (+ x y)))
     (format t "Local: ~D~%" (f 3))
     (format t "Local: ~D~%" (funcall #'f 3))
     (format t "Global: ~D~%" (funcall 'f 3))
     (format t "Global: ~D~%" (funcall (symbol-function 'f) 3))))

* (g 2)
Local: 5
Local: 5
Global: 4
Global: 4
NIL

Furthermore, unlike nested DEFUNs, the FLET form in G need not be 
"executed" each time G is invoked. From what I understand the closure F 
should only be created once (when the DEFUN of G is evaluated) and the 
appropriate binding for Y is simply established when G is called.

Aloha,
David Sletten
From: David Sletten
Subject: Re: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <Cd4Tf.4582$%d.880@tornado.socal.rr.com>
Dvd Avins wrote:

> I'd like to have a value with a default that can be changed at any of a
> few levels. I think it would be better not to keep changing the
> variable name. But this doesn't work:
> 
> (defun test1 (&optional (text "default 1"))
> 
>     (defun test2 (&optional (text text))
>         text))
> 
> When I run test 1 and then test 2 with no values supplied, I get NIL.
> But if I change the inner function to use a different variable name, it
> works:
> 
> (defun test1 (&optional (text "default 1"))
> 
>     (defun test2 (&optional (text2 text))
>         text2))
> 
> Now when I run everything in order, I get "default 1".
> 
> Is there any circumstance in which this behavior is desirable? And
> what's the best way around it?
> 

I tried your example on 4 different Lisp systems and did not get the 
behavior you describe. Instead I got the behavior I expected, namely 
without supplying arguments to TEST1 or TEST2, TEST2 returns "default 1".

The more important issue though is why you are using nested DEFUNs. This 
is kind of strange. Do you realize that TEST2 is redefined everytime 
TEST1 is called? Is this really what you want?

I'm not sure exactly what you're trying to do, but there are several 
ways to arrange for functions to share a variable. Assuming TEST1 is 
supposed to set the default which TEST2 may later use you could do this:
(let (text)
   (defun test1 (&optional (x "default"))
     (setf text x))

   (defun test2 (&optional (text text))
     text))

Or if TEST2 doesn't need to be externally visible:
(defun test1 (&optional (text "default"))
   (flet ((test2 (&optional (text text))
            text))
     (print (test2))
     (print (test2 "foo"))))

Or even something like:
(defun set-up (&optional (text "default"))
   (list #'(lambda (&optional (text text))
             (format t "Function 1: ~A~%" text))
         #'(lambda (&optional (text text))
             (format t "Function 2: ~A~%" text))))

Then you can do this:
* (defvar *f* (set-up))

*F*
* (defvar *g* (set-up "pung"))

*G*
* (funcall (first *f*))
Function 1: default
NIL
* (funcall (first *f*) "bar")
Function 1: bar
NIL
* (funcall (first *g*))
Function 1: pung
NIL
* (funcall (second *g*) "baz")
Function 2: baz
NIL

Aloha,
David Sletten
From: Dvd Avins
Subject: Re: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <1142740929.714721.303030@u72g2000cwu.googlegroups.com>
> I tried your example on 4 different Lisp systems and did not get the
> behavior you describe. Instead I got the behavior I expected, namely
> without supplying arguments to TEST1 or TEST2, TEST2 returns "default 1".

Hmm. From Corman:

  (defun test1 (&optional (text "default 1"))

      (defun test2 (&optional (text text))
          text))
  TEST1

  (test1)
  TEST2

  (test2)
  NIL

But in LispBox, it works. All the more reason that I'm gald I finally
installed something other than Corman.

> The more important issue though is why you are using nested DEFUNs. This
> is kind of strange. Do you realize that TEST2 is redefined everytime
> TEST1 is called? Is this really what you want?

Yes, that really is what I want. In any given session, my equivalent of
test1 will probably only be run once, but if it is run again, I want
the detault behavior of test2 to adapt to the value passed to test1.

> I'm not sure exactly what you're trying to do, but there are several
> ways to arrange for functions to share a variable. Assuming TEST1 is
> supposed to set the default which TEST2 may later use you could do this:
> (let (text)
>    (defun test1 (&optional (x "default"))
>      (setf text x))

test1 is really a function that takes several arguments and sets up my
environment. I haven't finished writing the code, but I plan to put the
computation that I *know* I'll do every time inside test1, too. That
computation will rely, in part, on test2. But test2 will also be useful
in computation that I will do on some occasions but not others. So it
does have to be externally visible. Given that information, do you
still think the structure of my code is inefficient or too quirky? My
way avoids the need for globals, but are globals not as grievous a sin
as nested defuns?
From: Luke J Crook
Subject: Re: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <_I2dnRT_9uL-fIHZnZ2dnUVZ_sadnZ2d@giganews.com>
Dvd Avins wrote:
> 
> But in LispBox, it works. All the more reason that I'm gald I finally
> installed something other than Corman.
> 

In Corman, try (setf ccl::*compiler-fold-constants* nil)

The compiler may be performing an optimization that you do not want.

Also, see the following:
http://www.artofprogramming.com/bb/viewtopic.php?p=600&highlight=#600
http://www.artofprogramming.com/bb/viewtopic.php?p=737&highlight=#737

-Luke
From: Dvd Avins
Subject: Re: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <1142747221.967191.297700@e56g2000cwe.googlegroups.com>
I've had that problem with Corman before (and there was a thread about
it here  several weeks ago). But this isn't dependent on constants. I
tired your suggestion and, as expected, it made no difference.
From: David Sletten
Subject: Re: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <oY4Tf.3701$WK1.1062@tornado.socal.rr.com>
Dvd Avins wrote:

>>I tried your example on 4 different Lisp systems and did not get the
>>behavior you describe. Instead I got the behavior I expected, namely
>>without supplying arguments to TEST1 or TEST2, TEST2 returns "default 1".
> 
> 
> Hmm. From Corman:
> 
>   (defun test1 (&optional (text "default 1"))
> 
>       (defun test2 (&optional (text text))
>           text))
>   TEST1
> 
>   (test1)
>   TEST2
> 
>   (test2)
>   NIL
> 
> But in LispBox, it works. All the more reason that I'm gald I finally
> installed something other than Corman.
> 
> 

Heh. Corman is one I didn't try.

>>The more important issue though is why you are using nested DEFUNs. This
>>is kind of strange. Do you realize that TEST2 is redefined everytime
>>TEST1 is called? Is this really what you want?
> 
> 
> Yes, that really is what I want. In any given session, my equivalent of
> test1 will probably only be run once, but if it is run again, I want
> the detault behavior of test2 to adapt to the value passed to test1.
> 
> 
>>I'm not sure exactly what you're trying to do, but there are several
>>ways to arrange for functions to share a variable. Assuming TEST1 is
>>supposed to set the default which TEST2 may later use you could do this:
>>(let (text)
>>   (defun test1 (&optional (x "default"))
>>     (setf text x))
> 
> 
> test1 is really a function that takes several arguments and sets up my
> environment. I haven't finished writing the code, but I plan to put the
> computation that I *know* I'll do every time inside test1, too. That
> computation will rely, in part, on test2. But test2 will also be useful
> in computation that I will do on some occasions but not others. So it
> does have to be externally visible. Given that information, do you
> still think the structure of my code is inefficient or too quirky? My
> way avoids the need for globals, but are globals not as grievous a sin
> as nested defuns?
> 

I wouldn't go so far as to say that the nested DEFUNs are _strictly_ 
wrong. They may be appropriate for what you're doing. But I showed you 
some alternatives that may be clearer if all you're doing is setting up 
some defaults. The first example is a sort of controlled (global) 
non-local variable, i.e., not accessible to outside functions.

Aloha,
David Sletten
From: Zach Beane
Subject: Re: Can interior functions share names with the functions that define them?
Date: 
Message-ID: <m3u09u38ym.fsf@unnamed.xach.com>
"Dvd Avins" <········@pobox.com> writes:

> I'd like to have a value with a default that can be changed at any of a
> few levels.

This is usually done by making the default the value of a special
variable, e.g.

   (defun output (object &optional (stream *standard-output*))
     ...)

Nesting DEFUN is not common.

Zach