From: Andrew Baine
Subject: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <1164731031.410443.295400@j44g2000cwa.googlegroups.com>
In a simplified simulation of poker, I want to represent players as
functions:

(defconstant +fold+ 0)
(defconstant +bet+ 1)

(defun random-folder (top bottom)
  #'(lambda (card)
      (declare (ignore card))
      (if (< (random bottom) top) +fold+ +bet+)))

(defun query-player ()
  #'(lambda (card)
      (if (yes-or-no-p (format nil "Your card is ~A; do you want to
bet?" card))
	  +bet+ +fold+)))

But I want to guarantee that two calls to query-player will return a
unique function each time, so I can index a hash by "players" which are
really just functions.  As it is, my implementation CLISP quite
reasonably has optimized query-player to return the very same function
every time.

CL-USER> (let ((p1 (query-player))
                       (p2 (query-player)))
                   (eq p1 p2))
T

Any advice on haw to create a new unique function every time?  Thanks
in advance,

Andrew

From: Barry Margolin
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <barmar-41C5F1.12522728112006@comcast.dca.giganews.com>
In article <························@j44g2000cwa.googlegroups.com>,
 "Andrew Baine" <·······@gmail.com> wrote:

> In a simplified simulation of poker, I want to represent players as
> functions:
> 
> (defconstant +fold+ 0)
> (defconstant +bet+ 1)
> 
> (defun random-folder (top bottom)
>   #'(lambda (card)
>       (declare (ignore card))
>       (if (< (random bottom) top) +fold+ +bet+)))
> 
> (defun query-player ()
>   #'(lambda (card)
>       (if (yes-or-no-p (format nil "Your card is ~A; do you want to
> bet?" card))
> 	  +bet+ +fold+)))
> 
> But I want to guarantee that two calls to query-player will return a
> unique function each time, so I can index a hash by "players" which are
> really just functions.  As it is, my implementation CLISP quite
> reasonably has optimized query-player to return the very same function
> every time.
> 
> CL-USER> (let ((p1 (query-player))
>                        (p2 (query-player)))
>                    (eq p1 p2))
> T
> 
> Any advice on haw to create a new unique function every time?  Thanks
> in advance,

As the other responder said, this seems like the wrong way to go about 
it.  But if you really want to, maybe something like this will do it:

(defun query-player (&aux (r (random 100)))
  #'(lambda (card)
      (if (and (< r 100)
               (yes-or-no-p ...))
        +bet+ +fold+)))

While a really smart optimizer *could* conceivably determine that (< r 
100) will always be true, it seems an unlikely optimization in real 
life.  But if it does, you could replace RANDOM with MY-RANDOM, which is 
just a user-written function that calls RANDOM -- as long as it's not 
declared INLINE, the compiler can't assume anything about it.

-- 
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: Pascal Bourguignon
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <87mz6ba5vp.fsf@thalassa.informatimago.com>
"Andrew Baine" <·······@gmail.com> writes:

