From: Florian Leitner
Subject: newbie question - designator [coercion]
Date: 
Message-ID: <ae356$43ceac6e$506d4c8c$430@news.chello.at>
This is a multi-part message in MIME format.
--------------000608040006030902010907
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

I'm a newbie to LISP, currently munching away at Peter Seibel's
"Practical Common Lisp"-Book (grand book Peter, btw!). I'm just in its
very first chapters although, and have encountered an [to me] ambiguous code

(1)
<code>
(remove-if-not #'evenp (1 2 3 4 5 6))
</code>

Looking up the CLHyperSpec, it only reads:
(remove-if-not <test: function designator> <sequence> ...)
and checking on function designators: they do not require to be used in
sharp-quote notation - the functions symbol is enough, so i can write

(2)
<code>
(remove-if-not 'evenp (1 2 3 4 5 6))
</code>

and it evals just as nice.

This is what I tried to make up:
Checking up on designators, they are coerced. So, if I hand
remove-if-not the function "directly" using the quote-sharp notation, it
is (slightly?) more efficient because no coercion from symbol to
function is necessary as in (2).
But if I use "(step <form>)" to inspect what happens in my CLISP/SLIME
environment, both approaches requite exactly 3 steps, and both notations
seem to get coerced. So, what is the reason for writing the designator
in quote-sharp notation instead of the straightforward way? Or [my, my]
is there no difference at all? I just can't believe Peter wrote this
"just for fun".

thanks & best regards,
florian




--------------000608040006030902010907
Content-Type: text/x-vcard; charset=utf-8;
 name="allthatstuff.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="allthatstuff.vcf"

begin:vcard
fn:Florian Leitner
n:Leitner;Florian
org:Institute for Molecular Pathology;Eisenhaber Bioinformatics Group
adr:;;Dr.-Bohr-Gasse 7;Vienna;;1030;Austria
···························@gmx.net
x-mozilla-html:FALSE
url:http://mendel.imp.univie.ac.at
version:2.1
end:vcard


--------------000608040006030902010907--

From: Jason Kantz
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <1137619463.970063.69140@f14g2000cwb.googlegroups.com>
A couple of hints ...

What is the does the #' do when the lisp reader reads #'evenp?

What do you get when you evaluate (pprint-linear t '#'evenp) ?
From: Florian Leitner
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <7e681$43ceb816$506d4c8c$2926@news.chello.at>
This is a multi-part message in MIME format.
--------------080700050207040009080108
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

well this is simple:

(equal #'foo (function foo)) => t

[more in Szymons mail...]

Jason Kantz schrieb:
> A couple of hints ...
> 
> What is the does the #' do when the lisp reader reads #'evenp?
> 
> What do you get when you evaluate (pprint-linear t '#'evenp) ?
> 

--------------080700050207040009080108
Content-Type: text/x-vcard; charset=utf-8;
 name="allthatstuff.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="allthatstuff.vcf"

begin:vcard
fn:Florian Leitner
n:Leitner;Florian
org:Institute for Molecular Pathology;Eisenhaber Bioinformatics Group
adr:;;Dr.-Bohr-Gasse 7;Vienna;;1030;Austria
···························@gmx.net
x-mozilla-html:FALSE
url:http://mendel.imp.univie.ac.at
version:2.1
end:vcard


--------------080700050207040009080108--
From: Barry Margolin
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <barmar-38FF4D.21231618012006@comcast.dca.giganews.com>
In article <···························@news.chello.at>,
 Florian Leitner <············@gmx.net> wrote:

> I'm a newbie to LISP, currently munching away at Peter Seibel's
> "Practical Common Lisp"-Book (grand book Peter, btw!). I'm just in its
> very first chapters although, and have encountered an [to me] ambiguous code
> 
> (1)
> <code>
> (remove-if-not #'evenp (1 2 3 4 5 6))
> </code>
> 
> Looking up the CLHyperSpec, it only reads:
> (remove-if-not <test: function designator> <sequence> ...)
> and checking on function designators: they do not require to be used in
> sharp-quote notation - the functions symbol is enough, so i can write
> 
> (2)
> <code>
> (remove-if-not 'evenp (1 2 3 4 5 6))
> </code>
> 
> and it evals just as nice.
> 
> This is what I tried to make up:
> Checking up on designators, they are coerced. So, if I hand
> remove-if-not the function "directly" using the quote-sharp notation, it
> is (slightly?) more efficient because no coercion from symbol to
> function is necessary as in (2).
> But if I use "(step <form>)" to inspect what happens in my CLISP/SLIME
> environment, both approaches requite exactly 3 steps, and both notations
> seem to get coerced. So, what is the reason for writing the designator
> in quote-sharp notation instead of the straightforward way? Or [my, my]
> is there no difference at all? I just can't believe Peter wrote this
> "just for fun".

You don't see the coercion step because it's being done internally 
within REMOVE-IF-NOT (actually it's done by the APPLY function that 
REMOVE-IF-NOT eventually calls), and STEP doesn't show you the internal 
processing of a compiled function.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: tichy
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <dqmc43$rio$1@nemesis.news.tpi.pl>
Hi.
Try this:

(defun foo (x)
   (declare (ignore x))
   (write-string "Foo :)")
   (terpri))

(defun test-1 ()
   (map nil 'foo '(0 0 0)))

(defun test-2 ()
   (flet ((foo (x) (princ x)))
     (map nil 'foo '(0 0 0))))

(defun test-3 ()
   (flet ((foo (x) (princ x)))
     (map nil #'foo '(0 0 0))))

(map nil (lambda (x) (funcall x) (terpri))
      '(test-1 test-2 test-3))

Foo :)
Foo :)
Foo :)

Foo :)
Foo :)
Foo :)

000

Regards, Szymon.
From: Florian Leitner
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <4076f$43ceba59$506d4c8c$3372@news.chello.at>
This is a multi-part message in MIME format.
--------------050001040209070804070302
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

tichy schrieb:
> 
> Hi.
> Try this:
> 
> (defun foo (x)
>   (declare (ignore x))
>   (write-string "Foo :)")
>   (terpri))
> 
> (defun test-1 ()
>   (map nil 'foo '(0 0 0)))
> 
> (defun test-2 ()
>   (flet ((foo (x) (princ x)))
>     (map nil 'foo '(0 0 0))))
> 
> (defun test-3 ()
>   (flet ((foo (x) (princ x)))
>     (map nil #'foo '(0 0 0))))
> 
> (map nil (lambda (x) (funcall x) (terpri))
>      '(test-1 test-2 test-3))
> 
> Foo :)
> Foo :)
> Foo :)
> 
> Foo :)
> Foo :)
> Foo :)
> 
> 000
> 
> Regards, Szymon.

well, here you are tricking with lexical scoping: flet only allows
<b>function names</b> to be scoped to the body, while using sharp-quote,
you are referencing the function object itself. So, as I get it, I can
design designators either as symbols, as in test-2 to stay in the
lexical scope of the closure OR as objects to refer to the global object
by using the method in test-3. am i getting to your point?

florian

--------------050001040209070804070302
Content-Type: text/x-vcard; charset=utf-8;
 name="allthatstuff.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="allthatstuff.vcf"

begin:vcard
fn:Florian Leitner
n:Leitner;Florian
org:Institute for Molecular Pathology;Eisenhaber Bioinformatics Group
adr:;;Dr.-Bohr-Gasse 7;Vienna;;1030;Austria
···························@gmx.net
x-mozilla-html:FALSE
url:http://mendel.imp.univie.ac.at
version:2.1
end:vcard


--------------050001040209070804070302--
From: Jason Kantz
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <1137637245.077060.315550@z14g2000cwz.googlegroups.com>
I think you have it backwards.

Special Operator FUNCTION:
"The value of function is the functional value of name in the current
*lexical* environment."
http://www.lisp.org/HyperSpec/Body/speope_function.html

function designator:
"a symbol (denoting the function named by that symbol in the *global*
environment)  or a function (denoting itself)."
http://www.lisp.org/HyperSpec/Body/glo_f.html#function_designator

