From: Jeff M.
Subject: User-defined EQUALP
Date: 
Message-ID: <1097509143.636285.29830@f14g2000cwb.googlegroups.com>
Like SETF, is there a method of defining new EQUALP functions or
macros. I have a foreign function that compares two areas of RAM to see
if they are the same or one completely encloses the other:

int is_same_memory(mem_range *, mem_range *);

I don't really mind calling the function, but I think it would be nice
to wrap this into an EQUALP if possible. Thanks!

Jeff

From: Marco Antoniotti
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <shDad.9$u5.7833@typhoon.nyu.edu>
Jeff M. wrote:
> Like SETF, is there a method of defining new EQUALP functions or
> macros. I have a foreign function that compares two areas of RAM to see
> if they are the same or one completely encloses the other:
> 
> int is_same_memory(mem_range *, mem_range *);
> 
> I don't really mind calling the function, but I think it would be nice
> to wrap this into an EQUALP if possible. Thanks!

(defpackage "MY-EQUAL" (:use "CL")
   (:export "EQUALITY"))


(in-package "MY-EQUAL")


(defgeneric equality (a b))

(defmethod equality ((a number) (b number)) (= a b))

(defmethod equality ((a sequence) (b sequence))
    (every #'equality a b))

(defmethod equality ((a cons) (b cons))
    (and (equality (cdr a) (cdr b))
         (equality (cdr a) (cdr b))))

(defmethod equality ((a symbol) (b symbol))
    (eql a b))

(defmethod equality ((a character) (b character))
    (char= a b))

... more methods here ...

The above is untested and also long winded, but it is just to give you 
the idea...

Cheers
--
Marco
From: Christophe Turle
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <416b8c30$0$6929$626a14ce@news.free.fr>
"Marco Antoniotti" <·······@cs.nyu.edu> a �crit dans le message de
····················@typhoon.nyu.edu...
>
>
> Jeff M. wrote:
> > Like SETF, is there a method of defining new EQUALP functions or
> > macros. I have a foreign function that compares two areas of RAM to see
> > if they are the same or one completely encloses the other:
> >
> > int is_same_memory(mem_range *, mem_range *);
> >
> > I don't really mind calling the function, but I think it would be nice
> > to wrap this into an EQUALP if possible. Thanks!
>
> (defpackage "MY-EQUAL" (:use "CL")
>    (:export "EQUALITY"))
>
>
> (in-package "MY-EQUAL")

;;; being in "USER"

(shadow 'equalp)

>
> (defgeneric equality (a b))
>
> (defmethod equality ((a number) (b number)) (= a b))
>
> (defmethod equality ((a sequence) (b sequence))
>     (every #'equality a b))
>
> (defmethod equality ((a cons) (b cons))
>     (and (equality (cdr a) (cdr b))
>          (equality (cdr a) (cdr b))))
>
> (defmethod equality ((a symbol) (b symbol))
>     (eql a b))
>
> (defmethod equality ((a character) (b character))
>     (char= a b))
>
> ... more methods here ...

(defmethod equalp (a b)
  (cl:equalp a b) )

(defmethod equalp ((a mem-range) (b mem-range))
  (is-same-memory a b) )

>
> The above is untested and also long winded, but it is just to give you
> the idea...

And this is tested ;-)


___________________________________________________________
Christophe Turle.
(format nil ···@~S.~S" 'c.turle 'wanadoo 'fr)

sava preview : http://perso.wanadoo.fr/turle/lisp/sava.html
From: Pascal Bourguignon
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <87zn2sqje7.fsf@thalassa.informatimago.com>
"Christophe Turle" <······@nospam.com> writes:
> (shadow 'equalp)
> 
> (defmethod equalp (a b)
>   (cl:equalp a b) )
> 
> (defmethod equalp ((a mem-range) (b mem-range))
>   (is-same-memory a b) )

Well, while I'm usually promoter of using the Common-Lisp package
system to write new lisps, like COMMON-LISP-WITH-GENERIC-EQUALP, I
have to note that there are still problems with redefining such a
standard operator:  

    - You'll have to replace/add (:USE "COMMON-LISP-WITH-GENERIC-EQUALP") 
      in all the packages you're using in your project that use EQUALP
      and may possibly get one of your objects.

    - It still does not work with COMMON-LISP:MAKE-HASH-TABLE and a
      few others, you'll have to write a layer over a lot of
      COMMON-LISP!

So really, unless you're in the language design business, you should
use a different name for your generic.


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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Marco Antoniotti
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <416D34A8.6040007@cs.nyu.edu>
Edi Weitz wrote:
> On Wed, 13 Oct 2004 12:20:21 +0200, "Christophe Turle" <······@nospam.com> wrote:
> 
> 
>>Isn't it because COMMON-LISP:MAKE-HASH-TABLE is bad designed ?
> 
> 
> No.
> 
> 
>>naively, the test keyword should take whatever binary predicate you
>>provide. After all, at an abstract level, it's just used to compare
>>keys.
> 
> 
> As you said, that's na�ve. You not only need a binary predicate but
> you also need a hash function which fits this predicate and which
> should be efficient. If the user can provide arbitrary hash function
> then he/she also has to provide the hash function.

Which is why SXHASH is "naively" designed. :)  CMUCL used to return the 
"correct" value 42 for any call to (SXHASH (MAKE-INSTANCE 'FOO)).  LWW 
gives a warning and returns the less correct number 7 :)

Of course this is one of the things that needs updating.  After all 
there are plenty of extensions in various CL that go in this direction.
Yet, this is not a task for the faint of heart, as the whole chapter on 
HASH-TABLEs and lengthy discussions here show.

Cheers
--
Marco
From: Frode Vatvedt Fjeld
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <2hpt3maovs.fsf@vserver.cs.uit.no>
"Christophe Turle" <······@nospam.com> writes:

> Isn't it because COMMON-LISP:MAKE-HASH-TABLE is bad designed ?
> naively, the test keyword should take whatever binary predicate you
> provide. After all, at an abstract level, it's just used to compare
> keys.

I think the clue with user-specified hash-tables lies in the
relationship you need betwen equalp or whatever test you have and the
hashing function. I.e. if two objects are the same under some test,
that needs to imply that the hashing function returns the same value
when applied to either object.

-- 
Frode Vatvedt Fjeld
From: Edi Weitz
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <uk6tuj3pt.fsf@agharta.de>
On Wed, 13 Oct 2004 12:41:41 +0200, Svein Ove Aas <·········@aas.no> wrote:

> Any better ways around?

Yes, use CMUCL, LispWorks, AllegroCL, CLISP, or some other
implementation which supports user-defined hash functions.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Edi Weitz
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <u1xg2d4my.fsf@agharta.de>
On Wed, 13 Oct 2004 17:15:47 +0200, Svein Ove Aas <·········@aas.no> wrote:

> User-defined hash functions weren't the issue; user-defined equality
> predicates were.
>
> I needed to consider some objects to be equal that even euqalp
> didn't.

Well, of course all of these also allow for user-defined equality
predicates. Why else should they offer user-defined hash functions?
RTFM.

  <http://www.franz.com/support/documentation/6.2/doc/implementation.htm#cl-make-hash-table-2>
  <http://www.lispworks.com/reference/lw43/LWRM/html/lwref-57.htm#marker-986038>
  <http://common-lisp.net/project/cmucl/doc/cmu-user/extensions.html#toc18>
  <http://clisp.sourceforge.net/impnotes/hash-dict.html#make-hash>

Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Svein Ove Aas
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <ckji4e$e4k$1@services.kq.no>
Edi Weitz wrote:

> On Wed, 13 Oct 2004 17:15:47 +0200, Svein Ove Aas <·········@aas.no>
> wrote:
> 
>> User-defined hash functions weren't the issue; user-defined equality
>> predicates were.
>>
>> I needed to consider some objects to be equal that even euqalp
>> didn't.
> 
> Well, of course all of these also allow for user-defined equality
> predicates. Why else should they offer user-defined hash functions?
> RTFM.
> 
Why, indeed?


Actually, I was using sbcl, but that's all right. This could be useful
information later - thanks. 
From: Christophe Turle
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <416d5205$0$12156$636a15ce@news.free.fr>
"Edi Weitz" <········@agharta.de> a �crit dans le message de
··················@agharta.de...
> On Wed, 13 Oct 2004 12:20:21 +0200, "Christophe Turle" <······@nospam.com>
wrote:
>
> > Isn't it because COMMON-LISP:MAKE-HASH-TABLE is bad designed ?
>
> No.
>
> > naively, the test keyword should take whatever binary predicate you
> > provide. After all, at an abstract level, it's just used to compare
> > keys.
>
> As you said, that's na�ve. You not only need a binary predicate but
> you also need a hash function which fits this predicate and which
> should be efficient. If the user can provide arbitrary hash function
> then he/she also has to provide the hash function.

1- Perhaps the fact that the user can't provide his hash function is bad
design ;-)

2- Is it really needed to provide the hash function, say by using :hash-fn ?
i believe the answer is no.

(defmethod make-hash-fn-from-equal-def ((fn (eql #'eq)))
  #'eql-hash-fn )

(defmethod make-hash-fn-from-equal-def ((fn (eql #'my-equal)))
  #'eql-my-equal-fn )

; for the general case

(defmacro def-equality-predicate ( ...)
  ...
  `(progn
      (defmethod make-hash-fn-from-equal-def ((p (eql
',equality-predicate)))
        ',(gen-hash-fn equality-predicate) )))

If you can give a good/efficient hash function from an equal definition,
code this expertise in gen-hash-fn. This way all cases handled by the
:hash-fn may be handled without it.


-- 

___________________________________________________________
Christophe Turle.
(format nil ···@~S.~S" 'c.turle 'wanadoo 'fr)

sava preview : http://perso.wanadoo.fr/turle/lisp/sava.html
From: Pascal Bourguignon
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <87hdp1t7f5.fsf@thalassa.informatimago.com>
"Jeff M." <·······@gmail.com> writes:

> Like SETF, is there a method of defining new EQUALP functions or
> macros. I have a foreign function that compares two areas of RAM to see
> if they are the same or one completely encloses the other:
> 
> int is_same_memory(mem_range *, mem_range *);
> 
> I don't really mind calling the function, but I think it would be nice
> to wrap this into an EQUALP if possible. Thanks!

You'll have to use your implementation specific FFI, or UFFI that
provides a uniform API over your implementation 9and a couple of
others) specific FFI, and to name it EQUAL-BIT-PATTERN-IN-MEMORY.

You'll have to add also operators to create MEM-RANGE perhaps from
Common-Lisp objects (do you know that Common-Lisp objects can and do
move often due to the garbage collection?) or from foreign objects.


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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Jeff
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <hyEad.349612$mD.3847@attbi_s02>
Pascal Bourguignon wrote:

> "Jeff M." <·······@gmail.com> writes:
> 
> > Like SETF, is there a method of defining new EQUALP functions or
> > macros. I have a foreign function that compares two areas of RAM to
> > see if they are the same or one completely encloses the other:
> > 
> > int is_same_memory(mem_range *, mem_range *);
> > 
> > I don't really mind calling the function, but I think it would be
> > nice to wrap this into an EQUALP if possible. Thanks!
> 
> You'll have to use your implementation specific FFI, or UFFI that
> provides a uniform API over your implementation 9and a couple of
> others) specific FFI, and to name it EQUAL-BIT-PATTERN-IN-MEMORY.
> 
> You'll have to add also operators to create MEM-RANGE perhaps from
> Common-Lisp objects (do you know that Common-Lisp objects can and do
> move often due to the garbage collection?) or from foreign objects.

Thanks for the reply, but perhaps I didn't state the problem properly.
I already have the FFI done (LispWorks FLI, actually) and it works
great. I can call is_same_memory() without problems. I'm hoping to do
something along the lines of:

(defmethod equalp ((range1 mem-range) (range2 mem-range))
	(is-same-memory range1 range2))

Nothing special, just a little syntactic sugar is all. If this can't be
done, that's fine. Just wondering if there was a little "hook" into
EQUALP that I was unaware of.

Jeff M.
From: Svein Ove Aas
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <ckf5nt$f6i$1@services.kq.no>
Jeff wrote:

> Pascal Bourguignon wrote:
> 
>> "Jeff M." <·······@gmail.com> writes:
>> 
>> > Like SETF, is there a method of defining new EQUALP functions or
>> > macros. I have a foreign function that compares two areas of RAM to
>> > see if they are the same or one completely encloses the other:
>> > 
>> > int is_same_memory(mem_range *, mem_range *);
>> > 
>> > I don't really mind calling the function, but I think it would be
>> > nice to wrap this into an EQUALP if possible. Thanks!
>> 
>> You'll have to use your implementation specific FFI, or UFFI that
>> provides a uniform API over your implementation 9and a couple of
>> others) specific FFI, and to name it EQUAL-BIT-PATTERN-IN-MEMORY.
>> 
>> You'll have to add also operators to create MEM-RANGE perhaps from
>> Common-Lisp objects (do you know that Common-Lisp objects can and do
>> move often due to the garbage collection?) or from foreign objects.
> 
> Thanks for the reply, but perhaps I didn't state the problem properly.
> I already have the FFI done (LispWorks FLI, actually) and it works
> great. I can call is_same_memory() without problems. I'm hoping to do
> something along the lines of:
> 
> (defmethod equalp ((range1 mem-range) (range2 mem-range))
> (is-same-memory range1 range2))
> 
> Nothing special, just a little syntactic sugar is all. If this can't be
> done, that's fine. Just wondering if there was a little "hook" into
> EQUALP that I was unaware of.
> 
There is no such hook, for what appears to be very good reasons.
If you want to create such a function, you should probbaly name it
'similar', because it isn't going to use the same notion of equality for
all objects you could pass to it.

(Ever seen how the Java 'equals' function tends to work out?)
From: Mark McConnell
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <d3aed052.0410120611.40d6f86c@posting.google.com>
Svein Ove Aas <·········@aas.no> wrote in message news:<············@services.kq.no>...
> (Ever seen how the Java 'equals' function tends to work out?)

Superbly well.  You have to define it carefully for the objects you're
comparing, and define hashCode() to be "consistent with equals".  This
means
[*]   a.equals(b)  implies  a.hashCode() == b.hashCode()
but not conversely.  After that, Hashtables and the other Collections
classes handle "equal" pairs of objects intelligently.

In Lisp, hash-tables only support the four built-in equality
predicates.  Even if I write my own hash-code function consistent with
my custom equality predicate, I can't use it for the keys in a Lisp
hash-table unless hash-code is injective--in other words, unless [*]
_does_ hold conversely.  IMHO, this is one area where Java is better
than Lisp.  One of the :-) few :-) areas...
From: Edi Weitz
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <ubrf8ypbn.fsf@agharta.de>
On 12 Oct 2004 07:11:15 -0700, ···············@yahoo.com (Mark McConnell) wrote:

> In Lisp, hash-tables only support the four built-in equality
> predicates.

Some implementations support user-defined extensions.

Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Pascal Bourguignon
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <87vfdfrj5e.fsf@thalassa.informatimago.com>
Edi Weitz <········@agharta.de> writes:

> On 12 Oct 2004 07:11:15 -0700, ···············@yahoo.com (Mark McConnell) wrote:
> 
> > In Lisp, hash-tables only support the four built-in equality
> > predicates.
> 
> Some implementations support user-defined extensions.

They should issue CLRFIs!

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

Voting Democrat or Republican is like choosing a cabin in the Titanic.
From: Lars Brinkhoff
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <85655dbhqg.fsf@junk.nocrew.org>
Ingvar <······@hexapodia.net> writes:
> do people prefer:
>         (HASHREF <table> <key> &optional default-value)
> or:
>         (HASHREF <key> <table> &optional default-value)
> The first is closer to AREF, the latter is closer to GETHASH.

I'd prefer GETHASH closeness.

-- 
Lars Brinkhoff,         Services for Unix, Linux, GCC, HTTP
Brinkhoff Consulting    http://www.brinkhoff.se/
From: Adam Warner
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <pan.2004.10.14.12.32.35.198097@consulting.net.nz>
Hi Ingvar,

> I'll get it cleaned up, do a bit more testing and provide a hook for a
> default number of hash buckets for any given "hash-table type
> designator".

Great! As an aside, it's a pity that weak hash tables appear to be
impossible to implement in userspace.

> Oh, while I still have the option of changing things, do people (in
> general) prefer:
>         (HASHREF <table> <key> &optional default-value)
> or:
>         (HASHREF <key> <table> &optional default-value)
> 
> The first is closer to AREF, the latter is closer to GETHASH.

(<table> <key> &optional default-value). GETHASH and NTH have anomalous
argument orders. It's a good opportunity to fix an irregularity.

Regards,
Adam
From: ··············@hotmail.com
Subject: Re: User-defined EQUALP
Date: 
Message-ID: <1097613702.196580.61810@c13g2000cwb.googlegroups.com>
It all depends on what you mean by a "new:" EQUALP.

There is nothing that prevents you from defining any Lisp function you
want to perform any comparison you wish.

What exactly do you want the rest of Lisp to do with your function that
it does with EQUALP?