From: Damien Kick
Subject: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <13fu8dasl34l035@corp.supernews.com>
With LispWorks Personal Edition 5.0.1 (PowerPC), I see the following 
behavior:

<code>
CL-USER 1 > (defparameter *x* #'(lambda () 13))
*X*

CL-USER 2 > *x*
#<anonymous interpreted function 200EB012>

CL-USER 3 > (setf (symbol-function 'f) *x*)
#<anonymous interpreted function 200EB012>

CL-USER 4 > (setf (symbol-function 'g) *x*)
#<anonymous interpreted function 200EB012>

CL-USER 5 > (eq #'f #'g)
NIL

CL-USER 6 > (eql #'f #'g)
NIL

CL-USER 7 > (eql #'f *x*)
NIL

CL-USER 8 > (eq *x* *x*)
T
</code>

I would've expected (EQ #'F #'G) => T.  I am getting that result, i.e. 
(EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is LispWorks 
mistaken or is that an allowable result?

From: Rob Warnock
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <DpidnT1j35JpymLbnZ2dnUVZ_gmdnZ2d@speakeasy.net>
Damien Kick  <·····@earthlink.net> wrote:
+---------------
| With LispWorks Personal Edition 5.0.1 (PowerPC),
| I see the following behavior:
...
| CL-USER 3 > (setf (symbol-function 'f) *x*)
| #<anonymous interpreted function 200EB012>
| 
| CL-USER 4 > (setf (symbol-function 'g) *x*)
| #<anonymous interpreted function 200EB012>
| 
| CL-USER 5 > (eq #'f #'g)
| NIL
+---------------

I don't use LispWorks, so this may be a totally wild hair,
but try (SETF (FDEFINITION 'F) *X*) and see what happens.
SYMBOL-FUNCTION & FDEFINITION are *supposed* to be the same
when applied to symbols, but LispWorks might be treating
them differently...


-Rob

p.s. Oh, and in CMUCL all five of *X*, (SYMBOL-FUNCTION 'F),
(SYMBOL-FUNCTION 'G), (FDEFINITION 'F), & (FDEFINITION 'G) are EQ.


-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Damien Kick
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <13futov2lfgmtac@corp.supernews.com>
Rob Warnock wrote:
> Damien Kick  <·····@earthlink.net> wrote:
> +---------------
> | With LispWorks Personal Edition 5.0.1 (PowerPC),
> | I see the following behavior:
> ....
> | CL-USER 3 > (setf (symbol-function 'f) *x*)
> | #<anonymous interpreted function 200EB012>
> | 
> | CL-USER 4 > (setf (symbol-function 'g) *x*)
> | #<anonymous interpreted function 200EB012>
> | 
> | CL-USER 5 > (eq #'f #'g)
> | NIL
> +---------------
> 
> I don't use LispWorks, so this may be a totally wild hair,
> but try (SETF (FDEFINITION 'F) *X*) and see what happens.
> SYMBOL-FUNCTION & FDEFINITION are *supposed* to be the same
> when applied to symbols, but LispWorks might be treating
> them differently...

CL-USER 1 > (defparameter *x* #'(lambda () 13))
*X*

CL-USER 2 > (setf (fdefinition 'f) *x*)
#<anonymous interpreted function 200C9212>

CL-USER 3 > (setf (fdefinition 'g) *x*)
#<anonymous interpreted function 200C9212>

CL-USER 4 > (eq #'f #'g)
NIL

CL-USER 5 >
From: Rob Warnock
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <YrKdnS1bPvi8IZ3anZ2dnUVZ_rSinZ2d@speakeasy.net>
Damien Kick  <·····@earthlink.net> wrote:
+---------------
| Rob Warnock wrote:
| > I don't use LispWorks, so this may be a totally wild hair,
| > but try (SETF (FDEFINITION 'F) *X*) and see what happens.
...
| CL-USER 1 > (defparameter *x* #'(lambda () 13))
| *X*
| 
| CL-USER 2 > (setf (fdefinition 'f) *x*)
| #<anonymous interpreted function 200C9212>
| 
| CL-USER 3 > (setf (fdefinition 'g) *x*)
| #<anonymous interpreted function 200C9212>
| 
| CL-USER 4 > (eq #'f #'g)
| NIL
+---------------

Wow! That's especially weird, given that the address printed
is the same for both. Oh, wait a minute: SETF returns the value
being stored, *not* necessarily the new value of the location
being stored into. Try this: After doing the above, see what
(FDEFINITION 'F) & (FDEFINITION 'G) print at the REPL, and also
what #'F & #'G print, and whether those four values print the
same as *X* prints. It may be that there is some sort of implicit
wrapper around an FDEFINITION (or SYMBOL-FUNCTION) of a symbol
that's added whenever a new function value is stored into them.
and that function identity is really identity of the wrapper.

[In CMUCL & CLISP all five are the same, but clearly LispWorks
is different somehow.]

Also, what do (EQ *X* *X*) and (EQ #'F #'F) give? 
*Those*, at least, should both return T...


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Tobias C. Rittweiler
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <87ve9rw4lu.fsf@freebits.de>
····@rpw3.org (Rob Warnock) writes:

> Also, what do (EQ *X* *X*) and (EQ #'F #'F) give? 
> *Those*, at least, should both return T...

The former must (in absence of threads.) The latter not
necessarily so: 

Think of an interpreter that supports JIT compiling, and the measure if
compiling is worth it, is determined (among other factors) by a count of
how many times the function object was retrieved via FUNCTION. 

In (EQ #'F #'F) this counter could jump above a certain threshold right
after the first #'F, which will cause the second occurence of #'F to JIT
compile, and return a different function object.

This is a valid possibility in the implementation design space, AFAIU.

  -T. 
From: Klaus Harbo
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <46ff5943$0$73339$edfadb0f@dread11.news.tele.dk>
Damien Kick wrote:
> With LispWorks Personal Edition 5.0.1 (PowerPC), I see the following 
> behavior:
> 
> <code>
> CL-USER 1 > (defparameter *x* #'(lambda () 13))
> *X*
> 
> CL-USER 2 > *x*
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 3 > (setf (symbol-function 'f) *x*)
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 4 > (setf (symbol-function 'g) *x*)
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 5 > (eq #'f #'g)
> NIL
> 
> CL-USER 6 > (eql #'f #'g)
> NIL
> 
> CL-USER 7 > (eql #'f *x*)
> NIL
> 
> CL-USER 8 > (eq *x* *x*)
> T
> </code>
> 
> I would've expected (EQ #'F #'G) => T.  I am getting that result, i.e. 
> (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is LispWorks 
> mistaken or is that an allowable result?

FWIW, on LWM 5.0.2 (Intel) I get

   CL-USER 121 > (defparameter *x* (lambda () 27))
   *X*

   CL-USER 122 > (setf (symbol-function 'f) *x*)
   #.#'(LAMBDA () 27)

   CL-USER 123 > (setf (symbol-function 'g) *x*)
   #.#'(LAMBDA () 27)

   CL-USER 124 > (eql #'f #'g)
   T

   CL-USER 125 >

-Klaus.
From: Tobias C. Rittweiler
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <87ir5s8o9y.fsf@freebits.de>
Damien Kick <·····@earthlink.net> writes:

> I would've expected (EQ #'F #'G) => T.  I am getting that result,
> i.e. (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is
> LispWorks mistaken or is that an allowable result?

FUNCTION is allowed to return a fresh function object.

  -T.
From: Damien Kick
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <13fuu31dgq1nt4f@corp.supernews.com>
Tobias C. Rittweiler wrote:
> Damien Kick <·····@earthlink.net> writes:
> 
>> I would've expected (EQ #'F #'G) => T.  I am getting that result,
>> i.e. (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is
>> LispWorks mistaken or is that an allowable result?
> 
> FUNCTION is allowed to return a fresh function object.

I don't find anything in the hyperspec which seems to support this.  I 
could very well be missing something, though.  I do find

<blockquote>
If name is a lambda expression, then a lexical closure is returned. In 
situations where a closure over the same set of bindings might be 
produced more than once, the various resulting closures might or might 
not be eq.
</blockquote>

But there is only one LAMBDA involved and it should only be evaluated once.

But if that was the reason, I would expect that (EQ #'F #'F) => NIL, as 
FUNCTION would be returning a fresh function object every time, which 
hardly seems reasonable to me.  Am I missing something?
From: Tobias C. Rittweiler
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <87ejgg8lpg.fsf@freebits.de>
Damien Kick <·····@earthlink.net> writes:

> Tobias C. Rittweiler wrote:
>> Damien Kick <·····@earthlink.net> writes:
> >
> > > I would've expected (EQ #'F #'G) => T.  I am getting that result,
> > > i.e. (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is
> > > LispWorks mistaken or is that an allowable result?
> >
> > FUNCTION is allowed to return a fresh function object.
>
> I don't find anything in the hyperspec which seems to support this.  I
> could very well be missing something, though.  [...]

Well, there's 3.1.4 which says

  That is, two /functions/ that are behaviorally indistinguishable might
  or might not be identical.

If I remember correctly, this was a bit better worded in either CLtL or
CLtL2. But even there, it required some between-the-lines reading.

I think, it's just consensus that even `(flet ((f ...)) (eq #'f #'f))'
is allowed to return NIL.


But then, it's better to think of FUNCTION operating in this manner
anyway in face of function redefinition, and tracing/profiling.


  -T.
From: Damien Kick
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <13fvljak7jn001e@corp.supernews.com>
Tobias C. Rittweiler wrote:
> Damien Kick <·····@earthlink.net> writes:
> 
>> Tobias C. Rittweiler wrote:
>>> Damien Kick <·····@earthlink.net> writes:
>>>
>>>> I would've expected (EQ #'F #'G) => T.  I am getting that result,
>>>> i.e. (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is
>>>> LispWorks mistaken or is that an allowable result?
>>> FUNCTION is allowed to return a fresh function object.
>> I don't find anything in the hyperspec which seems to support this.  I
>> could very well be missing something, though.  [...]
> 
> Well, there's 3.1.4 which says
> 
>   That is, two /functions/ that are behaviorally indistinguishable might
>   or might not be identical.

I'm not convinced.  From 3.1.4

<blockquote>
In situations where a closure of a lambda expression over the same set 
of bindings may be produced more than once, the various resulting 
closures may or may not be identical, at the discretion of the 
implementation.
</blockquote>

So it seems to me that this is saying that evaluating the same lambda 
expression more than once is allowed to produce different closures.  But 
my reading of the text would lead me to expect (FLET ((F ...)) (EQ #'F 
#'F) => T but (FLET ((MAKE-F () #'(LAMBDA ()))) (EQ (MAKE-F) (MAKE-F))) 
=> implementation-defined.  In this case, the two behaviorally 
indistinguishable functions returned by MAKE-F might not be identical. 
But, again, perhaps I'm missing something.  However, with the fact that 
even other versions of LispWorks produce the results I was expecting, 
I'm pretty confident that this is a bug in the version of LispWorks I 
was using.
From: Kent M Pitman
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <ubqbkjbw9.fsf@nhplace.com>
Damien Kick <·····@earthlink.net> writes:

> With LispWorks Personal Edition 5.0.1 (PowerPC), I see the following
> behavior:
> 
> <code>
> CL-USER 1 > (defparameter *x* #'(lambda () 13))
> *X*
> 
> CL-USER 2 > *x*
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 3 > (setf (symbol-function 'f) *x*)
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 4 > (setf (symbol-function 'g) *x*)
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 5 > (eq #'f #'g)
> NIL
> 
> CL-USER 6 > (eql #'f #'g)
> NIL
> 
> CL-USER 7 > (eql #'f *x*)
> NIL
> 
> CL-USER 8 > (eq *x* *x*)
> T
> </code>
> 
> I would've expected (EQ #'F #'G) => T.  I am getting that result,
> i.e. (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is
> LispWorks mistaken or is that an allowable result?

I don't think the FUNCTION special form is required not to cons, and
hence I'm not sure object identity across a store/retrieve is
guaranteed.  I'm quite sure this was questioned, and whatever the
outcome, I know it's controversial.  I'm just saying I think it was
the status quo from CLTL that it might cons (perhaps only because I'm
pretty sure it was not specified there), and I don't recall X3J13
fixing that.  (If I'm not remembering some change we finally made,
someone please cite it.)

But, as I recall, the reasons why a rational implementor might not have
wanted to guarantee you expected behavior above include...

The function space needs to be quickly callable more than it needs to
be quickly something you can grab something out of.  So some
implementations may have wanted to store something there that was
unwrapped and needed to be wrapped on access.  (Normally you'd expect
they could use a tricky offset scheme to hide that, but that's really
quite dependent on the hardware architecture and addressing modes for
the processor in question--recall that CL is not written for a
specific architecture.)

It's probably fair to say that most functions are never accessed by #'
so the space it takes to represent a fully wrapped version of every system
function may have been considered something to be omitted.  Lisp used to
get hammered by other languages for how BIG it was, and forcing a space
use to hold a full wrapper may have been tough.  The function cell may be
unboxed, and boxing it may cons.  You could imagine the process of setting
symbol value to be an unboxing step, storing unboxed data in the symbol (or
a table indexed by it) because a second lary of boxing wasn't needed.

Also, if I recall correctly, there was specific problem with the transition
from CLTL to ANSI CL regarding the fact that (LAMBDA (X) X), the list, used
to be a function, and no longer was to be a function.  Clearly, even when it
WAS a function, this was problematic since you can't [easily] make the list
datatype executable, so putting it in the function cell was a barrier to 
speed. But this meant that in CLTL if you did 
 (SETF (SYMBOL-FUNCTION 'F) '(LAMBDA (X) X))
you had a serious problem.  You had to either wrap it with an object that
allowed it to be jumped to directly or coerce it to a fast object that replaced
it.  In the former case, extraction as a value even when there was no such 
object was slowed down because it wasn't a simple move instruction but now was
something that had to sniff at the value there and decide whether to 
provisionally unwrap it, returning the list (LAMBDA (X) X) again... or else
it had to be allowed to return #<FUNCTION (LAMBDA (X) X)> even when that was
not what had been stored.  So in CLTL things were a mess, which is why I'm
pretty sure CLTL semantics did not require equality.  But then when we moved
to ANSI, I'm not sure this part was cleaned up, even though it could have been;
there was the issue of backward compatibility, which my recollection was we
left to vendors.

Underlying the entire issue is the question of whether anyone should
be storing in the function cell for the purpose of object identity.
I think good arguments can be made on both sides, so it's one of those
language design choice points one has to think hard about it.

I've even heard rational arguments that functions should be among the short
list of datatypes, along with numbers and characters, that are super-primitive
because of their need to be operated on by raw machine instructions, and
that therefore should be always possible to store in "dirty registers" and 
hence might sometimes be split or coalesced in weird ways... for example, in
MACLISP (which pre-dated CL), small integers (the bottom range of fixnums,
but not all fixnums) were interned, and it was USUALLY possible to use EQ
on them, but even so, everyone knew not to lean very heavily on this because
sometimes in what we called number-compiled code (that is, code with heavy
declarations where you really wanted the compiler to be shifting things freely
among registers), it was critical to be able to move an integer into a 
non-pointer register, where it would lose its identity... and might even share identity with some other integer that was also using that register. Rather
than have the presence of a nearby EQ force such optimizations not to be done
(for fear the wrong result would occur), we just weakened the definition of
EQ.  And I've heard suggestions this should be true of functions.  (I've also
heard suggestions functions simply shouldn't be possible to compare with EQ
at all.)  I don't think EQ should ever signal an error under any circumstances,
but while I tend to think functions should have identity and not be subject
to the slippery-identity thing that integers and characters are, I do think
the case is not as clear in that case.

Whether any of this is why LW does what it does, I can't say.  I'm
just speaking general abstracts.  Does any of this make you more comfortable
with the fact that this might be legitimately different among implementations?
From: Carl Taylor
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <AEPLi.156737$ax1.111929@bgtnsc05-news.ops.worldnet.att.net>
"Damien Kick" <·····@earthlink.net> wrote in message 
····················@corp.supernews.com...
> With LispWorks Personal Edition 5.0.1 (PowerPC), I see the following behavior:

[...]

> I would've expected (EQ #'F #'G) => T.  I am getting that result, i.e. (EQ #'F 
> #'G) => T, with both Allegro CL 8.0 and Clisp.  Is LispWorks mistaken or is 
> that an allowable result?

No problem with LW Personal 5.0.1 on Windows XP!

clt


CL-USER 1 > (defparameter *x* #'(lambda () 13))
*X*

CL-USER 2 > *x*
#<anonymous interpreted function 2009D3EA>

CL-USER 3 > (setf (symbol-function 'f) *x*)
#<anonymous interpreted function 2009D3EA>

CL-USER 4 > (setf (symbol-function 'g) *x*)
#<anonymous interpreted function 2009D3EA>

CL-USER 5 > (eq #'f #'g)
T

CL-USER 6 > (eql #'f #'g)
T

CL-USER 7 > (eq *x* *x*)
T 
From: Barry Margolin
Subject: Re: Confused by behavior of LispWorks for code snippet
Date: 
Message-ID: <barmar-C65A72.16022530092007@comcast.dca.giganews.com>
In article <···············@corp.supernews.com>,
 Damien Kick <·····@earthlink.net> wrote:

> With LispWorks Personal Edition 5.0.1 (PowerPC), I see the following 
> behavior:
> 
> <code>
> CL-USER 1 > (defparameter *x* #'(lambda () 13))
> *X*
> 
> CL-USER 2 > *x*
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 3 > (setf (symbol-function 'f) *x*)
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 4 > (setf (symbol-function 'g) *x*)
> #<anonymous interpreted function 200EB012>
> 
> CL-USER 5 > (eq #'f #'g)
> NIL
> 
> CL-USER 6 > (eql #'f #'g)
> NIL
> 
> CL-USER 7 > (eql #'f *x*)
> NIL
> 
> CL-USER 8 > (eq *x* *x*)
> T
> </code>
> 
> I would've expected (EQ #'F #'G) => T.  I am getting that result, i.e. 
> (EQ #'F #'G) => T, with both Allegro CL 8.0 and Clisp.  Is LispWorks 
> mistaken or is that an allowable result?

What do you see when you just type #'f and #'g?

-- 
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 ***