(eql (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle") (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle")) -> NIL I think it should be eql, probably eq. I know they are equal.
The documentation for eq says: Returns true if its arguments are the same, identical object; otherwise, returns false.
They are and they are not. That they are not is only a quirk of the implementation.
eql adds equality for characters and numbers
I'd argue that was done because of uncertainly over boxing in different implementations and not wanting to fall back to a more expensive equal call. Seems that java objects are an equivalent case.
Where this matters is that case and friends use eql for comparison. One ought to be able to write a standard case statement that switches off of an enum defined java, but one can't at the moment.
That's all, Alan
On Sun, Apr 25, 2010 at 10:17 AM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
(eql (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle") (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle")) -> NIL I think it should be eql, probably eq. I know they are equal.
The documentation for eq says: Returns true if its arguments are the same, identical object; otherwise, returns false.
They are and they are not. That they are not is only a quirk of the implementation.
Well, eq is supposed to work following "quirks of the implementation", for example, eql fixnums are not required to be eq and indeed they are not on abcl due to boxing. So two boxed java objects are not eq.
eql adds equality for characters and numbers
right, and equal should provide equality for compound objects, descending their structure. But the standard explicitly says that equal behaves like eq for all objects excepts for those types mentioned in the definition of equal. I encountered this problem too in the past and I tried to understand it better by carefully reading the Hyperspec and by asking people on comp.lang.lisp about it. It seems that there's not a uniform opinion in the Lisp community: some say that the standard prohibits implementations from giving EQUAL a new meaning for "non-CL" objects. Others say that implementation can and sometimes should change CL functions giving them new meanings for implementation-specific objects. Others still say that implementations can extend EQUAL, but should not do it to avoid surprising the users. I personally think that position #2 is the most sensible in this case, but it's hard to get it right, because some people think #2 and #3 break CL conformance.
If you're interested, the discussion on c.l.l. is here: http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/c2f56ab69c93...
Bye, Alessio
Alessio Stalla alessiostalla@gmail.com writes:
On Sun, Apr 25, 2010 at 10:17 AM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
(eql (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle") (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle")) -> NIL I think it should be eql, probably eq. I know they are equal.
The documentation for eq says: Returns true if its arguments are the same, identical object; otherwise, returns false.
They are and they are not. That they are not is only a quirk of the implementation.
Well, eq is supposed to work following "quirks of the implementation", for example, eql fixnums are not required to be eq and indeed they are not on abcl due to boxing. So two boxed java objects are not eq.
eql adds equality for characters and numbers
right, and equal should provide equality for compound objects, descending their structure. But the standard explicitly says that equal behaves like eq for all objects excepts for those types mentioned in the definition of equal. I encountered this problem too in the past and I tried to understand it better by carefully reading the Hyperspec and by asking people on comp.lang.lisp about it. It seems that there's not a uniform opinion in the Lisp community: some say that the standard prohibits implementations from giving EQUAL a new meaning for "non-CL" objects. Others say that implementation can and sometimes should change CL functions giving them new meanings for implementation-specific objects. Others still say that implementations can extend EQUAL, but should not do it to avoid surprising the users. I personally think that position #2 is the most sensible in this case, but it's hard to get it right, because some people think #2 and #3 break CL conformance.
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Regarding extending EQUAL, just don't. Whatever you do, it won't come off as natural.
Rather provide an EXT:EQUIVALENT generic function (or some small protocol) which can a) be extended by the user, b) hooks into however Java does it (Comparable?).
-T.
On Apr 25, 2010, at 6:55, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
FWIW, I think it makes sense to have EQL compare “deeply” anything which is a strictly (outside of using explicitly write-to-arbitrary- memory operations) immutable “box”. Such immutability is rare in CL: characters and numbers happen to be its only occurrences. But the spirit of the thing, it seems to me, is to make EQL hide distinctions which are of no use whatsoever to the end programmer.
(Note that by strictly immutable I mean that you can't change *what object the box contains*, not that you can't mutate the object the box contains if that object is mutable.)
Rather provide an EXT:EQUIVALENT generic function (or some small protocol) which can a) be extended by the user, b) hooks into however Java does it (Comparable?).
Object.equals(Object), actually.
Kevin Reid kpreid@switchb.org writes:
Rather provide an EXT:EQUIVALENT generic function (or some small protocol) which can a) be extended by the user, b) hooks into however Java does it (Comparable?).
Object.equals(Object), actually.
I'm not versed in Java, so pardon if we're actually on the same line.
I meant to say that when users specialize on EQUIVALENT, Java code can take advantage of that, too, presumably by using .equals(). (Hence my parenthetical remark about a protocol, rather than a single generic function, in case this kind of integration turns out to require more elaboration.)
-T.
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
1. Our Java side JavaObject class is merely a box for a Java instance value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word 4. From point (1) and the definitions of EQ and EQL, I concur with Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
Bye,
Erik.
[1] http://www.lispworks.com/documentation/lw51/CLHS/Body/26_glo_o.htm#object
On 25 April 2010 21:37, Erik Huelsmann ehuels@gmail.com wrote:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will)
The abstract boxing is an implementation detail. If you want to walk through that implementation detail in order to find out whether there are java enums underneath the boxing, CLHS won't stop you.
- The definitions of EQ and EQL talk about Objects, but I interpret
them to refer to the first meaning in [1], not to instances of lisp classes
Objects in this case are not object-oriented in any way; multiple languages, object-oriented or not, have a term object that means an addressable thing that may have multiple references (in the case of lisp, dynamic and lexical) to it. As far as I can see, Common Lisp is not at all different in this regard. Numbers are objects. Sequences are objects. CLOS objects are objects.
- From point (1) and the definitions of EQ and EQL, I concur with
Alan that "raison d'etre" of EQL should equally apply to JavaObjects
I do believe that it's within the CL spec to do EQL to JavaObjects wrapping enums/ints so that the values are inspected, and as java-reference comparison to others. Some JavaObjects are numbers. Some are not.
On Sun, Apr 25, 2010 at 8:43 PM, Ville Voutilainen ville.voutilainen@gmail.com wrote:
I do believe that it's within the CL spec to do EQL to JavaObjects wrapping enums/ints so that the values are inspected, and as java-reference comparison to others. Some JavaObjects are numbers. Some are not.
What's the difference between enums/ints and other values? == works for any object. In fact, enum values under the hood are instances of a class like any other.
On Sun, Apr 25, 2010 at 8:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word 4. From point (1) and the definitions of EQ and EQL, I concur with Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
I agree almost completely, but I'd like to add that:
1. if EQL is modified, then EQUAL must be modified as well because (eql x y) should always imply (equal x y) 2. if we have freedom to modify EQL and EQUAL, then I'd say that EQUAL should call Object.equals(), but I know this is controversial 3. in any case, hash functions must be modified as well to respect the behavior of EQL and EQUAL.
What do you think?
-- Alessio
Alessio Stalla alessiostalla@gmail.com writes:
On Sun, Apr 25, 2010 at 8:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word 4. From point (1) and the definitions of EQ and EQL, I concur with Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
I agree almost completely, but I'd like to add that:
- if EQL is modified, then EQUAL must be modified as well because
(eql x y) should always imply (equal x y)
EQUAL does not internally call EQL? If that's indeed not the case, perhaps it should be made so?
- if we have freedom to modify EQL and EQUAL, then I'd say that EQUAL
should call Object.equals(), but I know this is controversial
No that would be false reasoning IMHO. The only reason why it's acceptable to extend EQL that way is because the Notes section in EQL kind of implies (albeit does not spell it out explicitly) certain implementational freedom in the interplay of EQ and EQL.
-T.
On Sun, Apr 25, 2010 at 9:49 PM, Tobias C. Rittweiler tcr@freebits.de wrote:
Alessio Stalla alessiostalla@gmail.com writes:
On Sun, Apr 25, 2010 at 8:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word 4. From point (1) and the definitions of EQ and EQL, I concur with Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
I agree almost completely, but I'd like to add that:
- if EQL is modified, then EQUAL must be modified as well because
(eql x y) should always imply (equal x y)
EQUAL does not internally call EQL? If that's indeed not the case, perhaps it should be made so?
Maybe it does, I was reasoning in the abstract, I meant: let's ensure that EQUAL works consistently.
- if we have freedom to modify EQL and EQUAL, then I'd say that EQUAL
should call Object.equals(), but I know this is controversial
No that would be false reasoning IMHO. The only reason why it's acceptable to extend EQL that way is because the Notes section in EQL kind of implies (albeit does not spell it out explicitly) certain implementational freedom in the interplay of EQ and EQL.
I don't read more implementational freedom in EQL than in EQUAL.
For EQL, the precise rules are:
"The value of eql is true of two objects, x and y, in the folowing (sic) cases:
1. If x and y are eq. 2. If x and y are both numbers of the same type and the same value. 3. If they are both characters that represent the same character.
Otherwise the value of eql is false."
The notes then say a more general thing, that "eql tells whether two objects are conceptually the same, whereas eq tells whether two objects are implementationally identical".
For EQUAL, instead:
"Returns true if x and y are structurally similar (isomorphic) objects" describes it in general, as EQL is described in general in its notes.
Then the precise rules are set:
"Objects are treated as follows by equal. [...] Other (Structures, hash-tables, instances, ...)
Two other objects are equal only if they are eq."
So, both are presented with a description in natural language that seems to concede leeway for an extension, but are also described by a very strict set of rules. Whether those rules permit extensions or not depends on whether non-CL objects, like Java objects, are considered "objects" as defined by the CL standard or not. Imho, there are valid rational arguments for both interpretations, but the second one (Java objects are not Lisp objects) is the most practical in my opinion.
Alessio
On Sun, Apr 25, 2010 at 4:05 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Sun, Apr 25, 2010 at 9:49 PM, Tobias C. Rittweiler tcr@freebits.de wrote:
Alessio Stalla alessiostalla@gmail.com writes:
On Sun, Apr 25, 2010 at 8:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word 4. From point (1) and the definitions of EQ and EQL, I concur with Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
I agree almost completely, but I'd like to add that:
- if EQL is modified, then EQUAL must be modified as well because
(eql x y) should always imply (equal x y)
EQUAL does not internally call EQL? If that's indeed not the case, perhaps it should be made so?
Maybe it does, I was reasoning in the abstract, I meant: let's ensure that EQUAL works consistently.
- if we have freedom to modify EQL and EQUAL, then I'd say that EQUAL
should call Object.equals(), but I know this is controversial
No that would be false reasoning IMHO. The only reason why it's acceptable to extend EQL that way is because the Notes section in EQL kind of implies (albeit does not spell it out explicitly) certain implementational freedom in the interplay of EQ and EQL.
I don't read more implementational freedom in EQL than in EQUAL.
I concur, though the kinds of freedoms are spelled out. Java .equals() doesn't seem to have the same constraint that lisp equals has - namely that the comparison is structural.
My read is that == on the java side is eql on the lisp side, that equals on the java side is it's own thing, and that we would be on the right side to define lisp equal and equalp on java objects such as arraylists in such a way that the comparison is elementwise as would be done on the lisp side.
-Alan
For EQL, the precise rules are:
"The value of eql is true of two objects, x and y, in the folowing (sic) cases:
- If x and y are eq.
- If x and y are both numbers of the same type and the same value.
- If they are both characters that represent the same character.
Otherwise the value of eql is false."
The notes then say a more general thing, that "eql tells whether two objects are conceptually the same, whereas eq tells whether two objects are implementationally identical".
For EQUAL, instead:
"Returns true if x and y are structurally similar (isomorphic) objects" describes it in general, as EQL is described in general in its notes.
Then the precise rules are set:
"Objects are treated as follows by equal. [...] Other (Structures, hash-tables, instances, ...)
Two other objects are equal only if they are eq."
So, both are presented with a description in natural language that seems to concede leeway for an extension, but are also described by a very strict set of rules. Whether those rules permit extensions or not depends on whether non-CL objects, like Java objects, are considered "objects" as defined by the CL standard or not. Imho, there are valid rational arguments for both interpretations, but the second one (Java objects are not Lisp objects) is the most practical in my opinion.
Alessio
armedbear-devel mailing list armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On Sun, Apr 25, 2010 at 10:25 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Sun, Apr 25, 2010 at 4:05 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Sun, Apr 25, 2010 at 9:49 PM, Tobias C. Rittweiler tcr@freebits.de wrote:
Alessio Stalla alessiostalla@gmail.com writes:
On Sun, Apr 25, 2010 at 8:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
> I think that's past Alan's point which, from my understanding, is simply > "Java enums should be comparable by EQL." Makes perfect sense as EQL is > for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word 4. From point (1) and the definitions of EQ and EQL, I concur with Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
I agree almost completely, but I'd like to add that:
- if EQL is modified, then EQUAL must be modified as well because
(eql x y) should always imply (equal x y)
EQUAL does not internally call EQL? If that's indeed not the case, perhaps it should be made so?
Maybe it does, I was reasoning in the abstract, I meant: let's ensure that EQUAL works consistently.
- if we have freedom to modify EQL and EQUAL, then I'd say that EQUAL
should call Object.equals(), but I know this is controversial
No that would be false reasoning IMHO. The only reason why it's acceptable to extend EQL that way is because the Notes section in EQL kind of implies (albeit does not spell it out explicitly) certain implementational freedom in the interplay of EQ and EQL.
I don't read more implementational freedom in EQL than in EQUAL.
I concur, though the kinds of freedoms are spelled out. Java .equals() doesn't seem to have the same constraint that lisp equals has - namely that the comparison is structural.
My read is that == on the java side is eql on the lisp side, that equals on the java side is it's own thing, and that we would be on the right side to define lisp equal and equalp on java objects such as arraylists in such a way that the comparison is elementwise as would be done on the lisp side.
Ok, I understand your view. However, if you fear equals() is too much of a black box, and might make cl:equal work in unexpected ways, then I'd prefer always using ==. Traversing stuff in Lisp isn't wise imho, since collections are not just ArrayLists and LinkedLists, but also Sets (for which you need another algorithm than traversing it one element at a time, since sets are unordered in general), and more hairy things like PersistentCollection (Hibernate) which potentially are not easily compared elementwise. equals() exists also to provide an unified entry point for all those diverse algorithms.
Alessio
On Sun, Apr 25, 2010 at 4:50 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Sun, Apr 25, 2010 at 10:25 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Sun, Apr 25, 2010 at 4:05 PM, Alessio Stalla alessiostalla@gmail.com wrote:
On Sun, Apr 25, 2010 at 9:49 PM, Tobias C. Rittweiler tcr@freebits.de wrote:
Alessio Stalla alessiostalla@gmail.com writes:
On Sun, Apr 25, 2010 at 8:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote: > > On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote: >
My read is that == on the java side is eql on the lisp side, that equals on the java side is it's own thing, and that we would be on the right side to define lisp equal and equalp on java objects such as arraylists in such a way that the comparison is elementwise as would be done on the lisp side.
Ok, I understand your view. However, if you fear equals() is too much of a black box, and might make cl:equal work in unexpected ways, then I'd prefer always using ==. Traversing stuff in Lisp isn't wise imho, since collections are not just ArrayLists and LinkedLists, but also Sets (for which you need another algorithm than traversing it one element at a time, since sets are unordered in general), and more hairy things like PersistentCollection (Hibernate) which potentially are not easily compared elementwise. equals() exists also to provide an unified entry point for all those diverse algorithms.
Again, I'm not too bent one way or another about equals. I agree in general that it is complicated and my tendency would be to try to make only those data structures on the java side that have cognates on the lisp side respond to equals in the same way as their cognates.
-Alan
Alessio
Alessio Stalla alessiostalla@gmail.com writes:
No that would be false reasoning IMHO. The only reason why it's acceptable to extend EQL that way is because the Notes section in EQL kind of implies (albeit does not spell it out explicitly) certain implementational freedom in the interplay of EQ and EQL.
I don't read more implementational freedom in EQL than in EQUAL.
For EQL, the precise rules are:
"The value of eql is true of two objects, x and y, in the folowing (sic) cases:
- If x and y are eq.
- If x and y are both numbers of the same type and the same value.
- If they are both characters that represent the same character.
Otherwise the value of eql is false."
The notes then say a more general thing, that "eql tells whether two objects are conceptually the same, whereas eq tells whether two objects are implementationally identical".
For EQUAL, instead:
"Returns true if x and y are structurally similar (isomorphic) objects" describes it in general, as EQL is described in general in its notes.
The notes section of EQL is not interesting because of the "conceptually the same" -- that's too vague and could mean anything anway; the crux is the implied distinction between EQL and EQ, and telling them apart by stating that EQ is inherently implementation-dependent whereas EQL is supposed to smooth over implementational quirks.
-T.
Hi Tobias,
- if EQL is modified, then EQUAL must be modified as well because
(eql x y) should always imply (equal x y)
EQUAL does not internally call EQL? If that's indeed not the case, perhaps it should be made so?
- if we have freedom to modify EQL and EQUAL, then I'd say that EQUAL
should call Object.equals(), but I know this is controversial
No that would be false reasoning IMHO. The only reason why it's acceptable to extend EQL that way is because the Notes section in EQL kind of implies (albeit does not spell it out explicitly) certain implementational freedom in the interplay of EQ and EQL.
That's an additional - and compelling - argument, if you ask me.
Let's go for it.
Bye,
Erik.
Erik Huelsmann ehuels@gmail.com writes:
Hi all,
On Sun, Apr 25, 2010 at 7:26 PM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
On Apr 25, 2010, at 6:55 AM, Tobias C. Rittweiler wrote:
I think that's past Alan's point which, from my understanding, is simply "Java enums should be comparable by EQL." Makes perfect sense as EQL is for object identity.
Yes, and Java "objects" too.
I've read this thread, the thread on c.l.l regarding EQUAL and the definitions of EQ and EQL. The following is my interpretation of it all:
- Our Java side JavaObject class is merely a box for a Java instance
value (a pointer to a Java object, if you will) 2. The definitions of EQ and EQL talk about Objects, but I interpret them to refer to the first meaning in [1], not to instances of lisp classes 3. Our JavaObjects have not been defined in the (Common) Lisp spec; they don't adhere to the object-instantiation protocol nor are they any of any one of the predefined built-in classes and therefore can't be taken to be "Lisp Objects" in that sense of the word
These JavaObjects are not a subtype of T?
- From point (1) and the definitions of EQ and EQL, I concur with
Alan that "raison d'etre" of EQL should equally apply to JavaObjects 5. From ponits (2) and (3) and the discussion on #lisp and c.l.l, I conclude that we're basically free to extend the meaning of EQL here: the JavaObject values were not in the spec to begin with: they're not Lisp class instances, they're not symbols, numbers nor characters
The only objection there is from both #lisp and c.l.l is that EQ, EQL and EQUAL shouldn't start to behave unpredictably regarding defined behaviour. For all the spec cares, we would have generated an error when EQ-comparing 2 java objects...
Agreed?
As also written in the reply to Alessio, I'd argue from the point that the Notes section for EQL pretty much implies implementational freedom regarding the behaviour of EQ and EQL.
ABCL extends that notion by adding these Java instance pointers to the mix of numbers and characters.
-T.
On Apr 25, 2010, at 5:51 AM, Alessio Stalla wrote:
On Sun, Apr 25, 2010 at 10:17 AM, Alan Ruttenberg alanruttenberg@gmail.com wrote:
(eql (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle") (jfield-raw "org.armedbear.lisp.Stream" "platformEolStyle")) -> NIL I think it should be eql, probably eq. I know they are equal.
The documentation for eq says: Returns true if its arguments are the same, identical object; otherwise, returns false.
They are and they are not. That they are not is only a quirk of the implementation.
Well, eq is supposed to work following "quirks of the implementation", for example, eql fixnums are not required to be eq and indeed they are not on abcl due to boxing.
By my understanding this was a known quirk, and so give insight into why eql was created. BTW, to be clear, "quirk" was a friendly, not a fighting work :)
So two boxed java objects are not eq.
Willing to accept that, as long as they are eql. After all, they are the "same, identical object" in the java sense, and we are trying to integrate with java.
eql adds equality for characters and numbers
right, and equal should provide equality for compound objects, descending their structure. But the standard explicitly says that equal behaves like eq for all objects excepts for those types mentioned in the definition of equal.
I'm not interested in equal, really, just noted that as in reading the code I see that JavaObject.equal() is defined. My sense is that this is misplaced and that JavaObject.eql() should be instead defined, to be true when two things are the "same, identical object" on the java side.
I think this because eql isolates us from implementation details which numbers are boxed and which not, and because it certainly could be the case that in a future abcl java objects are not boxed, and so eql would isolate us from this choice as well.
I encountered this problem too in the past and I tried to understand it better by carefully reading the Hyperspec and by asking people on comp.lang.lisp about it. It seems that there's not a uniform opinion in the Lisp community: some say that the standard prohibits implementations from giving EQUAL a new meaning for "non-CL" objects. Others say that implementation can and sometimes should change CL functions giving them new meanings for implementation-specific objects. Others still say that implementations can extend EQUAL, but should not do it to avoid surprising the users. I personally think that position #2 is the most sensible in this case, but it's hard to get it right, because some people think #2 and #3 break CL conformance.
Again, equal is not my concern. It's eql.
If you're interested, the discussion on c.l.l. is here: http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/c2f56ab69c93...
Thanks, I'll have a look later.
-Alan
armedbear-devel@common-lisp.net