So when you use a symbol as a function designator, it refers to the
function named by that symbol in the global environment.  To use a
function object as a designator, there are several ways to get your
hands on one.  You can use FUNCTION, which looks for the function named
by a symbol first in the lexical environment and then in the global
env.  You can use SYMBOL-FUNCTION, which (if the symbol is FBOUND) will
return the function named by the symbol in the global env.  Or you may
also use a variable whose value is already a function object.  So #'
does not just mean "the function itself", it is one particular way
among several for getting your hands on a function object.

It may help to study the examples under SYMBOL-FUNCTION,
http://www.lisp.org/HyperSpec/Body/acc_symbol-function.html#symbol-function
From: David Sletten
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <saBzf.1034$eV4.602@tornado.socal.rr.com>
Florian Leitner wrote:

> I'm a newbie to LISP, currently munching away at Peter Seibel's
> "Practical Common Lisp"-Book (grand book Peter, btw!). I'm just in its
> very first chapters although, and have encountered an [to me] ambiguous code
> 
> (1)
> <code>
> (remove-if-not #'evenp (1 2 3 4 5 6))
> </code>
> 
> Looking up the CLHyperSpec, it only reads:
> (remove-if-not <test: function designator> <sequence> ...)
> and checking on function designators: they do not require to be used in
> sharp-quote notation - the functions symbol is enough, so i can write
> 
> (2)
> <code>
> (remove-if-not 'evenp (1 2 3 4 5 6))
> </code>
> 
> and it evals just as nice.
> 
> This is what I tried to make up:
> Checking up on designators, they are coerced. So, if I hand
> remove-if-not the function "directly" using the quote-sharp notation, it
> is (slightly?) more efficient because no coercion from symbol to
> function is necessary as in (2).
> But if I use "(step <form>)" to inspect what happens in my CLISP/SLIME
> environment, both approaches requite exactly 3 steps, and both notations
> seem to get coerced. So, what is the reason for writing the designator
> in quote-sharp notation instead of the straightforward way? Or [my, my]
> is there no difference at all? I just can't believe Peter wrote this
> "just for fun".
> 
> thanks & best regards,
> florian
> 
> 
> 

It looks like you've got the idea now. Here's a couple of other twists. 
See if you understand what's going on here:

(defun pung (x) (+ x 1))

(let ((pung #'(lambda (x) (+ x 2))))
   (flet ((pung (x) (+ x 3)))
     (print (pung 4))
     (print (funcall #'pung 4))
     (print (funcall 'pung 4))
     (print (funcall (symbol-function 'pung) 4))
     (print (funcall pung 4))))

First we define a global function PUNG. Then we create a local variable 
PUNG and give it an anonymous function as a value. Next we create a 
local function definition for PUNG (distinct from its value as a variable).

In that context simply evaluating (pung 4) uses the local (lexical) 
definition as does (funcall #'pung 4) (You indicated that you already 
understand #'pung is equivalent to (function pung)).

However, when using the symbol PUNG as a function designator, the global 
function value is used. This is also what happens via SYMBOL-FUNCTION. 
Note that the 1st and 3rd calls to FUNCALL are receiving a function 
object as their first arg. But they are different functions.

Finally FUNCALL can use the function object stored as the _value_ of the 
variable PUNG as well.

Aloha,
David Sletten
From: Florian Leitner
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <43cfa7a3$0$12642$3b214f66@usenet.univie.ac.at>
David Sletten wrote:
> Florian Leitner wrote:
> 
>> I'm a newbie to LISP, currently munching away at Peter Seibel's
>> "Practical Common Lisp"-Book (grand book Peter, btw!). I'm just in its
>> very first chapters although, and have encountered an [to me] 
>> ambiguous code
>>
>> (1)
>> <code>
>> (remove-if-not #'evenp (1 2 3 4 5 6))
>> </code>
>>
>> Looking up the CLHyperSpec, it only reads:
>> (remove-if-not <test: function designator> <sequence> ...)
>> and checking on function designators: they do not require to be used in
>> sharp-quote notation - the functions symbol is enough, so i can write
>>
>> (2)
>> <code>
>> (remove-if-not 'evenp (1 2 3 4 5 6))
>> </code>
>>
>> and it evals just as nice.
>>
>> This is what I tried to make up:
>> Checking up on designators, they are coerced. So, if I hand
>> remove-if-not the function "directly" using the quote-sharp notation, it
>> is (slightly?) more efficient because no coercion from symbol to
>> function is necessary as in (2).
>> But if I use "(step <form>)" to inspect what happens in my CLISP/SLIME
>> environment, both approaches requite exactly 3 steps, and both notations
>> seem to get coerced. So, what is the reason for writing the designator
>> in quote-sharp notation instead of the straightforward way? Or [my, my]
>> is there no difference at all? I just can't believe Peter wrote this
>> "just for fun".
>>
>> thanks & best regards,
>> florian
>>
>>
>>
> 
> It looks like you've got the idea now. Here's a couple of other twists. 
> See if you understand what's going on here:
> 
> (defun pung (x) (+ x 1))
> 
> (let ((pung #'(lambda (x) (+ x 2))))
>   (flet ((pung (x) (+ x 3)))
>     (print (pung 4))
>     (print (funcall #'pung 4))
>     (print (funcall 'pung 4))
>     (print (funcall (symbol-function 'pung) 4))
>     (print (funcall pung 4))))
> 
> First we define a global function PUNG. Then we create a local variable 
> PUNG and give it an anonymous function as a value. Next we create a 
> local function definition for PUNG (distinct from its value as a variable).
> 
> In that context simply evaluating (pung 4) uses the local (lexical) 
> definition as does (funcall #'pung 4) (You indicated that you already 
> understand #'pung is equivalent to (function pung)).
> 
> However, when using the symbol PUNG as a function designator, the global 
> function value is used. This is also what happens via SYMBOL-FUNCTION. 
> Note that the 1st and 3rd calls to FUNCALL are receiving a function 
> object as their first arg. But they are different functions.
> 
> Finally FUNCALL can use the function object stored as the _value_ of the 
> variable PUNG as well.
> 
> Aloha,
> David Sletten

Now that [I hope...] elucidated it - to describe in my own words what is 
going on:

1) (pung 4)
pretty obvious - pung is eval'd by its functional value in its lexical 
scope, which is set by (flet ...)

2) (funcall #'pung 4)
again pung eval'd by its functional value in lexical scope, then the 
designator, now being a functional object, is again evalued in its 
lexical scope leads to the (flet ...) scope.

3) (funcall 'pung 4)
this time the functional designator being a symbol-function designator 
tells us that it gets eval'd in the *global* scope, eval'ing it to the 
defun of pung.

4) (funcall (symbol-function 'pung) 4)
basically as 3), we are twice eval'ing the symbol value, both leading to 
the *global* scope. this is also noted in the CLHS for symbol-function:
<quote>
symbol-function cannot access the value of a lexical function name 
produced by flet or labels; it can access only the global function value.
</quote>

5) (funcall pung 4)
now we are directly accessing the symbol value of pung, leading us to 
the (let ...) scope, wehre the symbol value of pung was set to the 
lambda-function.

So I would be tempted to summarize:
Using a symbol directly, as in (symbol ...), leads to its functional 
value, within the current [functional] lexical scope (1).
Scope of a designator:
as "bare" symbol: eval'd in its [symbolic] lexical scope (5).
as functional object: eval'd in the [functional] lexical scope (2).
as symbol-function: eval'd in the *global* scope (3 4).

So did I get this right - and is there any more fundamental "trickery" I 
might encounter in LISPs function scoping?

Thanks to all of you for your help here and comments!

cheers,
Florian
From: David Sletten
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <u4Rzf.1534$Ou1.746@tornado.socal.rr.com>
Florian Leitner wrote:

I think you're focusing a little too much on evaluation here. You talk 
about certain things being eval'd and then eval'd _again_.

This all boils down to the obvious idea that before Lisp can invoke a 
function it has to know which function to use. Once the correct function 
has been identified it is simply applied to its args. The function 
doesn't need to be _eval'd_ again.

If you designate a function by name (using a symbol), then Lisp has to 
look that function up. This is what happens in 1) and 3) below. However, 
in 2) and 4) by the time FUNCALL is invoked, Lisp has already resolved 
which function is associated with PUNG (by different mechanisms in each 
case). Here FUNCALL doesn't know anything about PUNG. It just receives 
the actual function as an argument. 5) is similar in that FUNCALL merely 
receives a function as its first arg, although this function being 
associated with PUNG in a different way (as a variable value rather than 
a function value).

Note that while referring to functions by name is more common, we can 
also invoke functions by specifying them explicitly. The following all 
produce the same result:
((lambda (x) (+ x 9)) 8) => 17

(funcall #'(lambda (x) (+ x 9)) 8) => 17

(defun bar (x) 

   (+ x 9))
(bar 8) => 17

Here are more details:
http://www.lispworks.com/documentation/HyperSpec/Body/03_ababc.htm
http://www.lispworks.com/documentation/HyperSpec/Body/03_ababd.htm

David Sletten

> 
> 1) (pung 4)
> pretty obvious - pung is eval'd by its functional value in its lexical 
> scope, which is set by (flet ...)
> 
> 2) (funcall #'pung 4)
> again pung eval'd by its functional value in lexical scope, then the 
> designator, now being a functional object, is again evalued in its 
> lexical scope leads to the (flet ...) scope.
> 
> 3) (funcall 'pung 4)
> this time the functional designator being a symbol-function designator 
> tells us that it gets eval'd in the *global* scope, eval'ing it to the 
> defun of pung.
> 
> 4) (funcall (symbol-function 'pung) 4)
> basically as 3), we are twice eval'ing the symbol value, both leading to 
> the *global* scope. this is also noted in the CLHS for symbol-function:
> <quote>
> symbol-function cannot access the value of a lexical function name 
> produced by flet or labels; it can access only the global function value.
> </quote>
> 
> 5) (funcall pung 4)
> now we are directly accessing the symbol value of pung, leading us to 
> the (let ...) scope, wehre the symbol value of pung was set to the 
> lambda-function.
> 
> So I would be tempted to summarize:
> Using a symbol directly, as in (symbol ...), leads to its functional 
> value, within the current [functional] lexical scope (1).
> Scope of a designator:
> as "bare" symbol: eval'd in its [symbolic] lexical scope (5).
> as functional object: eval'd in the [functional] lexical scope (2).
> as symbol-function: eval'd in the *global* scope (3 4).
> 
> So did I get this right - and is there any more fundamental "trickery" I 
> might encounter in LISPs function scoping?
> 
From: Florian Leitner
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <5a97d$43cfe1df$506d4c8c$32431@news.chello.at>
This is a multi-part message in MIME format.
--------------090200010405010405070506
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

David Sletten schrieb:
> Florian Leitner wrote:
> 
> I think you're focusing a little too much on evaluation here. You talk
> about certain things being eval'd and then eval'd _again_.
> 
> This all boils down to the obvious idea that before Lisp can invoke a
> function it has to know which function to use. Once the correct function
> has been identified it is simply applied to its args. The function
> doesn't need to be _eval'd_ again.
> 
> If you designate a function by name (using a symbol), then Lisp has to
> look that function up. This is what happens in 1) and 3) below. However,
> in 2) and 4) by the time FUNCALL is invoked, Lisp has already resolved
> which function is associated with PUNG (by different mechanisms in each
> case). Here FUNCALL doesn't know anything about PUNG. It just receives
> the actual function as an argument. 5) is similar in that FUNCALL merely
> receives a function as its first arg, although this function being
> associated with PUNG in a different way (as a variable value rather than
> a function value).
> 
> Note that while referring to functions by name is more common, we can
> also invoke functions by specifying them explicitly. The following all
> produce the same result:
> ((lambda (x) (+ x 9)) 8) => 17
> 
> (funcall #'(lambda (x) (+ x 9)) 8) => 17
> 
> (defun bar (x)
>   (+ x 9))
> (bar 8) => 17
> 
> Here are more details:
> http://www.lispworks.com/documentation/HyperSpec/Body/03_ababc.htm
> http://www.lispworks.com/documentation/HyperSpec/Body/03_ababd.htm
> 
> David Sletten
> 
>>
>> 1) (pung 4)
>> pretty obvious - pung is eval'd by its functional value in its lexical
>> scope, which is set by (flet ...)
>>
>> 2) (funcall #'pung 4)
>> again pung eval'd by its functional value in lexical scope, then the
>> designator, now being a functional object, is again evalued in its
>> lexical scope leads to the (flet ...) scope.
>>
>> 3) (funcall 'pung 4)
>> this time the functional designator being a symbol-function designator
>> tells us that it gets eval'd in the *global* scope, eval'ing it to the
>> defun of pung.
>>
>> 4) (funcall (symbol-function 'pung) 4)
>> basically as 3), we are twice eval'ing the symbol value, both leading
>> to the *global* scope. this is also noted in the CLHS for
>> symbol-function:
>> <quote>
>> symbol-function cannot access the value of a lexical function name
>> produced by flet or labels; it can access only the global function value.
>> </quote>
>>
>> 5) (funcall pung 4)
>> now we are directly accessing the symbol value of pung, leading us to
>> the (let ...) scope, wehre the symbol value of pung was set to the
>> lambda-function.
>>
>> So I would be tempted to summarize:
>> Using a symbol directly, as in (symbol ...), leads to its functional
>> value, within the current [functional] lexical scope (1).
>> Scope of a designator:
>> as "bare" symbol: eval'd in its [symbolic] lexical scope (5).
>> as functional object: eval'd in the [functional] lexical scope (2).
>> as symbol-function: eval'd in the *global* scope (3 4).
>>
>> So did I get this right - and is there any more fundamental "trickery"
>> I might encounter in LISPs function scoping?
>>
> 

I guess the problem was I did not understand what it means that a symbol
can have a name, a value and a function as well as that you can bind a
function object to the value while still retaining another function
object in the function "slot" (guess that's not the right term?). Then
you can apply either the symbol, its value or its function to a
designator. All this was kind of confusing to me... Anyway, I think now
I understood the concept, and thanks again for your help!

Florian

--------------090200010405010405070506
Content-Type: text/x-vcard; charset=utf-8;
 name="allthatstuff.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="allthatstuff.vcf"

begin:vcard
fn:Florian Leitner
n:Leitner;Florian
org:Institute for Molecular Pathology;Eisenhaber Bioinformatics Group
adr:;;Dr.-Bohr-Gasse 7;Vienna;;1030;Austria
···························@gmx.net
x-mozilla-html:FALSE
url:http://mendel.imp.univie.ac.at
version:2.1
end:vcard


--------------090200010405010405070506--
From: Coby Beck
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <bfSzf.110803$km.97024@edtnps89>
"Florian Leitner" <············@gmx.net> wrote in message 
··································@news.chello.at...

> I guess the problem was I did not understand what it means that a symbol
> can have a name, a value and a function as well as that you can bind a
> function object to the value while still retaining another function
> object in the function "slot" (guess that's not the right term?). Then
> you can apply either the symbol, its value or its function to a
> designator. All this was kind of confusing to me... Anyway, I think now
> I understood the concept, and thanks again for your help!

Function slot is the right term.  A symbol is just a structure with the 
following slots:

- Name
- Value
- Function
- Plist
- Package

There is actually alot less magic involved than it sometimes appears.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Florian Leitner
Subject: Re: newbie question - designator [coercion]
Date: 
Message-ID: <2c0f7$43cfddda$506d4c8c$13661@news.chello.at>
This is a multi-part message in MIME format.
--------------040506060207010502090400
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Florian Leitner schrieb:
> David Sletten wrote:
>> Florian Leitner wrote:
>>
>>> I'm a newbie to LISP, currently munching away at Peter Seibel's
>>> "Practical Common Lisp"-Book (grand book Peter, btw!). I'm just in its
>>> very first chapters although, and have encountered an [to me]
>>> ambiguous code
>>>
>>> (1)
>>> <code>
>>> (remove-if-not #'evenp (1 2 3 4 5 6))
>>> </code>
>>>
>>> Looking up the CLHyperSpec, it only reads:
>>> (remove-if-not <test: function designator> <sequence> ...)
>>> and checking on function designators: they do not require to be used in
>>> sharp-quote notation - the functions symbol is enough, so i can write
>>>
>>> (2)
>>> <code>
>>> (remove-if-not 'evenp (1 2 3 4 5 6))
>>> </code>
>>>
>>> and it evals just as nice.
>>>
>>> This is what I tried to make up:
>>> Checking up on designators, they are coerced. So, if I hand
>>> remove-if-not the function "directly" using the quote-sharp notation, it
>>> is (slightly?) more efficient because no coercion from symbol to
>>> function is necessary as in (2).
>>> But if I use "(step <form>)" to inspect what happens in my CLISP/SLIME
>>> environment, both approaches requite exactly 3 steps, and both notations
>>> seem to get coerced. So, what is the reason for writing the designator
>>> in quote-sharp notation instead of the straightforward way? Or [my, my]
>>> is there no difference at all? I just can't believe Peter wrote this
>>> "just for fun".
>>>
>>> thanks & best regards,
>>> florian
>>>
>>>
>>>
>>
>> It looks like you've got the idea now. Here's a couple of other
>> twists. See if you understand what's going on here:
>>
>> (defun pung (x) (+ x 1))
>>
>> (let ((pung #'(lambda (x) (+ x 2))))
>>   (flet ((pung (x) (+ x 3)))
>>     (print (pung 4))
>>     (print (funcall #'pung 4))
>>     (print (funcall 'pung 4))
>>     (print (funcall (symbol-function 'pung) 4))
>>     (print (funcall pung 4))))
>>
>> First we define a global function PUNG. Then we create a local
>> variable PUNG and give it an anonymous function as a value. Next we
>> create a local function definition for PUNG (distinct from its value
>> as a variable).
>>
>> In that context simply evaluating (pung 4) uses the local (lexical)
>> definition as does (funcall #'pung 4) (You indicated that you already
>> understand #'pung is equivalent to (function pung)).
>>
>> However, when using the symbol PUNG as a function designator, the
>> global function value is used. This is also what happens via
>> SYMBOL-FUNCTION. Note that the 1st and 3rd calls to FUNCALL are
>> receiving a function object as their first arg. But they are different
>> functions.
>>
>> Finally FUNCALL can use the function object stored as the _value_ of
>> the variable PUNG as well.
>>
>> Aloha,
>> David Sletten
> 
> Now that [I hope...] elucidated it - to describe in my own words what is
> going on:
> 

I have been giving this some more thoughts, especially in connection
with Jasons comments and i noted some inconsistency here:


> 1) (pung 4)
> pretty obvious - pung is eval'd by its functional value in its lexical
> scope, which is set by (flet ...)

actually the function value of the symbol pung is fbound to pung defined
in (flet), therefor using standard notation it calls that function

> 
> 2) (funcall #'pung 4)
> again pung eval'd by its functional value in lexical scope, then the
> designator, now being a functional object, is again evalued in its
> lexical scope leads to the (flet ...) scope.

this time, using (function ...) - which returns the function object of
the given symbol - again the pung defined in (flet) is used.

> 
> 3) (funcall 'pung 4)
> this time the functional designator being a symbol-function designator
> tells us that it gets eval'd in the *global* scope, eval'ing it to the
> defun of pung.

now we have a designator, and we are handing (funcall) the symbol pung.
using a symbol (!the important part!) as function designator, which
means to look for the symbols function object in *global* scope.

> 
> 4) (funcall (symbol-function 'pung) 4)
> basically as 3), we are twice eval'ing the symbol value, both leading to
> the *global* scope. this is also noted in the CLHS for symbol-function:
> <quote>
> symbol-function cannot access the value of a lexical function name
> produced by flet or labels; it can access only the global function value.
> </quote>
>
> 5) (funcall pung 4)
> now we are directly accessing the symbol value of pung, leading us to
> the (let ...) scope, wehre the symbol value of pung was set to the
> lambda-function.
> 

this time we are giving funcall the symbol value (not the function
object or the symbol per se (as with "(funcall 'pung 4)" - again this is
important!) bound to pung, therefor the (let)-scoped function is used.

> So I would be tempted to summarize:
> Using a symbol directly, as in (symbol ...), leads to its functional
> value, within the current [functional] lexical scope (1).
> Scope of a designator:
> as "bare" symbol: eval'd in its [symbolic] lexical scope (5).
> as functional object: eval'd in the [functional] lexical scope (2).
> as symbol-function: eval'd in the *global* scope (3 4).
> 

Therefor my first generalisation is kind of wrong, heres a better one:

A) using a bare symbol in the first position ("car") of a list:
it is evaluated to its function object, with its current lexical scope

B) using a bare symbol as function designator:
it is evaluated to its symbol value, with its current lexical scope

C) using forms as function designators:
depends on the form used, here are some possibilities:

C1) (quote <<symbol>>)
this means the designator is used as unevaluated symbol, and the global
scope is used to find the function object

C2) (function <<symbol>>)
this means the designator is used as the function object, and the
current lexical scope is used to find the symbols function object

C3) other forms like (symbol-function (quote <<symbol>>))
have their own, defined scope (here: global) - I guess I will have to
look them up when I come across them?

> So did I get this right - and is there any more fundamental "trickery" I
> might encounter in LISPs function scoping?
> 
> Thanks to all of you for your help here and comments!
> 
> cheers,
> Florian

I hope this is - appart from concepts in lexical closure, which i think
are more easy to comprehend - it, as to what can determine visiblity of
an object...

--------------040506060207010502090400
Content-Type: text/x-vcard; charset=utf-8;
 name="allthatstuff.vcf"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="allthatstuff.vcf"

begin:vcard
fn:Florian Leitner
n:Leitner;Florian
org:Institute for Molecular Pathology;Eisenhaber Bioinformatics Group
adr:;;Dr.-Bohr-Gasse 7;Vienna;;1030;Austria
···························@gmx.net
x-mozilla-html:FALSE
url:http://mendel.imp.univie.ac.at
version:2.1
end:vcard


--------------040506060207010502090400--