> In a simplified simulation of poker, I want to represent players as
> functions:
>
> (defconstant +fold+ 0)
> (defconstant +bet+ 1)
>
> (defun random-folder (top bottom)
>   #'(lambda (card)
>       (declare (ignore card))
>       (if (< (random bottom) top) +fold+ +bet+)))
>
> (defun query-player ()
>   #'(lambda (card)
>       (if (yes-or-no-p (format nil "Your card is ~A; do you want to
> bet?" card))
> 	  +bet+ +fold+)))
>
> But I want to guarantee that two calls to query-player will return a
> unique function each time, so I can index a hash by "players" which are
> really just functions.  As it is, my implementation CLISP quite
> reasonably has optimized query-player to return the very same function
> every time.

Yes, since it's not a closure, it can fold the function.


> CL-USER> (let ((p1 (query-player))
>                        (p2 (query-player)))
>                    (eq p1 p2))
> T
>
> Any advice on haw to create a new unique function every time?  Thanks
> in advance,

pWhy do you want distinguishable functions if they're not
distinguishable (they don't have any closed state)?

(defun make-query-player (name)
  (lambda (card)
     (if (yes-or-no-p
            (format nil "Hey ~:(~A~)! Your card is ~A; do you want to bet?" 
                         name card))
         +bet+ +fold+)))

(let ((john (make-query-player "JOHN"))
      (jill (make-query-player "JILL")))
  (print `(they are different ,(eq john jill)))
  (values (funcall john '(heart king))
          (funcall jill '(square ace)))) 


(THEY ARE DIFFERENT NIL) 
Hey John! Your card is (HEART KING); do you want to bet? (yes/no) yes
Hey Jill! Your card is (SQUARE ACE); do you want to bet? (yes/no) no
1 ;
0


Otherwise, a way to produce a different function everytime would be:

(defun make-unique-function ()
   (compile nil '(lambda (card) (format t "I'm unique; ~A~%" card))))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: Pascal Costanza
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <4t3dqhF11vte3U1@mid.individual.net>
Pascal Bourguignon wrote:
> "Andrew Baine" <·······@gmail.com> writes:
> 
>> In a simplified simulation of poker, I want to represent players as
>> functions:
>>
>> (defconstant +fold+ 0)
>> (defconstant +bet+ 1)
>>
>> (defun random-folder (top bottom)
>>   #'(lambda (card)
>>       (declare (ignore card))
>>       (if (< (random bottom) top) +fold+ +bet+)))
>>
>> (defun query-player ()
>>   #'(lambda (card)
>>       (if (yes-or-no-p (format nil "Your card is ~A; do you want to
>> bet?" card))
>> 	  +bet+ +fold+)))
>>
>> But I want to guarantee that two calls to query-player will return a
>> unique function each time, so I can index a hash by "players" which are
>> really just functions.  As it is, my implementation CLISP quite
>> reasonably has optimized query-player to return the very same function
>> every time.
> 
> Yes, since it's not a closure, it can fold the function.
[...]

> Otherwise, a way to produce a different function everytime would be:
> 
> (defun make-unique-function ()
>    (compile nil '(lambda (card) (format t "I'm unique; ~A~%" card))))

This will perform a compilation on each call, which is quite inefficient.

What is needed is a wrapper that is guaranteed to be unique. You can do 
this with the CLOS MOP:

(defun query-player ()
   (let ((player (make-instance 'clos:funcallable-standard-object)))
     (set-funcallable-instance-function
       player
       (lambda (card)
         (if (yes-or-no-p ...)
           +bet+ +fold+)))
     player))

Because of make-instance, the result is guaranteed to be unique, and 
because the class is clos:funcallable-standard-object, you can still 
treat the result as a regular function.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Thomas A. Russ
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <ymifyc0bjd7.fsf@sevak.isi.edu>
Pascal Costanza <··@p-cos.net> writes:

> Pascal Bourguignon wrote:
> > Otherwise, a way to produce a different function everytime would be:
> > (defun make-unique-function ()
> 
> >    (compile nil '(lambda (card) (format t "I'm unique; ~A~%" card))))
> 
> This will perform a compilation on each call, which is quite inefficient.

I don't think it matters, since MAKE-UNIQUE-FUNCTION won't get called
very often.  It will apparently only be called once for each player in
the game, but the resulting compiled function will be called
frequently.  I think this is a good use of the lisp compiler.

(Although I do like the idea of the closure with the name as a better
solution to the original problem.)


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Barry Margolin
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <barmar-F55AC7.20080230112006@comcast.dca.giganews.com>
In article <···············@mid.individual.net>,
 Pascal Costanza <··@p-cos.net> wrote:

> Pascal Bourguignon wrote:
> > "Andrew Baine" <·······@gmail.com> writes:
> > 
> >> In a simplified simulation of poker, I want to represent players as
> >> functions:
> >>
> >> (defconstant +fold+ 0)
> >> (defconstant +bet+ 1)
> >>
> >> (defun random-folder (top bottom)
> >>   #'(lambda (card)
> >>       (declare (ignore card))
> >>       (if (< (random bottom) top) +fold+ +bet+)))
> >>
> >> (defun query-player ()
> >>   #'(lambda (card)
> >>       (if (yes-or-no-p (format nil "Your card is ~A; do you want to
> >> bet?" card))
> >> 	  +bet+ +fold+)))
> >>
> >> But I want to guarantee that two calls to query-player will return a
> >> unique function each time, so I can index a hash by "players" which are
> >> really just functions.  As it is, my implementation CLISP quite
> >> reasonably has optimized query-player to return the very same function
> >> every time.
> > 
> > Yes, since it's not a closure, it can fold the function.
> [...]
> 
> > Otherwise, a way to produce a different function everytime would be:
> > 
> > (defun make-unique-function ()
> >    (compile nil '(lambda (card) (format t "I'm unique; ~A~%" card))))
> 
> This will perform a compilation on each call, which is quite inefficient.
> 
> What is needed is a wrapper that is guaranteed to be unique. You can do 
> this with the CLOS MOP:
> 
> (defun query-player ()
>    (let ((player (make-instance 'clos:funcallable-standard-object)))
>      (set-funcallable-instance-function
>        player
>        (lambda (card)
>          (if (yes-or-no-p ...)
>            +bet+ +fold+)))
>      player))
> 
> Because of make-instance, the result is guaranteed to be unique, and 
> because the class is clos:funcallable-standard-object, you can still 
> treat the result as a regular function.

How about this:

(defun query-player ()
  (list (lambda (card) ...)))

Then when you actually want to invoke the player, you just have to do 
(funcall (car player)) instead of (funcall player).  This is less 
overhead, and doesn't require resorting to the MOP.

-- 
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: Frode Vatvedt Fjeld
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <2hslg3cshw.fsf@vserver.cs.uit.no>
"Andrew Baine" <·······@gmail.com> writes:

> (defconstant +fold+ 0)
> (defconstant +bet+ 1)

This is a C-ism that is an abomination in a symbolic language like
lisp. I'd suggest using keywords like :fold and :bet.

Or rather, I'd think it more natural to have the function return the
amount to bet, or NIL to fold.

> (defun random-folder (top bottom)
>   #'(lambda (card)
>       (declare (ignore card))
>       (if (< (random bottom) top) +fold+ +bet+)))

This to me looks like a misuse of the function abstraction. Functions
are not good for representing identities. Classes (as declared by
defclass) are designed specifically for this purpose.

> Any advice on haw to create a new unique function every time?

You can use "(compile ..)" or "(coerce .. 'function), but really I
don't think there are any explicit guarantees that you'll get fresh
identities even then. Take this as one more indication that this is a
misuse of functions.

-- 
Frode Vatvedt Fjeld
From: Andrew Baine
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <1164743512.943988.130720@j44g2000cwa.googlegroups.com>
Thank you for the responses.  Mssr Costanza seems to have answered my
question.
From: Andrew Baine
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <1164744904.867905.129240@n67g2000cwd.googlegroups.com>
On Nov 28, 1:53 pm, Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> "Andrew Baine" <·······@gmail.com> writes:
> > (defconstant +fold+ 0)
> > (defconstant +bet+ 1)
> This is a C-ism that is an abomination in a symbolic language like
> lisp. I'd suggest using keywords like :fold and :bet.
>

Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18, at
601.

Incidentally, Pascal, when I tried invoking the
clos:funcallable-standard-object I see that it is appneciably slower
than a function defined with defun, so perhaps I'm better off
associating non-unique functions with unique player objects.

Thanks to all, Andrew

CL-USER> (let ((f1 (let ((player (make-instance
'clos:funcallable-standard-object)))
		     (set-funcallable-instance-function
		      player
		      (lambda () t))
		     player))
	       (f2 #'(lambda () t))
	       (n 1000000))
	   (time
	    (dotimes (i n)
	      (funcall f1)))
	   (time (dotimes (i n)
		   (funcall f2))))


Real time: 1.9227648 sec.
Run time: 1.9227648 sec.
Space: 868 Bytes
Real time: 1.7324913 sec.
Run time: 1.7124624 sec.
Space: 868 Bytes
NIL

Similar results in repeated trials.
From: Pascal Costanza
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <4t3komF12ddn5U1@mid.individual.net>
Andrew Baine wrote:
> On Nov 28, 1:53 pm, Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
>> "Andrew Baine" <·······@gmail.com> writes:
>>> (defconstant +fold+ 0)
>>> (defconstant +bet+ 1)
>> This is a C-ism that is an abomination in a symbolic language like
>> lisp. I'd suggest using keywords like :fold and :bet.
>>
> 
> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18, at
> 601.

It could be that Mr. Norvig makes mistakes. ;)

> Incidentally, Pascal, when I tried invoking the
> clos:funcallable-standard-object I see that it is appneciably slower
> than a function defined with defun, so perhaps I'm better off
> associating non-unique functions with unique player objects.

I think in the long run it's probably better to go for an OOP solution. 
I mean, it's quite natural to consider a player to be an object.

(defclass player ()
   ())

(defmethod play ((player player) card)
   (if (yes-or-no-p ...)
     'bet 'fold))

(defun query-player ()
   ; actually not necessary
   (make-instance 'player))


...but I don't know the overall design of your application, so I cannot 
tell if this fits. It's weird though that you return 'bet or 'fold (or 
+bet+ or +fold+) instead of just executing functions bet or fold.

Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Andrew Baine
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <1164750832.675579.258470@80g2000cwy.googlegroups.com>
On Nov 28, 3:33 pm, Pascal Costanza <····@p-cos.net> wrote:
> I think in the long run it's probably better to go for an OOP solution.
> I mean, it's quite natural to consider a player to be an object.
>
> (defclass player ()
>    ())
>
> (defmethod play ((player player) card)
>    (if (yes-or-no-p ...)
>      'bet 'fold))
>
> (defun query-player ()
>    ; actually not necessary
>    (make-instance 'player))
>
> ...but I don't know the overall design of your application, so I cannot
> tell if this fits. It's weird though that you return 'bet or 'fold (or
> +bet+ or +fold+) instead of just executing functions bet or fold.

OK, that makes sense.  I'd implemented it that way at first -- I had a
query-player class, a random-player class, a discerning-player class
(who plays any card higher than some limit) and so on.  And I had one
generic method, "player-act" that dispatched on each of these.  I was
just thinking that since I only have one generic method, Icould avoid
CLOS if I implemented players as functions.

Thanks Pascal and Frode both for your insight.
From: Frode Vatvedt Fjeld
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <2hodqrcljf.fsf@vserver.cs.uit.no>
"Andrew Baine" <·······@gmail.com> writes:

> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18,
> at 601.

By all means do. I don't have PAIP at hand to look up your reference,
but I'm quite prepared to defend the position that manually mapping
symbols to integers for any other reason than to translate externally
defined bit-patters (i.e. to read or write generate binary
file-formats/protocols) is a terrible idea in Lisp.

Lisp symbols already have identity. In fact, identity (together with
name) is the prime feature of symbols, and using symbols as such for
identity I would consider more or less the essence of "symbolic
computing", which in turn is a central concept in Lisp.

Numbers, and more specifically integers, on the other hand, are
mathematical objects for which identity is irrelevant. Numbers in
general do not have identity: Two numbers may be /equal/, not
identical (although they may in fact be "identical" in some
implementation-dependent and more-or-less accidental way, this is
clearly not part of the concept of numbers per se (the exact same is
true of functions, which you happen to try to abuse also)).

So you see, giving symbols "identity" as integers is a bad idea,
twice. Counting your abuse of functions; thrice.

> Incidentally, Pascal, when I tried invoking the
> clos:funcallable-standard-object I see that it is appneciably slower
> than a function defined with defun, so perhaps I'm better off
> associating non-unique functions with unique player objects.

Although the speed variations might provide a clue of how the
implementors intended the mechanisms to (not) be used, the above would
be a terrible reason for you to take a step in the right direction.

-- 
Frode Vatvedt Fjeld
From: Andreas Thiele
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <ekjipf$8qe$01$1@news.t-online.com>
"Frode Vatvedt Fjeld" <······@cs.uit.no> schrieb im Newsbeitrag ···················@vserver.cs.uit.no...
> "Andrew Baine" <·······@gmail.com> writes:
>
>> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18,
>> at 601.
>
> By all means do. I don't have PAIP at hand to look up your reference,
> but I'm quite prepared to defend the position that manually mapping
> symbols to integers for any other reason than to translate externally
> defined bit-patters (i.e. to read or write generate binary
> file-formats/protocols) is a terrible idea in Lisp.
> ...

I have PAIP at hand: This is exactly what Norvig does here!

p. 601
(defconstant black 1 "A black piece")

p. 625
(count black board)
where board is a simple vector.

Andreas
From: Frode Vatvedt Fjeld
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <2hk61ecbnh.fsf@vserver.cs.uit.no>
"Andreas Thiele" <······@nospam.com> writes:

> I have PAIP at hand: This is exactly what Norvig does here!
> 
> p. 601
> (defconstant black 1 "A black piece")
> 
> p. 625
> (count black board)
> where board is a simple vector.

As it stands, this looks to me as very unfortunate advice from a
reputable textbook. Of course, there may be more to it than this, I
still don't have PAIP to look up the context in which these code
fragments appear.

I thought of one more reasonable use of this sort of mapping:
sometimes it makes sense to combine symbolic and numeric computing,
i.e. if there are numeric algorithms that solve (sub-)problems that
are generally dealt with as symbolic problems. However, here the
numbers are used precisely for their numeric properties, and not as
identity.

As for compile-time checking, you can still use symbols for identity,
as someone else pointed out. Personally, I'm very happy that Lisp does
not force me to maintain such more or less arbitrary declarations
about my programs. I find it requires extra editing that disrupts my
concentration on the actual problem at hand, and provides very little
actual value.

-- 
Frode Vatvedt Fjeld
From: Larry Clapp
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <slrnemrv43.vfh.larry@theclapp.ddts.net>
On 2006-11-29, Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> "Andreas Thiele" <······@nospam.com> writes:
>
>> I have PAIP at hand: This is exactly what Norvig does here!
>> 
>> p. 601
>> (defconstant black 1 "A black piece")
>> 
>> p. 625
>> (count black board)
>> where board is a simple vector.
>
> As it stands, this looks to me as very unfortunate advice from a
> reputable textbook. Of course, there may be more to it than this, I
> still don't have PAIP to look up the context in which these code
> fragments appear.

See http://norvig.com/paip/othello.lisp

Norvig puns on the value of black, white, empty, and outer to
subscript an array to get the proper character to draw the Othello
board.  He also takes the MAX of black and white at one point, though
I haven't digested the code enough to figure out why.

> I thought of one more reasonable use of this sort of mapping:
> sometimes it makes sense to combine symbolic and numeric computing,
> i.e. if there are numeric algorithms that solve (sub-)problems that
> are generally dealt with as symbolic problems. However, here the
> numbers are used precisely for their numeric properties, and not as
> identity.

In othello.lisp, too.

> As for compile-time checking, you can still use symbols for
> identity, as someone else pointed out. Personally, I'm very happy
> that Lisp does not force me to maintain such more or less arbitrary
> declarations about my programs. I find it requires extra editing
> that disrupts my concentration on the actual problem at hand, and
> provides very little actual value.

Using literals in your code, whether number or symbol, can lead to
maintenance difficulties.  Lisp allows the use of different literals
and different values for constants, but aside from that the rule still
applies.  (IMHO.)

-- L
From: Frode Vatvedt Fjeld
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <2hbqmod7b1.fsf@vserver.cs.uit.no>
Larry Clapp <·····@theclapp.org> writes:

> Using literals in your code, whether number or symbol, can lead to
> maintenance difficulties.  Lisp allows the use of different literals
> and different values for constants, but aside from that the rule
> still applies.  (IMHO.)

The way I see it, this is not always true, or true most of the time,
even. I mean, if you have a function that returns either :bet or
:pass, you're not going to solve any maintenance problems by
referencing those values indirectly through some mapping. Rather, it
will make your code less readable and clear, for little gain.

-- 
Frode Vatvedt Fjeld
From: Thomas A. Russ
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <ymi4psgbi7q.fsf@sevak.isi.edu>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:

> "Andreas Thiele" <······@nospam.com> writes:
> 
> > I have PAIP at hand: This is exactly what Norvig does here!
> > 
> > p. 601
> > (defconstant black 1 "A black piece")
> > 
> > p. 625
> > (count black board)
> > where board is a simple vector.
> 
> As it stands, this looks to me as very unfortunate advice from a
> reputable textbook. Of course, there may be more to it than this, I
> still don't have PAIP to look up the context in which these code
> fragments appear.

Well, I happened to have the book on my shelf.

The missing context is that section 18.2 is about representation
choices, and Norvig is explicit about why he chooses to use small
integers for the representation.  From p. 599:

"An advantage of this approach is that an element can be packed into a
small space.  In the Othello domain, we anticipate that efficiency will
be important, because one way to pick a good move is to look at a large
number of posible sequences of moves....Thus we are willing to look hard
at alternative representations to find an efficient one.  It takes only
two bits to represent one of three possible types [using integers],
while it takes many more (perhaps 32) to represent a symbol.  Thus, we
may save space by representing pieces as small integers rather than
symbols."

> I thought of one more reasonable use of this sort of mapping:
> sometimes it makes sense to combine symbolic and numeric computing,
> i.e. if there are numeric algorithms that solve (sub-)problems that
> are generally dealt with as symbolic problems. However, here the
> numbers are used precisely for their numeric properties, and not as
> identity.

There is one clever use of this as well, but that could also be
accomplished by an even more clever use of single-character symbolic
names. 

> -- 
> Frode Vatvedt Fjeld

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Alex Mizrahi
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <456da278$0$49198$14726298@news.sunsite.dk>
(message (Hello 'Frode)
(you :wrote  :on '(28 Nov 2006 22:24:04 +0100))
(

 ??>> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18,
 ??>> at 601.

 FVF> By all means do. I don't have PAIP at hand to look up your reference,
 FVF> but I'm quite prepared to defend the position that manually mapping
 FVF> symbols to integers for any other reason than to translate externally
 FVF> defined bit-patters (i.e. to read or write generate binary
 FVF> file-formats/protocols) is a terrible idea in Lisp.

OTOH if you misspel symbol: :but instead of :bet, you'll notice this only in 
run-time, but if you use constants +bet+, if you write +but+, you'll likely 
get unbound-variable warning during compilation.
OTOH it's typicall in Lisp that you'll get wrong beh at run-time, but no 
warning at compile-time, because of dynamic nature..

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity") 
From: Andrew Baine
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <1164818301.628910.159420@j72g2000cwa.googlegroups.com>
On Nov 29, 10:08 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
> (message (Hello 'Frode)
> (you :wrote  :on '(28 Nov 2006 22:24:04 +0100))
> (
>
>  ??>> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18,
>  ??>> at 601.
>
>  FVF> By all means do. I don't have PAIP at hand to look up your reference,
>  FVF> but I'm quite prepared to defend the position that manually mapping
>  FVF> symbols to integers for any other reason than to translate externally
>  FVF> defined bit-patters (i.e. to read or write generate binary
>  FVF> file-formats/protocols) is a terrible idea in Lisp.
>
> OTOH if you misspel symbol: :but instead of :bet, you'll notice this only in
> run-time, but if you use constants +bet+, if you write +but+, you'll likely
> get unbound-variable warning during compilation.
> OTOH it's typicall in Lisp that you'll get wrong beh at run-time, but no
> warning at compile-time, because of dynamic nature..
>
> )
> (With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
> "People who lust for the Feel of keys on their fingertips (c) Inity")

Would this be sensible then?

(defconstant +bet+ :bet)
(defconstant +fold+ :fold)

Using defconstant at the beginning of a file does seem a nice way to
point out that there are some meaningful symbols you're going to be
using in the program.  Is this still an abomination?!

Andrew
From: Pascal Bourguignon
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <87k61e8a45.fsf@thalassa.informatimago.com>
"Andrew Baine" <·······@gmail.com> writes:

> On Nov 29, 10:08 am, "Alex Mizrahi" <········@users.sourceforge.net>
> wrote:
>> (message (Hello 'Frode)
>> (you :wrote  :on '(28 Nov 2006 22:24:04 +0100))
>> (
>>
>>  ??>> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18,
>>  ??>> at 601.
>>
>>  FVF> By all means do. I don't have PAIP at hand to look up your reference,
>>  FVF> but I'm quite prepared to defend the position that manually mapping
>>  FVF> symbols to integers for any other reason than to translate externally
>>  FVF> defined bit-patters (i.e. to read or write generate binary
>>  FVF> file-formats/protocols) is a terrible idea in Lisp.
>>
>> OTOH if you misspel symbol: :but instead of :bet, you'll notice this only in
>> run-time, but if you use constants +bet+, if you write +but+, you'll likely
>> get unbound-variable warning during compilation.
>> OTOH it's typicall in Lisp that you'll get wrong beh at run-time, but no
>> warning at compile-time, because of dynamic nature..

But it doesn't matter much because we don't expect bugs to be detected
at "compilation time", but at unit and coverage test time.

LISP> (defun f () 'bug)       {programming time}
                              {compilation time}
LISP> (equal (f) 'bag)        {unit test}
NIL                           {bug!}
LISP> (defun f () 'bag)       {debug (correction) time}
                              {compilation time}
LISP> (equal (f) 'bag)        {unit test}
T                             {success}


> Would this be sensible then?
>
> (defconstant +bet+ :bet)
> (defconstant +fold+ :fold)
>
> Using defconstant at the beginning of a file does seem a nice way to
> point out that there are some meaningful symbols you're going to be
> using in the program.  

Yes, IF the compiler you have signals the use of undefined variables.
But it would be a strange use...
Better would be to write some declarations:

(declaim (ftype (function () (member :bet :fold)) f))
(defun f () :bug)
   
But still a compiler just compile it without a warning; you always
need the above unit tests!


> Is this still an abomination?!

No.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Wanna go outside.
Oh, no! Help! I got outside!
Let me back inside!
From: Thomas A. Russ
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <ymibqmobiij.fsf@sevak.isi.edu>
"Andrew Baine" <·······@gmail.com> writes:

> On Nov 28, 1:53 pm, Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> > "Andrew Baine" <·······@gmail.com> writes:
> > > (defconstant +fold+ 0)
> > > (defconstant +bet+ 1)
> > This is a C-ism that is an abomination in a symbolic language like
> > lisp. I'd suggest using keywords like :fold and :bet.
> >
> 
> Shall I forward your concerns to Mr. Norvig?  See PAIP, chapter 18, at
> 601.

Feel free.  But you have to also realize that Peter Norvig had a
specific reason for using numeric constants, namely to implement his
simple mapping from pieces into printing characters in the NAME-OF
function.

It is sometimes important to understand the reasons for certain design
choices rather than to just blindly copy the surface form of the
program.  It doesn't appear that the considerations that led Norvig to
use small integers as his representation apply to your particular case.


-- 
Thomas A. Russ,  USC/Information Sciences Institute

In the South Seas there is a cargo cult of people. During the war they
saw airplanes with lots of good materials, and they want the same thing
to happen now.  So they've arranged to make things like runways, to put
fires along the sides of the runways, to make a wooden hut for a man to
sit in, with two wooden pieces on his head to headphones and bars of
bamboo sticking out like antennas -- he's the controller -- and they
wait for the airplanes to land. They're doing everything right. The form
is perfect. It looks exactly the way it looked before. But it doesn't
work. No airplanes land. So I call these things cargo cult science,
because they follow all the apparent precepts and forms of scientific
investigation, but they're missing something essential, because the
planes don't land.

   -- Richard Feynman "Cargo Cult Science".
From: Pascal Costanza
Subject: Re: Guarantee that two functions with the same body are not eq
Date: 
Message-ID: <4t3jikF1231nrU1@mid.individual.net>
Andrew Baine wrote:
> Thank you for the responses.  Mssr Costanza seems to have answered my
> question.

I have answered the technical question. It's definitely a good idea to 
think about Frode's reply and see whether you can improve your design.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/