digitalmars.D - Object.opCmp - about time we came to a decision
- Stewart Gordon (50/50) Apr 14 2005 It's about time we finally made up our mind what we're going to do with
- Matthew (3/38) Apr 14 2005 It's got to go.
- pragma (13/14) Apr 14 2005 This solution gets my vote. IMO, there is nothing odd about requiring t...
- Kris (13/23) Apr 14 2005 Java also
- pragma (20/45) Apr 14 2005 ::cringe:: I forgot about this.
- Ivan Senji (6/31) Apr 15 2005 sortable).
- Uwe Salomon (6/11) Apr 14 2005 ?? I thought the question was about Object.opCmp() to get rid of, not of...
-
Stewart Gordon
(12/17)
Apr 15 2005
- xs0 (24/41) Apr 15 2005 Actually, Java 1.5 doesn't have templates, but generics.. The Comparable...
- Stewart Gordon (11/21) Apr 15 2005 Why not
- xs0 (9/34) Apr 15 2005 I don't know, really. Could be as well, considering that the default
- Stewart Gordon (14/21) Apr 18 2005 The whole point of exception messages is to be addressed to the user.
- xs0 (8/32) Apr 18 2005 If the user ever sees a message from opCmp(), the app is totally not
- xs0 (42/70) Apr 15 2005 BTW, after some thinking, opEquals should do the same; you don't know
- Stewart Gordon (9/26) Apr 18 2005 To me, not defining an opEquals is basically stating that two object
- xs0 (17/44) Apr 18 2005 To me, not defining an opEquals is basically stating you won't compare
-
Stewart Gordon
(9/13)
Apr 18 2005
- xs0 (12/26) Apr 18 2005 Well, I'm sure that argument can be used for any given implementation of...
- TechnoZeus (6/56) Apr 14 2005 I vote for fixing it, as I have already outlined.
- Matthew (19/19) Apr 14 2005 Current definition:
- Kris (17/36) Apr 14 2005 Aye.
- Matthew (15/63) Apr 14 2005 Well, aren't you keen to open up all Pandora's boxes in one go!
- kris (4/83) Apr 14 2005 Just looking for trouble :-)
- Matthew (4/87) Apr 14 2005 The only solution then would be to eschew the built-in containers.
- Stewart Gordon (20/35) Apr 15 2005 Why not
- TechnoZeus (5/40) Apr 15 2005 Yes, I have also been thinking about that delema. An ordered comparison...
- Walter (13/14) Apr 15 2005 opCmp operator, but that would probably require the results of opCmp to ...
-
Stewart Gordon
(12/15)
Apr 18 2005
- TechnoZeus (5/20) Apr 20 2005 Technically, I can't think of any possible type that would be "unorderab...
- Kris (34/69) Apr 15 2005 The rest of the class was asleep :-)
- Sean Kelly (14/34) Apr 15 2005 Good question. In my experience, I've never created a class that has on...
- Stewart Gordon (20/35) Apr 18 2005 Yes, so that:
- TechnoZeus (5/24) Apr 15 2005 Well, as long as having other methods doesn't reduce performance, I thin...
- Ben Hinkle (25/27) Apr 15 2005 I'm not sure how many people know this but you can compare dynamic array...
- TechnoZeus (3/30) Apr 20 2005 Actually, the natural extension of your pointing out that you are not su...
- Ben Hinkle (7/8) Apr 15 2005 I would add 2a: leave it in, document it and add a warning to dmd and dl...
- Matthew (6/16) Apr 15 2005 But what's the attraction with addressing the symptoms of a disease,
- pragma (3/20) Apr 15 2005 It requires zero compiler changes.
- Matthew (5/32) Apr 15 2005 Sure. But is that a good reason, in a pre-1.0 language that aims to
- TechnoZeus (3/36) Apr 20 2005 What you are calling a disease, in this case, I think of as a useful and...
- xs0 (4/27) Apr 15 2005 You can sort an Object[] without caring what the actual types are? (of
- Sean Kelly (4/9) Apr 15 2005 But is this an advantage? I've personally never found a reason to compa...
- TechnoZeus (4/14) Apr 20 2005 Yes, there are huge advantages to it in specific cases where that is wha...
- Matthew (9/35) Apr 15 2005 But sorting heterogeneous types is only meaningful in a subset of
- xs0 (14/52) Apr 15 2005 Who said anything about heteregeneous types? Object[] means whatever,
- Ben Hinkle (9/12) Apr 15 2005 hmm. It is pretty scary if we are allowed to do
- xs0 (5/19) Apr 15 2005 Well, what does this have to do with opCmp? :)
- Ben Hinkle (7/25) Apr 15 2005 I saw the statement that Foo[] is implicitly castable to Object[] and I ...
- xs0 (12/45) Apr 15 2005 Yes way:
- TechnoZeus (5/17) Apr 20 2005 Don't be scared so easily. :)
- Ben Hinkle (16/45) Apr 20 2005 Here's another example that might be more common:
- xs0 (15/27) Apr 20 2005 But here, you're calling basically fillSomeElementsWithFoos(Bar[]). You
- Ben Hinkle (15/42) Apr 20 2005 A core principle of upcasting is substitutability. If Bar is derived fro...
- xs0 (41/46) Apr 20 2005 See, it's not that simple. To have more type safety, you'd require more
- Ben Hinkle (11/21) Apr 20 2005 I'm suggesting the user be more explicit about when they are risking typ...
- xs0 (19/41) Apr 20 2005 I agree, but I don't think forcing them to explicitly cast is the best
- Georg Wrede (8/46) Apr 20 2005 Anybody writing that piece of code is asking for First Blood. Out of his...
- xs0 (5/18) Apr 20 2005 Why exactly? The point was that
- Georg Wrede (3/30) Apr 20 2005 If the code handles "any Object", then why be surprised if the compiler
- xs0 (3/27) Apr 21 2005 I don't get what you're trying to say, sorry..
- Georg Wrede (7/21) Apr 21 2005 The code and the explanation looked as if having a reference to an
- Ben Hinkle (8/24) Apr 15 2005 I'd like to see a more complete description of what would change before
- Sean Kelly (8/14) Apr 15 2005 Moving the methods to interfaces *almost* works, and the changes really ...
- Ben Hinkle (10/31) Apr 15 2005 The interface would presumably be Comparable.opCmp(Comparable), correct?...
- Matthew (15/50) Apr 15 2005 I think there are two (or more) proposals here. My idea doesn't
- Ben Hinkle (14/33) Apr 15 2005 Yeah - the C++-style of using compile-time generics instead of run-time
- Matthew (6/31) Apr 15 2005 Excellent point. I'd suggest that we downgrade any enthusiasm for
- J C Calvarese (12/19) Apr 17 2005 If you go to http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D,
- Ben Hinkle (6/22) Apr 17 2005 I meant all I know how to do is this:
- J C Calvarese (17/48) Apr 17 2005 Oops, I misunderstood. I don't think I've seen anyone do that (maybe it
- Georg Wrede (3/57) Apr 18 2005 Man, we should collect money to give him a Linux box. ;-)
- Ben Hinkle (11/31) Apr 18 2005 I agree - I don't think it is possible either, but I figured I'd ask sin...
- Georg Wrede (4/14) Apr 18 2005 I meant get a Linux box for Walter, so he didn't have to _remember_ to
- J C Calvarese (6/26) Apr 18 2005 I don't expect Walter to update the archives every day, but once a month...
- Walter (3/5) Apr 30 2005 Jan and I have been talking about automating it a bit.
- Regan Heath (13/31) Apr 18 2005 I just grab the first part of the url i.e.
- xs0 (13/28) Apr 15 2005 I went and checked (btw, it would've been nice to mention that the
- Kris (23/50) Apr 15 2005 Aye.
- Ben Hinkle (19/45) Apr 15 2005 Personally I have no problem with a default behavior if it has enough
- Matthew (7/38) Apr 15 2005 Not at all. It's a great idea. I myself have only a semi-rigorous
- Kris (14/54) Apr 15 2005 ? Yer arse!
- Matthew (19/92) Apr 15 2005 Before we get into this, and potentially waste many more hours on
- Georg Wrede (4/15) Apr 17 2005 You'd better ask Walter off-line.
It's about time we finally made up our mind what we're going to do with Object.opCmp. Three possible solutions I can see: 1. Get rid of it, and either reimplement AAs and sort using templates, or implement the alternative solution described in point 3 here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/10558 Just thinking about it, is this solution really implementable, considering the possibility of inheriting multiple opCmp methods (from a class and an interface or from multiple interfaces)? 2. Leave the current DMD behaviour in, and document it properly. Something to the effect of this: ---------- arrays.html - Associative arrays For associative arrays to work on a class KeyType, the class must override the following member functions of Object: int opEquals(Object) int opCmp(Object) uint toHash() Note that the first two must have the parameter of type Object, not of the specific class in which they are defined. arrays.html - Array properties For sorting to work on a class type, the class must override the int opCmp(Object) member of class Object. Note that the parameter type is Object, not the specific class in which it is defined. operatoroverloading.html - Overloading == and != The equality operator of a class must be defined by overriding Object.opEquals(Object) (not by merely creating a new opEquals of a more specific parameter type), otherwise associative arrays will not work correctly. operatoroverloading.html - Overloading <, <=, > and >= - Rationale The existence of Object.opCmp(Object) is due to a constraint of the way associative arrays and sorting are implemented. As such, the comparator must be defined by overriding this method (not by merely creating a new opCmp of a more specific parameter type), otherwise associative arrays and sorting will not work correctly. ---------- 3. Keep Object.opCmp, but redefine it to always return zero. So effectively all objects of a class rank equally unless they override opCmp to specify otherwise. Consequently a principle of OO is effectively maintained - in a derived class, one can choose to add a natural ordering, rather than being expected to subtract the meaningless (and contrary to GC guidelines) natural ordering from Object. And AAs will at least work on classes of which the designer has defined opEquals and toHash but not opCmp. Indeed, something will need to be done to the documentation whichever route we take. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 14 2005
It's got to go. Score an emphatic 1 for option 1. "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:d3m7do$1bdk$1 digitaldaemon.com...It's about time we finally made up our mind what we're going to do with Object.opCmp. Three possible solutions I can see: 1. Get rid of it, and either reimplement AAs and sort using templates, or implement the alternative solution described in point 3 here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/10558 Just thinking about it, is this solution really implementable, considering the possibility of inheriting multiple opCmp methods (from a class and an interface or from multiple interfaces)? 2. Leave the current DMD behaviour in, and document it properly. Something to the effect of this: ---------- arrays.html - Associative arrays For associative arrays to work on a class KeyType, the class must override the following member functions of Object: int opEquals(Object) int opCmp(Object) uint toHash() Note that the first two must have the parameter of type Object, not of the specific class in which they are defined. arrays.html - Array properties For sorting to work on a class type, the class must override the int opCmp(Object) member of class Object. Note that the parameter type is Object, not the specific class in which it is defined. operatoroverloading.html - Overloading == and != The equality operator of a class must be defined by overriding Object.opEquals(Object) (not by merely creating a new opEquals of a more specific parameter type), otherwise associative arrays will not work correctly. operatoroverloading.html - Overloading <, <=, > and >= - Rationale The existence of Object.opCmp(Object) is due to a constraint of the way associative arrays and sorting are implemented. As such, the comparator must be defined by overriding this method (not by merely creating a new opCmp of a more specific parameter type), otherwise associative arrays and sorting will not work correctly. ---------- 3. Keep Object.opCmp, but redefine it to always return zero. So effectively all objects of a class rank equally unless they override opCmp to specify otherwise. Consequently a principle of OO is effectively maintained - in a derived class, one can choose to add a natural ordering, rather than being expected to subtract the meaningless (and contrary to GC guidelines) natural ordering from Object. And AAs will at least work on classes of which the designer has defined opEquals and toHash but not opCmp. Indeed, something will need to be done to the documentation whichever route we take. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 14 2005
In article <d3m7do$1bdk$1 digitaldaemon.com>, Stewart Gordon says...2. Leave the current DMD behaviour in, and document it properly.This solution gets my vote. IMO, there is nothing odd about requiring the implementor provide comparison and equality operators when they really want their class to behave like a value type in the first place (ie. sortable). IComparable interface, which requires the "compareTo(Object)" method. Java also has the Comparable interface which happens to be identical. So I think we're on the right track by keeping things as-is. Can I request that the behavior for sorting with the default operators be included as well? I think that's another potential source for confusion if left alone. $0.02 - EricAnderton at yahoo
Apr 14 2005
"pragma" <pragma_member pathlink.com> wrote ...In article <d3m7do$1bdk$1 digitaldaemon.com>, Stewart Gordon says...want2. Leave the current DMD behaviour in, and document it properly.This solution gets my vote. IMO, there is nothing odd about requiring the implementor provide comparison and equality operators when they reallytheir class to behave like a value type in the first place (ie. sortable). IComparable interface, which requires the "compareTo(Object)" method.Java alsohas the Comparable interface which happens to be identical. So I thinkwe're onthe right track by keeping things as-is.Don't get you, Eric. Are you saying keep the broken opCmp() and opEquals() in Object, and just assume the user will do the right thing by overriding them in their own class? If so, I have to disagree strongly. Such things should be trapped as compile-time errors, not runtime oblique-behaviour. IMO, they should get ripped out of Object, and then be supported via an Interface or similar. Note that these Object methods were in place long before Interfaces were even available. That might explain a lot :-) I believe toHash() is in the same boat? - Kris
Apr 14 2005
In article <d3mp8g$1t7a$1 digitaldaemon.com>, Kris says..."pragma" <pragma_member pathlink.com> wrote ...I had a huge reply written up, and then I noticed this line from the OP:In article <d3m7do$1bdk$1 digitaldaemon.com>, Stewart Gordon says...want2. Leave the current DMD behaviour in, and document it properly.This solution gets my vote. IMO, there is nothing odd about requiring the implementor provide comparison and equality operators when they reallytheir class to behave like a value type in the first place (ie. sortable). IComparable interface, which requires the "compareTo(Object)" method.Java alsohas the Comparable interface which happens to be identical. So I thinkwe're onthe right track by keeping things as-is.Don't get you, Eric. Are you saying keep the broken opCmp() and opEquals() in Object, and just assume the user will do the right thing by overriding them in their own class? If so, I have to disagree strongly. Such things should be trapped as compile-time errors, not runtime oblique-behaviour. IMO, they should get ripped out of Object, and then be supported via an Interface or similar. Note that these Object methods were in place long before Interfaces were even available. That might explain a lot :-) I believe toHash() is in the same boat?Note that the first two must have the parameter of type Object, not of the specific class in which they are defined.::cringe:: I forgot about this. Far be it from me to back an opinion, and continue to ride it when it starts to fall apart. So allow me to divorce my ego from my previous post. I need to give this a *lot* more thought. I thought I understood the entire problem, but upon rereading the thread and related material I'm left with more questions than answers. It's also eaten several hours of my time. :( The short, short answer is that I like the current implementation largely becuase it hasn't given me much trouble and seems to fit most of the use-cases out there. After all, if it isn't broken, don't fix it, right? But I also understand that this is pretty much head-in-the-sand thinking so I'm not 100% on this one. The biggest quandry I have is: how much of a problem is using the wrong override for opCmp and opEquals? Is this really an education problem, or a design problem? I honestly don't know. :( I'll get back to you with a more concrete opinion. Thank you for prodding me to think about this Kris. - EricAnderton at yahoo
Apr 14 2005
"Kris" <fu bar.com> wrote in message news:d3mp8g$1t7a$1 digitaldaemon.com..."pragma" <pragma_member pathlink.com> wrote ...theIn article <d3m7do$1bdk$1 digitaldaemon.com>, Stewart Gordon says...2. Leave the current DMD behaviour in, and document it properly.This solution gets my vote. IMO, there is nothing odd about requiringsortable).implementor provide comparison and equality operators when they reallywanttheir class to behave like a value type in the first place (ie.Well i agree with you 100%. I always thought we should get rid of them and make them compile-time errors. I really hope people/Walter listen to you!IComparable interface, which requires the "compareTo(Object)" method.Java alsohas the Comparable interface which happens to be identical. So I thinkwe're onthe right track by keeping things as-is.Don't get you, Eric. Are you saying keep the broken opCmp() and opEquals() in Object, and just assume the user will do the right thing by overriding them in their own class? If so, I have to disagree strongly. Such things should be trapped as compile-time errors, not runtime oblique-behaviour. IMO, they should get ripped out of Object, and then be supported via an Interface or similar. Note that these Object methods were in place long before Interfaces were even available. That might explain a lot :-)I believe toHash() is in the same boat? - Kris
Apr 15 2005
?? I thought the question was about Object.opCmp() to get rid of, not of opCmp() itself? Implementing an opCmp() for your own class is still Ciao uwe2. Leave the current DMD behaviour in, and document it properly.This solution gets my vote. IMO, there is nothing odd about requiring the implementor provide comparison and equality operators when they really want their class to behave like a value type in the first place (ie. sortable).
Apr 14 2005
pragma wrote: <snip>the IComparable interface, which requires the "compareTo(Object)" method. Java also has the Comparable interface which happens to be identical.<snip> Actually, Java 1.5 (aka Java™ 2 Platform Standard Edition 5.0 for some reason I can't imagine) has Comparable as a template, such that compareTo [sic] is defined only on the scope of the comparability.So I think we're on the right track by keeping things as-is.Why do some people seem to think copying others just for the sake of it is the way to go? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 15 2005
Stewart Gordon wrote:pragma wrote: <snip>Actually, Java 1.5 doesn't have templates, but generics.. The Comparable interface is always the same, you can just specify some class when you type, so you don't have to cast as much (just in the source code, that is, after it gets compiled, I believe the result is the same no matter what you type). Basically, Comparable<T> always compiles as Comparable<Object>...the IComparable interface, which requires the "compareTo(Object)" method. Java also has the Comparable interface which happens to be identical.<snip> Actually, Java 1.5 (aka Java™ 2 Platform Standard Edition 5.0 for some reason I can't imagine) has Comparable as a template, such that compareTo [sic] is defined only on the scope of the comparability.Wouldn't know :) I'd leave things as is, but redefine int opCmp(Object o) { if (this is o) return 0; throw new SomeException("You need to define opCmp(Object) for " ~ o.classinfo.name); } uint opHash(Object o) { return 0; } After/if/when introspection is added, these two can easily use it to do something more meaningful (for example, find all opCmp functions and choose one based on types, and hash and xor all the fields, respectively) xs0So I think we're on the right track by keeping things as-is.Why do some people seem to think copying others just for the sake of it is the way to go?
Apr 15 2005
xs0 wrote: <snip>I'd leave things as is, but redefine int opCmp(Object o) { if (this is o)Why not if (this == o) so that if one has defined opEquals, it'll get the message?return 0; throw new SomeException("You need to define opCmp(Object) for " ~ o.classinfo.name); }<snip> Why should applications tell their users to define opCmp(Object)? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 15 2005
Stewart Gordon wrote:xs0 wrote: <snip>I don't know, really. Could be as well, considering that the default opEquals is the same thing anyway. OTOH, it's not that important. Who will compare only equal objects anyway?I'd leave things as is, but redefine int opCmp(Object o) { if (this is o)Why not if (this == o) so that if one has defined opEquals, it'll get the message?Well, what I said and "comparison not defined for type Blah" are about equally useful to the users (not at all), yet my message is useful at least to coders? And if you just say it's not defined, everybody will come filing bugs about how their opCmp(Blah) actually is defined :) xs0return 0; throw new SomeException("You need to define opCmp(Object) for " ~ o.classinfo.name); }<snip> Why should applications tell their users to define opCmp(Object)?
Apr 15 2005
xs0 wrote:Stewart Gordon wrote:<snip>The whole point of exception messages is to be addressed to the user. Almost any exception message is bound to find its way into production code one day. And so the "You need to" notation truly is blaming the user for a fault of the programmer. On the other hand, simply saying "comparison not defined for type Blah" or similar, while equally meaningless to the user, doesn't label anyone as at fault, and arguably looks more like indication of a bug than a bogus message of action required from the user. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.Why should applications tell their users to define opCmp(Object)?Well, what I said and "comparison not defined for type Blah" are about equally useful to the users (not at all), yet my message is useful at least to coders? And if you just say it's not defined, everybody will come filing bugs about how their opCmp(Blah) actually is defined :)
Apr 18 2005
Stewart Gordon wrote:xs0 wrote:If the user ever sees a message from opCmp(), the app is totally not ready for use, I mean, it's such a basic thing. So, I was kind of assuming that the user would never see such a message, but the developer will. In any case, the point wasn't the exact wording. It can easily be personless. xs0Stewart Gordon wrote:<snip>The whole point of exception messages is to be addressed to the user. Almost any exception message is bound to find its way into production code one day. And so the "You need to" notation truly is blaming the user for a fault of the programmer. On the other hand, simply saying "comparison not defined for type Blah" or similar, while equally meaningless to the user, doesn't label anyone as at fault, and arguably looks more like indication of a bug than a bogus message of action required from the user.Why should applications tell their users to define opCmp(Object)?Well, what I said and "comparison not defined for type Blah" are about equally useful to the users (not at all), yet my message is useful at least to coders? And if you just say it's not defined, everybody will come filing bugs about how their opCmp(Blah) actually is defined :)
Apr 18 2005
BTW, after some thinking, opEquals should do the same; you don't know whether something is equal or not (unless it is identity-equal), so you can't just say it isn't. To sum up, I believe these should be the default implementations: int opCmp(Object o) { // basically doesn't work, but explains what should be done if (this==o) return 0; if (this.classinfo==o.classinfo) { throw new SomeException("You need to define opCmp(Object) for "~o.classinfo.name); } else { throw new SomeException("You need to define opCmp(Object) in " ~ this.classinfo.name ~ " that can compare with " ~ o.classinfo.name); } } int opEquals(Object o) { // basically doesn't work, but explains what should be done if (this is o) return 1; if (this.classinfo==o.classinfo) { throw new SomeException("You need to define opEquals(Object) for "~o.classinfo.name); } else { throw new SomeException("You need to define opEquals(Object) in " ~ this.classinfo.name ~ " that can test for equality with " ~ o.classinfo.name); } } uint toHash() { // basically works, but is utterly bad; still, if you compile properly // it will tell you there is a problem version(RUNTIME_LINT) { throw new PerformanceException("The default toHash() method is being used for class " ~ this.classinfo.name ~". It could not be more inefficient, so you should implement a better one."); } return 0; } xs0 Stewart Gordon wrote:xs0 wrote: <snip>I'd leave things as is, but redefine int opCmp(Object o) { if (this is o)Why not if (this == o) so that if one has defined opEquals, it'll get the message?return 0; throw new SomeException("You need to define opCmp(Object) for " ~ o.classinfo.name); }<snip> Why should applications tell their users to define opCmp(Object)? Stewart.
Apr 15 2005
xs0 wrote:BTW, after some thinking, opEquals should do the same; you don't know whether something is equal or not (unless it is identity-equal), so you can't just say it isn't.To me, not defining an opEquals is basically stating that two object references are equal only by referring to one and the same object.To sum up, I believe these should be the default implementations: int opCmp(Object o) { // basically doesn't work, but explains what should be done if (this==o) return 0; if (this.classinfo==o.classinfo) { throw new SomeException("You need to define opCmp(Object) for "~o.classinfo.name); } else { throw new SomeException("You need to define opCmp(Object) in " ~ this.classinfo.name ~ " that can compare with " ~ o.classinfo.name); } }<snip top of upside-down reply> I still don't get what practical use this idea really has. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 18 2005
Stewart Gordon wrote:xs0 wrote:To me, not defining an opEquals is basically stating you won't compare objects with ==. IMHO, if you want to compare references, you have is, and if you're writing templates that use ==, you should define opEquals anyway.BTW, after some thinking, opEquals should do the same; you don't know whether something is equal or not (unless it is identity-equal), so you can't just say it isn't.To me, not defining an opEquals is basically stating that two object references are equal only by referring to one and the same object.Well, I thought that one of the major issues with opCmp and the like is that they're defined in Object, which provides a problematic default implementation, that currently compares based on their objects addresses in memory, which is horrible. The other issue people had is that they define Foo.opCmp(Foo) and it doesn't work. I was trying to address those two issues by having Object still contain those methods (which is imho good) yet have them work in a GC-safe way, while not assuming any ordering/equalness at all, and if they do throw an exception, it might as well be something useful to the coder, which obviously thought that his code was going to be called, but it didn't. xs0To sum up, I believe these should be the default implementations: int opCmp(Object o) { // basically doesn't work, but explains what should be done if (this==o) return 0; if (this.classinfo==o.classinfo) { throw new SomeException("You need to define opCmp(Object) for "~o.classinfo.name); } else { throw new SomeException("You need to define opCmp(Object) in " ~ this.classinfo.name ~ " that can compare with " ~ o.classinfo.name); } }<snip top of upside-down reply> I still don't get what practical use this idea really has.
Apr 18 2005
xs0 wrote: <snip>To me, not defining an opEquals is basically stating you won't compare objects with ==. IMHO, if you want to compare references, you have is, and if you're writing templates that use ==, you should define opEquals anyway.<snip> And if I want to use a template from someone else's library wrote with a class from someone else's library...? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 18 2005
Stewart Gordon wrote:xs0 wrote: <snip>Well, I'm sure that argument can be used for any given implementation of opEquals.. Nothing will fit all possible requirements.. I don't know, extend the class and implement opEquals, or, if its a hierarchy, wrap the reference in a struct that has opEquals, or change the template (you can only use it in source form, so you must have source)? I guess the right way to write templates is "a is b || a==b" anyway, because it handles all cases of equality, regardless of what is defined where.. Anyway, it was just an idea, no need to argue about it - if you don't think it would be useful to you, it probably wouldn't.. xs0To me, not defining an opEquals is basically stating you won't compare objects with ==. IMHO, if you want to compare references, you have is, and if you're writing templates that use ==, you should define opEquals anyway.<snip> And if I want to use a template from someone else's library wrote with a class from someone else's library...? Stewart.
Apr 18 2005
I vote for fixing it, as I have already outlined. Post: Re: Solution - Re: How to bridge the gap between user defined types and built in types? Date: April 14th, 2005 6:08am (US Central time?) In response to the thread: How to bridge the gap between user defined types and built in types? TZ "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:d3m7do$1bdk$1 digitaldaemon.com...It's about time we finally made up our mind what we're going to do with Object.opCmp. Three possible solutions I can see: 1. Get rid of it, and either reimplement AAs and sort using templates, or implement the alternative solution described in point 3 here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/10558 Just thinking about it, is this solution really implementable, considering the possibility of inheriting multiple opCmp methods (from a class and an interface or from multiple interfaces)? 2. Leave the current DMD behaviour in, and document it properly. Something to the effect of this: ---------- arrays.html - Associative arrays For associative arrays to work on a class KeyType, the class must override the following member functions of Object: int opEquals(Object) int opCmp(Object) uint toHash() Note that the first two must have the parameter of type Object, not of the specific class in which they are defined. arrays.html - Array properties For sorting to work on a class type, the class must override the int opCmp(Object) member of class Object. Note that the parameter type is Object, not the specific class in which it is defined. operatoroverloading.html - Overloading == and != The equality operator of a class must be defined by overriding Object.opEquals(Object) (not by merely creating a new opEquals of a more specific parameter type), otherwise associative arrays will not work correctly. operatoroverloading.html - Overloading <, <=, > and >= - Rationale The existence of Object.opCmp(Object) is due to a constraint of the way associative arrays and sorting are implemented. As such, the comparator must be defined by overriding this method (not by merely creating a new opCmp of a more specific parameter type), otherwise associative arrays and sorting will not work correctly. ---------- 3. Keep Object.opCmp, but redefine it to always return zero. So effectively all objects of a class rank equally unless they override opCmp to specify otherwise. Consequently a principle of OO is effectively maintained - in a derived class, one can choose to add a natural ordering, rather than being expected to subtract the meaningless (and contrary to GC guidelines) natural ordering from Object. And AAs will at least work on classes of which the designer has defined opEquals and toHash but not opCmp. Indeed, something will need to be done to the documentation whichever route we take. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 14 2005
Current definition: class Object { void print(); char[] toString(); uint toHash(); int opCmp(Object o); int opEquals(Object o); } Only definition that makes sense to me: class Object { char[] toString(); } And that's only because toString() is a benign thing. In principle, it should be: class Object { }
Apr 14 2005
Aye. Supposing the "Three Stooges" were removed ... do you have a suggestion in terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); } interface Hashable { uint toHash(); } Or something else instead? - Kris "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3n7n3$28d4$1 digitaldaemon.com...Current definition: class Object { void print(); char[] toString(); uint toHash(); int opCmp(Object o); int opEquals(Object o); } Only definition that makes sense to me: class Object { char[] toString(); } And that's only because toString() is a benign thing. In principle, it should be: class Object { }
Apr 14 2005
Well, aren't you keen to open up all Pandora's boxes in one go! The answer depends on whether we feel that D should be a language that follows interface-based runtime polymorphism, or uses generic approaches. There's no reason why the language cannot be defined such that the compiler will only accept ar.sort() when ar is composed of homogeneous built-in types, or instances of class types that all share a comon base that has an opCmp() defined. Similarly, there's no reason why AAs could not be built only on types that have the appropriate methods. Since this approach also fully supports runtime polymorphic approaches, but does not mandate them, I think it's the best approach. (Obviously) Matthew "Kris" <fu bar.com> wrote in message news:d3nid8$2hqe$1 digitaldaemon.com...Aye. Supposing the "Three Stooges" were removed ... do you have a suggestion in terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); } interface Hashable { uint toHash(); } Or something else instead? - Kris "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3n7n3$28d4$1 digitaldaemon.com...Current definition: class Object { void print(); char[] toString(); uint toHash(); int opCmp(Object o); int opEquals(Object o); } Only definition that makes sense to me: class Object { char[] toString(); } And that's only because toString() is a benign thing. In principle, it should be: class Object { }
Apr 14 2005
Just looking for trouble :-) Supposing the compiler itself did not change ... any other solutions? - Kris Matthew wrote:Well, aren't you keen to open up all Pandora's boxes in one go! The answer depends on whether we feel that D should be a language that follows interface-based runtime polymorphism, or uses generic approaches. There's no reason why the language cannot be defined such that the compiler will only accept ar.sort() when ar is composed of homogeneous built-in types, or instances of class types that all share a comon base that has an opCmp() defined. Similarly, there's no reason why AAs could not be built only on types that have the appropriate methods. Since this approach also fully supports runtime polymorphic approaches, but does not mandate them, I think it's the best approach. (Obviously) Matthew "Kris" <fu bar.com> wrote in message news:d3nid8$2hqe$1 digitaldaemon.com...Aye. Supposing the "Three Stooges" were removed ... do you have a suggestion in terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); } interface Hashable { uint toHash(); } Or something else instead? - Kris "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3n7n3$28d4$1 digitaldaemon.com...Current definition: class Object { void print(); char[] toString(); uint toHash(); int opCmp(Object o); int opEquals(Object o); } Only definition that makes sense to me: class Object { char[] toString(); } And that's only because toString() is a benign thing. In principle, it should be: class Object { }
Apr 14 2005
"kris" <fu bar.org> wrote in message news:d3nlut$2kl4$1 digitaldaemon.com...Just looking for trouble :-) Supposing the compiler itself did not change ... any other solutions?The only solution then would be to eschew the built-in containers. (Which I pretty much do anyway, as it happens. ;/ )- Kris Matthew wrote:Well, aren't you keen to open up all Pandora's boxes in one go! The answer depends on whether we feel that D should be a language that follows interface-based runtime polymorphism, or uses generic approaches. There's no reason why the language cannot be defined such that the compiler will only accept ar.sort() when ar is composed of homogeneous built-in types, or instances of class types that all share a comon base that has an opCmp() defined. Similarly, there's no reason why AAs could not be built only on types that have the appropriate methods. Since this approach also fully supports runtime polymorphic approaches, but does not mandate them, I think it's the best approach. (Obviously) Matthew "Kris" <fu bar.com> wrote in message news:d3nid8$2hqe$1 digitaldaemon.com...Aye. Supposing the "Three Stooges" were removed ... do you have a suggestion in terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); } interface Hashable { uint toHash(); } Or something else instead? - Kris "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3n7n3$28d4$1 digitaldaemon.com...Current definition: class Object { void print(); char[] toString(); uint toHash(); int opCmp(Object o); int opEquals(Object o); } Only definition that makes sense to me: class Object { char[] toString(); } And that's only because toString() is a benign thing. In principle, it should be: class Object { }
Apr 14 2005
Kris wrote:Aye. Supposing the "Three Stooges" were removed ... do you have a suggestion in terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); }Why not int opEquals (Comparable o); int opCmp (Comparable o); Moreover: - The presence of a concept of equality certainly doesn't correlate directly with the presence of a natural ordering, so let's not pretend it does. - There's been just as much of a debate over whether Object should have opEquals. My thought is that the default implementation (a given object is equal only to itself) makes sense, and (in theory) makes it possible to use such a class as an AA key. But this doesn't by itself equate to a cause for either keeping or removing Object.opEquals - the 'equal only to itself' behaviour would still be the default if it's removed.interface Hashable { uint toHash(); }<snip top of upside-down reply> Would primitive types implement this interface as well? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 15 2005
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:d3o2an$4e$1 digitaldaemon.com...Kris wrote:Yes, I have also been thinking about that delema. An ordered comparison implies an underlying order. Well, technically speaking, there always is one somewhere in the computer, even if it is meaningless to the intended representation of data, but it should be possible flag a specific kind of item as ordered or unordered, and have that property be inhereted by default. Technically, there should also be a way to indicate "unequal" through the opCmp operator, but that would probably require the results of opCmp to be an enumeration of something like "less", "equal", "greater", "unordered" so that's probably why the opEquals function has independant functionality by default. TZ TZAye. Supposing the "Three Stooges" were removed ... do you have a suggestion in terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); }Why not int opEquals (Comparable o); int opCmp (Comparable o); Moreover: - The presence of a concept of equality certainly doesn't correlate directly with the presence of a natural ordering, so let's not pretend it does. - There's been just as much of a debate over whether Object should have opEquals. My thought is that the default implementation (a given object is equal only to itself) makes sense, and (in theory) makes it possible to use such a class as an AA key. But this doesn't by itself equate to a cause for either keeping or removing Object.opEquals - the 'equal only to itself' behaviour would still be the default if it's removed.interface Hashable { uint toHash(); }<snip top of upside-down reply> Would primitive types implement this interface as well? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 15 2005
"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d3oakv$8qc$1 digitaldaemon.com...Technically, there should also be a way to indicate "unequal" through theopCmp operator, but that would probably require the results of opCmp to be an enumeration of something like "less", "equal", "greater", "unordered" so that's probably why the opEquals function has independant functionality by default. You're right. At the moment, it is not practical to create a class that wraps a float because the comparisons won't be able to handle unordered values. I've been thinking about adding an "opCmpX" or something like that that returns 4 states. If it wasn't defined for a class, it would fall back to opCmp. The reason opEquals is a separate implementation is because some types can be equal or not equal, but have no concept of ordering.
Apr 15 2005
Walter wrote: <snip>You're right. At the moment, it is not practical to create a class that wraps a float because the comparisons won't be able to handle unordered values.<snip> Moreover, unordered values can't be used in binary search trees and the like (one thing Java uses orderings for). But maybe it's possible to support partially ordered types in such a way that they'll be distinguishable from totally ordered types. And maybe even implement a topological sort on partial orderings. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 18 2005
Technically, I can't think of any possible type that would be "unorderable" although it is sometimes good to distinguish between an ordering that is implicit in the nature of the intended representation, and an ordering that is derived from the internal representation used to store the data rather than the nature of what that data was meant to represent. In other words, the concepts of ">" and "<" could be used to predictably sort items for the sake of being able to have them at least temporarily in a predictable order even if that order is unrelated to the nature of the items being sorted. For example, if an enum type assigns an integer value internally to each of it's "unordered" values, then an ordered comparison will have predictable results at least within a limited context and scope. For example, true>false may not give the same results for different implementations, but would give the same results each time it occurrs within a given implementation as long as the internal values of "true" and "fales" are not altered. My point is, there are many grey areas in the concept of ordered or unordered, and some of them may be useful to have access to by allowing the underlying "bit patterns" to be accessed, set, compared, etc., independant of the nature of the data that those bit patterns are intended to represent. One good example of this is the idea of using the bit patterns of reference types in default comparison and assignment operations. TZ "Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:d400kv$m57$1 digitaldaemon.com...Walter wrote: <snip>You're right. At the moment, it is not practical to create a class that wraps a float because the comparisons won't be able to handle unordered values.<snip> Moreover, unordered values can't be used in binary search trees and the like (one thing Java uses orderings for). But maybe it's possible to support partially ordered types in such a way that they'll be distinguishable from totally ordered types. And maybe even implement a topological sort on partial orderings. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 20 2005
"Stewart Gordon" <smjg_1998 yahoo.com> wrote inKris wrote:inAye. Supposing the "Three Stooges" were removed ... do you have a suggestionThe rest of the class was asleep :-)terms of implementation? Are you thinking in terms of Interfaces? For example: interface Comparable { int opEquals (Object o); int opCmp (Object o); }Why not int opEquals (Comparable o); int opCmp (Comparable o);Moreover: - The presence of a concept of equality certainly doesn't correlate directly with the presence of a natural ordering, so let's not pretend it does.Very true. But if one of them exists for any given class, that object is now exhibiting comparison-traits of the 'deep' variety. If this is done for one, then does it not follow it should be done for the other? In other words, is the Comparable really an indirect indicator of 'deep' comparison? And, does this lead to a suggestion for one method rather than two of them? Is it really /so/ beneficial to have two seperate methods for comparison purposes? I'm just trying to provoke some thought here; not make assertions.- There's been just as much of a debate over whether Object should have opEquals. My thought is that the default implementation (a given object is equal only to itself) makes sense, and (in theory) makes it possible to use such a class as an AA key. But this doesn't by itself equate to a cause for either keeping or removing Object.opEquals - the 'equal only to itself' behaviour would still be the default if it's removed.You must have missed the thread on 'is' vs '==' :-) Defaulting opEqual() to identity conflicts with its role, and opens the door to both misinterpretation and buggy code. Naturally, there's potential for compromise all over the place. But if opEqual() remains in Object, then it should likely have an assert(0), since the developer should actually be using 'is' instead of '=='. But this is bogus too, since the error should be thrown at compile-time rather than runtime. Thus, opEqual() really should come out the root object, such that appropriate compile-time errors are thrown.This is part and parcel of the problem with mixing primitives and aggregates into a soup. I won't pretend to have an answer for it, but retaining toHash() within the root object causes technical issues for a compacting GC, and exhibits similar "shallow vs deep" traits as both opCmp() & opEqual(). That is, if an object has something internal considered worthy of use for comparison purposes, then it is rather likely to also have something worthy of hashing (quite possibly the same attribute(s)). Yes? One can understand why Object has these methods right now ~ it represents the easy way out. It's a shame that it's not also the robust way. I'm no OO bigot, but we're talking about the root object here ~ which, at some level, affects every single class written in D. Applying the "good enough" yardstick to this arena is asking for trouble, IMO. And not just from this NG :-) This needs some solid engineering; and I'm glad you keep raising the issue, Stewart.interface Hashable { uint toHash(); }<snip top of upside-down reply> Would primitive types implement this interface as well?Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Apr 15 2005
In article <d3p3gt$12bt$1 digitaldaemon.com>, Kris says..."Stewart Gordon" <smjg_1998 yahoo.com> wrote inGood question. In my experience, I've never created a class that has one method and not the other, but I wouldn't say that's indicative of a rule. Here's a bad example... say I have a collection of objects that represet classifications. I might want to know if two objects represent the same classification, but ordering a set of such objects might not make a lot of sense. Always preferring compile-time to run-time error checking, it would be nice if I could ensure that my codebase wasn't mistakenly trying to order such objects without running a zillion unit tests.Moreover: - The presence of a concept of equality certainly doesn't correlate directly with the presence of a natural ordering, so let's not pretend it does.Very true. But if one of them exists for any given class, that object is now exhibiting comparison-traits of the 'deep' variety. If this is done for one, then does it not follow it should be done for the other? In other words, is the Comparable really an indirect indicator of 'deep' comparison? And, does this lead to a suggestion for one method rather than two of them? Is it really /so/ beneficial to have two seperate methods for comparison purposes?Defaulting opEqual() to identity conflicts with its role, and opens the door to both misinterpretation and buggy code. Naturally, there's potential for compromise all over the place. But if opEqual() remains in Object, then it should likely have an assert(0), since the developer should actually be using 'is' instead of '=='. But this is bogus too, since the error should be thrown at compile-time rather than runtime. Thus, opEqual() really should come out the root object, such that appropriate compile-time errors are thrown.It's too bad that template member functions can't be virtual or you could define these methods in Object and put a static assert in them. What about making Object an abstract base class and declaring these functions but not defining them? Sean
Apr 15 2005
Sean Kelly wrote:In article <d3p3gt$12bt$1 digitaldaemon.com>, Kris says...<snip>Yes, so that: - equality comparisons can be made more efficient than ordered comparisons - unequal objects can rank equally in order (such as database records with matching sort keys). <snip>Very true. But if one of them exists for any given class, that object is now exhibiting comparison-traits of the 'deep' variety. If this is done for one, then does it not follow it should be done for the other? In other words, is the Comparable really an indirect indicator of 'deep' comparison? And, does this lead to a suggestion for one method rather than two of them? Is it really /so/ beneficial to have two seperate methods for comparison purposes?<snip> opEqual? What happened to the 's'? As I've said a few times, my understanding is that if someone didn't define opEquals, he/she/it really meant that object references of this class are equal only by being one and the same. So what should happen to AAs when no opEquals is defined? Should they default to ===/is instead of == ? Or should they, artificially and not very logically, be implicitly prevented from use as AA keys? My vote would go to the former, and this is the behaviour provided by the current default opEquals. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.Defaulting opEqual() to identity conflicts with its role, and opens the door to both misinterpretation and buggy code. Naturally, there's potential for compromise all over the place. But if opEqual() remains in Object, then it should likely have an assert(0), since the developer should actually be using 'is' instead of '=='. But this is bogus too, since the error should be thrown at compile-time rather than runtime. Thus, opEqual() really should come out the root object, such that appropriate compile-time errors are thrown.
Apr 18 2005
Well, as long as having other methods doesn't reduce performance, I think it's better to let Object have as many "useful" methods as you can give it that would make sense for "most" obects, because people can always choose to redefine them or simply not use them on objects for which they make no sense. I think though that the default behavior of opEquals should be to call opCmp and compare the results of that call with 0, but that's just my opinion. I also think that the opCmp default behavior should be to compare for identity first, and if the items being compared are one and the same then return 0 to indicate "no difference" rather than waste time comparing the contents of an item to itself... but to compare the contents of the items if they are not one and the same. TechnoZeus "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3n7n3$28d4$1 digitaldaemon.com...Current definition: class Object { void print(); char[] toString(); uint toHash(); int opCmp(Object o); int opEquals(Object o); } Only definition that makes sense to me: class Object { char[] toString(); } And that's only because toString() is a benign thing. In principle, it should be: class Object { }
Apr 15 2005
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:d3m7do$1bdk$1 digitaldaemon.com...It's about time we finally made up our mind what we're going to do with Object.opCmp.I'm not sure how many people know this but you can compare dynamic arrays. For arrays of objects it winds up calling Object.opCmp. So removing Object.opCmp would make array comparison more complex since presumably the compiler would have to check if it was legal or not. Not that I'm arguing opCmp should stay - just that any argument to remove it needs to look at all the places it is used, propose alternatives and objectively assess the pros and cons. int main() { int[] x,y; x = new int[5]; y = new int[7]; printf("shorter %d %d %d\n",x<y, x == y, x is y); y = new int[5]; printf("equal %d %d %d\n",x<y, x == y, x is y); x[3] = 10; printf("greater %d %d %d\n",x<y, x == y, x is y); return 0; } prints shorter 1 0 0 equal 0 1 0 greater 0 0 0 Substitute a class for 'int' above and it continues to work.
Apr 15 2005
Actually, the natural extension of your pointing out that you are not sure how many people are aware of that is exactly why I think it's important to have such things work "across the board" whenever possible. It makes the unknown into something versitile and predictable. In other words, we can know that something is (or at least should be) possible, without ever having tried it... or even having heard of it. TechnoZeus "Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p354$1252$1 digitaldaemon.com..."Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:d3m7do$1bdk$1 digitaldaemon.com...It's about time we finally made up our mind what we're going to do with Object.opCmp.I'm not sure how many people know this but you can compare dynamic arrays. For arrays of objects it winds up calling Object.opCmp. So removing Object.opCmp would make array comparison more complex since presumably the compiler would have to check if it was legal or not. Not that I'm arguing opCmp should stay - just that any argument to remove it needs to look at all the places it is used, propose alternatives and objectively assess the pros and cons. int main() { int[] x,y; x = new int[5]; y = new int[7]; printf("shorter %d %d %d\n",x<y, x == y, x is y); y = new int[5]; printf("equal %d %d %d\n",x<y, x == y, x is y); x[3] = 10; printf("greater %d %d %d\n",x<y, x == y, x is y); return 0; } prints shorter 1 0 0 equal 0 1 0 greater 0 0 0 Substitute a class for 'int' above and it continues to work.
Apr 20 2005
2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
In article <d3pcr2$19r3$1 digitaldaemon.com>, Matthew says..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...It requires zero compiler changes. - EricAnderton at yahooBut what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
"pragma" <pragma_member pathlink.com> wrote in message news:d3pfrv$1c70$1 digitaldaemon.com...In article <d3pcr2$19r3$1 digitaldaemon.com>, Matthew says...Sure. But is that a good reason, in a pre-1.0 language that aims to avoid making the mistakes of its predecessors? What's wrong with change at this stage?"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...It requires zero compiler changes.But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
What you are calling a disease, in this case, I think of as a useful and powerful feature. Perhaps that's why people would rather treat it than cure it. Why fix it if it's not broken? TZ "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3pn7e$1hth$1 digitaldaemon.com..."pragma" <pragma_member pathlink.com> wrote in message news:d3pfrv$1c70$1 digitaldaemon.com...In article <d3pcr2$19r3$1 digitaldaemon.com>, Matthew says...Sure. But is that a good reason, in a pre-1.0 language that aims to avoid making the mistakes of its predecessors? What's wrong with change at this stage?"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...It requires zero compiler changes.But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 20 2005
Matthew wrote:"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...You can sort an Object[] without caring what the actual types are? (of course, as long as all classes involved implement opCmp(Object)) xs0But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
In article <d3pg6t$1c8i$1 digitaldaemon.com>, xs0 says...But is this an advantage? I've personally never found a reason to compare to entirely unrelated types. Type safety is a Good Thing. SeanI'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?You can sort an Object[] without caring what the actual types are? (of course, as long as all classes involved implement opCmp(Object))
Apr 15 2005
"Sean Kelly" <sean f4.ca> wrote in message news:d3phhq$1dlj$1 digitaldaemon.com...In article <d3pg6t$1c8i$1 digitaldaemon.com>, xs0 says...Yes, there are huge advantages to it in specific cases where that is what the software designer wants to do. Never assume that your not having found something precludes it's existance. That's the beauty of generic functionality. In addition to being applicable to a wide range of known situations, it's applicable to things nobody's even thought of yet. Besides, removing it would only increase the work that the compiler would have to perform in some cases and increase the work that the programmer would have to perform in other cases. There are no cases where removing such an ability would reduce the amount of coding necessary to produce an algorithm that would perform a specific task, and removing such an ability would commonly have a negative impact on performance while rarely if ever having a positive impact. TZBut is this an advantage? I've personally never found a reason to compare to entirely unrelated types. Type safety is a Good Thing. SeanI'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?You can sort an Object[] without caring what the actual types are? (of course, as long as all classes involved implement opCmp(Object))
Apr 20 2005
"xs0" <xs0 xs0.com> wrote in message news:d3pg6t$1c8i$1 digitaldaemon.com...Matthew wrote:But sorting heterogeneous types is only meaningful in a subset of cases, and all those cases are accounted for in the alternative proposal. I meant what advantages does the current approach have over the proposed approach? Since it has non-trivial disadvantages, there has to be advantages. Otherwise the language can be said to be just a mix of arbitrary illogical decisions, surely?"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...You can sort an Object[] without caring what the actual types are? (of course, as long as all classes involved implement opCmp(Object))But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
Matthew wrote:"xs0" <xs0 xs0.com> wrote in message news:d3pg6t$1c8i$1 digitaldaemon.com...Who said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object. How exactly would this work, if Object was without opCmp: void checkRange(Object a, Object b, Object c) { if (a<=b && b<=c) return; logger.logError("Range check failed"); } Now this is not about comparing different types, it's about comparing any types. xs0Matthew wrote:But sorting heterogeneous types is only meaningful in a subset of cases, and all those cases are accounted for in the alternative proposal."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...You can sort an Object[] without caring what the actual types are? (of course, as long as all classes involved implement opCmp(Object))But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
Who said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object.hmm. It is pretty scary if we are allowed to do class Foo{int foo;} void main() { Foo[] x; x.length = 2; Object[] y = x; // implicitly cast y[0] = new Object; x[0].foo = 10; // Object is not a Foo - yikes! }
Apr 15 2005
Ben Hinkle wrote:Well, what does this have to do with opCmp? :) And you can't do that anyway, Object doesn't have a .foo property, so you'll get a compile error.. xs0Who said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object.hmm. It is pretty scary if we are allowed to do class Foo{int foo;} void main() { Foo[] x; x.length = 2; Object[] y = x; // implicitly cast y[0] = new Object; x[0].foo = 10; // Object is not a Foo - yikes! }
Apr 15 2005
"xs0" <xs0 xs0.com> wrote in message news:d3q40g$1qbt$2 digitaldaemon.com...Ben Hinkle wrote:I saw the statement that Foo[] is implicitly castable to Object[] and I said to myself "no way" and then I went to get the compiler error and was surprised that it didn't error.Well, what does this have to do with opCmp? :)Who said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object.hmm. It is pretty scary if we are allowed to do class Foo{int foo;} void main() { Foo[] x; x.length = 2; Object[] y = x; // implicitly cast y[0] = new Object; x[0].foo = 10; // Object is not a Foo - yikes! }And you can't do that anyway, Object doesn't have a .foo property, so you'll get a compile error..Notice "x" is declared as Foo[] so x[0].foo is legal. Scarily enough the example compiled and ran. It should have errored at the implicit cast. I'll probably put something on D.bugs soon...
Apr 15 2005
Ben Hinkle wrote:"xs0" <xs0 xs0.com> wrote in message news:d3q40g$1qbt$2 digitaldaemon.com...Yes way: A dynamic array T[] can be implicitly converted to one of the following: * T* * U[] where U is a base class of T. * U* where U is a base class of T. * void*Ben Hinkle wrote:I saw the statement that Foo[] is implicitly castable to Object[] and I said to myself "no way" and then I went to get the compiler error and was surprised that it didn't error.Well, what does this have to do with opCmp? :)Who said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object.hmm. It is pretty scary if we are allowed to do class Foo{int foo;} void main() { Foo[] x; x.length = 2; Object[] y = x; // implicitly cast y[0] = new Object; x[0].foo = 10; // Object is not a Foo - yikes! }Sorry, I misread x[0] as y[0]. But how is it a bug (in the language)? Foo[] is Object[] in the sense that every Foo is an Object. Later, when you insert an Object, it's not Foo[] anymore, but you then use an "implicit explicit cast" back to Foo[], which is the error in this case. xs0And you can't do that anyway, Object doesn't have a .foo property, so you'll get a compile error..Notice "x" is declared as Foo[] so x[0].foo is legal. Scarily enough the example compiled and ran. It should have errored at the implicit cast. I'll probably put something on D.bugs soon...
Apr 15 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3q2tm$1pag$1 digitaldaemon.com...Don't be scared so easily. :) Seriously though, the only problem with that is the potential that the programmer may not have meant to do an identity assignment when they typed "y=x" and therefore may not have planned for the side effects of x and y having the same identity. A situation that could be easily avoided if separate value and identity assignment operators were introduces. I don't see anything being done there that lacks the "potential to be useful" in the right situation. Sure, it could be misused, but that's true of anything that can be used at all. The only hazard I see is the potential for it to be done accidentally, and that's not likely. TZWho said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object.hmm. It is pretty scary if we are allowed to do class Foo{int foo;} void main() { Foo[] x; x.length = 2; Object[] y = x; // implicitly cast y[0] = new Object; x[0].foo = 10; // Object is not a Foo - yikes! }
Apr 20 2005
"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message news:d457b2$2oai$1 digitaldaemon.com..."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3q2tm$1pag$1 digitaldaemon.com...Here's another example that might be more common: class Foo{} class Bar:Foo{} void clamp(Foo[] x) { // cheesy function that changes x foreach(inout Foo y; x) { if (y < 0) y = new Foo(0); } } ... Bar[] y; ... fill(y); // y potentially has a Foo in it - a type violation. Implicitly casting shouldn't open up such a large hole in the type system. At least in C violating the type system requires a cast.Don't be scared so easily. :) Seriously though, the only problem with that is the potential that the programmer may not have meant to do an identity assignment when they typed "y=x" and therefore may not have planned for the side effects of x and y having the same identity. A situation that could be easily avoided if separate value and identity assignment operators were introduces. I don't see anything being done there that lacks the "potential to be useful" in the right situation. Sure, it could be misused, but that's true of anything that can be used at all. The only hazard I see is the potential for it to be done accidentally, and that's not likely.Who said anything about heteregeneous types? Object[] means whatever, including Foo[], because you can implicitly cast Foo[] to Object[]. I.e. everything is an Object.hmm. It is pretty scary if we are allowed to do class Foo{int foo;} void main() { Foo[] x; x.length = 2; Object[] y = x; // implicitly cast y[0] = new Object; x[0].foo = 10; // Object is not a Foo - yikes! }
Apr 20 2005
Here's another example that might be more common: class Foo{} class Bar:Foo{} void clamp(Foo[] x) { // cheesy function that changes x foreach(inout Foo y; x) { if (y < 0) y = new Foo(0); } } .... Bar[] y; .... fill(y); // y potentially has a Foo in it - a type violation.But here, you're calling basically fillSomeElementsWithFoos(Bar[]). You obviously can't expect the result to be Bars only.. I mean, the problem is not the implicit cast, but the type of y, when used with fill(). Even if you call fill(cast(Foo[])y), it can still contain a Foo, while its type is Bar[].. My point is that you need to know what your functions do, otherwise you'll run into problems, with implicit casting of arrays or not. If implicit casting of arrays were to be removed, it would mean that each function that works on an array works exactly on that kind of array and nothing else. The result would be just requiring a ton of casts, which solves nothing, yet could cause more problems than it solves - in the case above, you would type "fill(cast(Foo[])y)". But then, when you write fill(Bar[]) to handle Bar[] filling, it won't get called, because you cast the real type away.. xs0
Apr 20 2005
"xs0" <xs0 xs0.com> wrote in message news:d45psv$l74$1 digitaldaemon.com...A core principle of upcasting is substitutability. If Bar is derived from Foo then everything that takes a Foo can take a Bar. With arrays, though, an array of Foo cannot be substituted with an array of Bar since an array of Foo can hold an aribitrary Foo while an array of Bar cannot. Implicitly upcasting containers is a big type safety hole if the result is allowed to change the contents of the container.Here's another example that might be more common: class Foo{} class Bar:Foo{} void clamp(Foo[] x) { // cheesy function that changes x foreach(inout Foo y; x) { if (y < 0) y = new Foo(0); } } .... Bar[] y; .... fill(y); // y potentially has a Foo in it - a type violation.But here, you're calling basically fillSomeElementsWithFoos(Bar[]). You obviously can't expect the result to be Bars only.. I mean, the problem is not the implicit cast, but the type of y, when used with fill(). Even if you call fill(cast(Foo[])y), it can still contain a Foo, while its type is Bar[]..My point is that you need to know what your functions do, otherwise you'll run into problems, with implicit casting of arrays or not.Sure, but with enough care we wouldn't have any bugs at all and we'd have no need for type checking or type-safety. Imagine how hard it would be to track down something as subtle as this.If implicit casting of arrays were to be removed, it would mean that each function that works on an array works exactly on that kind of array and nothing else.True, but that's life. I believe sacrificing type-safety is too high a price to pay for the convenience of implicit array coversions. In my D coding, for instance, I haven't ever needed implicit array conversions.The result would be just requiring a ton of casts, which solves nothing, yet could cause more problems than it solves - in the case above, you would type "fill(cast(Foo[])y)". But then, when you write fill(Bar[]) to handle Bar[] filling, it won't get called, because you cast the real type away..Casting is the accepted way to blow away type safety. Let's keep it that way.
Apr 20 2005
Ben Hinkle wrote:Implicitly upcasting containers is a big type safety hole if the result is allowed to change the contents of the container.Casting is the accepted way to blow away type safety. Let's keep it that way.See, it's not that simple. To have more type safety, you'd require more casts, but they result in less type safety, so it may actually be conterproductive.. Java and C++ both allow implicit array upcasts, too, so I wouldn't say that people can't live with it? OTOH, If you look at Java's generics spec, they addressed this issue somewhat by having parameters be one of (with List as an example) List<T> - accepts exactly T List<? super T> - accepts T and T's supertypes List<? extends T> - accepts T and T's subtypes The first is read/write, the second is write-only, the third is read-only, for obvious reasons. Considering how write-only is significantly rarer than the other two, perhaps the best option with D would be to get support and a new syntax for demanding an exact type in function parameters, which is where most of the problem is. Perhaps void func(Type! a) void func(Type![] a) void func(Type!(int)! a) void func(Type!(int)![] a) Read-only functions would work as they do now, which is fine because they don't suffer from type unsafety. Read/write functions would be able to demand an exact type (which may or may not be useful outside the context of arrays, but I don't see why it shouldn't be allowed). Finally, for write-only functions, I guess the way to go would be again requiring an exact type, which'd require an explicit cast. However, this case of casting is not as problematic, because if you have like a FooSuperclass[] and cast it to Foo[] when calling a func, you're still keeping it locally as a FooSuperclass[], which it still is even after it gets filled with Foos (unlike casting a Subclass[] to Foo[], which is then no longer a Subclass[]). Finally, to solve the local issue of Foo[] a=...; Object[] b=a; b[0]=new Object; a[0].do(); I'd say that implicit casting of arrays can only be done when calling functions, where it's only really needed anyway. Locally, you can always use the other type in the first place, I guess.. Thoughts? xs0
Apr 20 2005
"xs0" <xs0 xs0.com> wrote in message news:d4632l$uke$1 digitaldaemon.com...Ben Hinkle wrote:I'm suggesting the user be more explicit about when they are risking type safety. The implicit cast is hiding some potentially very dangerous code.Implicitly upcasting containers is a big type safety hole if the result is allowed to change the contents of the container.Casting is the accepted way to blow away type safety. Let's keep it that way.See, it's not that simple. To have more type safety, you'd require more casts, but they result in less type safety, so it may actually be conterproductive..Java and C++ both allow implicit array upcasts, too, so I wouldn't say that people can't live with it?Note Java allows the implicit cast but doesn't allow the assignment that would break the type-safety. I'm not suggesting D go the Java route and store all the run-time array type information. I do suggest D make the coder more explicitly acknowledge when they are taking a risk with type safety. I agree C++ allows implicit pointer upcasting but everyone grumbles about C++ type-safety holes like that. It's one of C++'s weaknesses in following C so closely.
Apr 20 2005
Ben Hinkle wrote:I agree, but I don't think forcing them to explicitly cast is the best solution. See my previous post for what I'd suggest. Another option is simply using inout, although in that case you can't cast even if you want to (at least not very easily - you need a new var and a cast back).. btw, what I suggested is exactly the same regarding type safety as inout, the only inout's downside is that the caller's reference can be overwritten..I'm suggesting the user be more explicit about when they are risking type safety. The implicit cast is hiding some potentially very dangerous code.Implicitly upcasting containers is a big type safety hole if the result is allowed to change the contents of the container.Casting is the accepted way to blow away type safety. Let's keep it that way.See, it's not that simple. To have more type safety, you'd require more casts, but they result in less type safety, so it may actually be conterproductive..True, yet it still only happens at run-time, and it may even be unneeded: Object[] blah=someFunc(); // returns a new String[]; blah[0]=new Whatever(blah[0]); Although it's true - in D such an error will most probably not even get detected right away, which can probably cause quite a havoc, if you're lucky.. Again, I don't think forcing explicit casts will help; if a change is going to happen, it should be where the function is, not where the caller is (in other words, type safety should be enforced already when defining functions, not when calling them).Java and C++ both allow implicit array upcasts, too, so I wouldn't say that people can't live with it?Note Java allows the implicit cast but doesn't allow the assignment that would break the type-safety.I'm not suggesting D go the Java route and store all the run-time array type information. I do suggest D make the coder more explicitly acknowledge when they are taking a risk with type safety.everyone grumbles about C++ type-safety holes. It's one of C++'s weaknesses in following C so closely.Agreed on both counts. xs0
Apr 20 2005
xs0 wrote:Ben Hinkle wrote:Anybody writing that piece of code is asking for First Blood. Out of his own nose. There are limits to things. We don't want D to be jerk-proof. Probably there ought to be a law that says this kind of people should not have cutlery in the kitchen. (Why? Well, they might carve the dog or the postman, just out of ignorance: Oh, I just wanted to check if this knife is as sharp as they say on TV, Officer.)I agree, but I don't think forcing them to explicitly cast is the best solution. See my previous post for what I'd suggest. Another option is simply using inout, although in that case you can't cast even if you want to (at least not very easily - you need a new var and a cast back).. btw, what I suggested is exactly the same regarding type safety as inout, the only inout's downside is that the caller's reference can be overwritten..I'm suggesting the user be more explicit about when they are risking type safety. The implicit cast is hiding some potentially very dangerous code.Implicitly upcasting containers is a big type safety hole if the result is allowed to change the contents of the container.Casting is the accepted way to blow away type safety. Let's keep it that way.See, it's not that simple. To have more type safety, you'd require more casts, but they result in less type safety, so it may actually be conterproductive..True, yet it still only happens at run-time, and it may even be unneeded: Object[] blah=someFunc(); // returns a new String[]; blah[0]=new Whatever(blah[0]);Java and C++ both allow implicit array upcasts, too, so I wouldn't say that people can't live with it?Note Java allows the implicit cast but doesn't allow the assignment that would break the type-safety.Although it's true - in D such an error will most probably not even get detected right away, which can probably cause quite a havoc, if you're lucky.. Again, I don't think forcing explicit casts will help;
Apr 20 2005
Why exactly? The point was that a) the code handles any Object b) Java would needlessly throw an exception hereTrue, yet it still only happens at run-time, and it may even be unneeded: Object[] blah=someFunc(); // returns a new String[]; blah[0]=new Whatever(blah[0]);Anybody writing that piece of code is asking for First Blood. Out of his own nose.There are limits to things. We don't want D to be jerk-proof. Probably there ought to be a law that says this kind of people should not have cutlery in the kitchen. (Why? Well, they might carve the dog or the postman, just out of ignorance: Oh, I just wanted to check if this knife is as sharp as they say on TV, Officer.)Bah, I can think of some other laws as well :P xs0
Apr 20 2005
xs0 wrote:If the code handles "any Object", then why be surprised if the compiler doesn't catch the situation where you suddenly don't want it to?Why exactly? The point was that a) the code handles any Object b) Java would needlessly throw an exception hereTrue, yet it still only happens at run-time, and it may even be unneeded: Object[] blah=someFunc(); // returns a new String[]; blah[0]=new Whatever(blah[0]);Anybody writing that piece of code is asking for First Blood. Out of his own nose.There are limits to things. We don't want D to be jerk-proof. Probably there ought to be a law that says this kind of people should not have cutlery in the kitchen. (Why? Well, they might carve the dog or the postman, just out of ignorance: Oh, I just wanted to check if this knife is as sharp as they say on TV, Officer.)Bah, I can think of some other laws as well :P xs0
Apr 20 2005
Georg Wrede wrote:xs0 wrote:I don't get what you're trying to say, sorry.. xs0If the code handles "any Object", then why be surprised if the compiler doesn't catch the situation where you suddenly don't want it to?Why exactly? The point was that a) the code handles any Object b) Java would needlessly throw an exception hereTrue, yet it still only happens at run-time, and it may even be unneeded: Object[] blah=someFunc(); // returns a new String[]; blah[0]=new Whatever(blah[0]);Anybody writing that piece of code is asking for First Blood. Out of his own nose.
Apr 21 2005
xs0 wrote:Below is what I responded to:If the code handles "any Object", then why be surprised if the compiler doesn't catch the situation where you suddenly don't want it to?I don't get what you're trying to say, sorry..Object[] blah=someFunc(); // returns a new String[]; blah[0]=new Whatever(blah[0]); Although it's true - in D such an error will most probably not even get detected right away, which can probably cause quite a havoc, if you're lucky.. Again, I don't think forcing explicit casts will help; if a change is going to happen, it should be where the function is, not where the caller is (in other words, type safety should be enforced already when defining functions, not when calling them).The code and the explanation looked as if having a reference to an instance of "Whatever" in the array was not welcome. The text mentioned "such an error". This gave me the impression that the coder had created an Object[] without intending it to accept precisely anything.
Apr 21 2005
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3pcr2$19r3$1 digitaldaemon.com..."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
In article <d3pq4b$1jhe$1 digitaldaemon.com>, Ben Hinkle says...I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.Moving the methods to interfaces *almost* works, and the changes really aren't too bad on the library side (I gave this a whirl with Ares--there's a branched version on my website if you're interested). But this approach also requires changes to portions of DMD that aren't shipped in source form, so estimating their scope is somewhat difficult. Maybe someone with GDC experience could chime in? Sean
Apr 15 2005
"Sean Kelly" <sean f4.ca> wrote in message news:d3pqsk$1jsl$1 digitaldaemon.com...In article <d3pq4b$1jhe$1 digitaldaemon.com>, Ben Hinkle says...The interface would presumably be Comparable.opCmp(Comparable), correct? I thought the primary complaint against opCmp was that people would define a class Foo with Foo.opCmp(Foo) and expect it to work. With Comparable to get things to work one has to know about Comparable and write Foo.opCmp(Comparable) instead of Foo.opCmp(Object). Is this what the interfaces proposal is? I'm asking because I'm not sure exactly what the details of the proposal are. If that is the proposal then what are the benefits?I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.Moving the methods to interfaces *almost* works, and the changes really aren't too bad on the library side (I gave this a whirl with Ares--there's a branched version on my website if you're interested). But this approach also requires changes to portions of DMD that aren't shipped in source form, so estimating their scope is somewhat difficult. Maybe someone with GDC experience could chime in?
Apr 15 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3prvs$1kms$1 digitaldaemon.com..."Sean Kelly" <sean f4.ca> wrote in message news:d3pqsk$1jsl$1 digitaldaemon.com...I think there are two (or more) proposals here. My idea doesn't involve a particular interface, rather heterogeneity is supported as a natural consequence of the requirement for all types in the array (or whatever) to be related polymorphically. I'm pretty sure what I proposed in March - "A proposal for a new, improved opCmp() [WAS: Round-up of the excuses for keeping Object.opCmp, and rebuttals to them]" (d0lsv5$1496$1 digitaldaemon.com) - still accurately represents my thoughts. Matthew P.S. Anyone advise on how to get a clickable message link from an entry in Outlook Express? I know it's done, because some of you do it. :-)In article <d3pq4b$1jhe$1 digitaldaemon.com>, Ben Hinkle says...The interface would presumably be Comparable.opCmp(Comparable), correct? I thought the primary complaint against opCmp was that people would define a class Foo with Foo.opCmp(Foo) and expect it to work. With Comparable to get things to work one has to know about Comparable and write Foo.opCmp(Comparable) instead of Foo.opCmp(Object). Is this what the interfaces proposal is? I'm asking because I'm not sure exactly what the details of the proposal are. If that is the proposal then what are the benefits?I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.Moving the methods to interfaces *almost* works, and the changes really aren't too bad on the library side (I gave this a whirl with Ares--there's a branched version on my website if you're interested). But this approach also requires changes to portions of DMD that aren't shipped in source form, so estimating their scope is somewhat difficult. Maybe someone with GDC experience could chime in?
Apr 15 2005
Yeah - the C++-style of using compile-time generics instead of run-time dispatching (Object or Comparable) seems like the most reasonable alternative to me at the moment - though it would also probably disrupt the TypeInfo system the most. The TypeInfos are a way to get generic type hooks without using templates or overloading. My gut is leaning towards either keeping Object.opCmp dynamic binding or ditching that for compile-time binding. The Comparable solution seems like a fairly small modification of Object.opCmp that doesn't really give enough benefits over Object.opCmp. But that's just my gut feelings without knowing much of anything about the actual proposals and their impact...The interface would presumably be Comparable.opCmp(Comparable), correct? I thought the primary complaint against opCmp was that people would define a class Foo with Foo.opCmp(Foo) and expect it to work. With Comparable to get things to work one has to know about Comparable and write Foo.opCmp(Comparable) instead of Foo.opCmp(Object). Is this what the interfaces proposal is? I'm asking because I'm not sure exactly what the details of the proposal are. If that is the proposal then what are the benefits?I think there are two (or more) proposals here. My idea doesn't involve a particular interface, rather heterogeneity is supported as a natural consequence of the requirement for all types in the array (or whatever) to be related polymorphically.I'm pretty sure what I proposed in March - "A proposal for a new, improved opCmp() [WAS: Round-up of the excuses for keeping Object.opCmp, and rebuttals to them]" (d0lsv5$1496$1 digitaldaemon.com) - still accurately represents my thoughts.I'll try to hunt that down.Matthew P.S. Anyone advise on how to get a clickable message link from an entry in Outlook Express? I know it's done, because some of you do it. :-)That would be nice because I only know how to point to the forum page on the DigitalMars site and that only takes you to a particular message and not the thread.
Apr 15 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3pvun$1n8i$1 digitaldaemon.com...Excellent point. I'd suggest that we downgrade any enthusiasm for the interface-based approach (and upgrade it for my proposal of course ... <laughing hysterically; kids looking on bemused "shush daddy!">Yeah - the C++-style of using compile-time generics instead of run-time dispatching (Object or Comparable) seems like the most reasonable alternative to me at the moment - though it would also probably disrupt the TypeInfo system the most. The TypeInfos are a way to get generic type hooks without using templates or overloading. My gut is leaning towards either keeping Object.opCmp dynamic binding or ditching that for compile-time binding. The Comparable solution seems like a fairly small modification of Object.opCmp that doesn't really give enough benefits over Object.opCmp. But that's just my gut feelings without knowing much of anything about the actual proposals and their impact...The interface would presumably be Comparable.opCmp(Comparable), correct? I thought the primary complaint against opCmp was that people would define a class Foo with Foo.opCmp(Foo) and expect it to work. With Comparable to get things to work one has to know about Comparable and write Foo.opCmp(Comparable) instead of Foo.opCmp(Object). Is this what the interfaces proposal is? I'm asking because I'm not sure exactly what the details of the proposal are. If that is the proposal then what are the benefits?I think there are two (or more) proposals here. My idea doesn't involve a particular interface, rather heterogeneity is supported as a natural consequence of the requirement for all types in the array (or whatever) to be related polymorphically.
Apr 15 2005
Ben Hinkle wrote: ...If you go to http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D, and click on the "Subject" tab, you can see the message titles. Since they're alphabetized, the first page currently has entries for "" (no subject), "!(null is hkey) ??", and other subjects which begin with punctuation symbols. You'll probably need to click the "More" button a few times to get close to what you're looking for. (Is that what you want or did I answer the wrong question?) -- jcc7 http://jcc_7.tripod.com/d/P.S. Anyone advise on how to get a clickable message link from an entry in Outlook Express? I know it's done, because some of you do it. :-)That would be nice because I only know how to point to the forum page on the DigitalMars site and that only takes you to a particular message and not the thread.
Apr 17 2005
"J C Calvarese" <jcc7 cox.net> wrote in message news:d3ume6$2h3g$1 digitaldaemon.com...Ben Hinkle wrote: ...I meant all I know how to do is this: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/6809 How can I get a link to the whole thread instead of just a message in the thread?If you go to http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D, and click on the "Subject" tab, you can see the message titles. Since they're alphabetized, the first page currently has entries for "" (no subject), "!(null is hkey) ??", and other subjects which begin with punctuation symbols. You'll probably need to click the "More" button a few times to get close to what you're looking for. (Is that what you want or did I answer the wrong question?)P.S. Anyone advise on how to get a clickable message link from an entry in Outlook Express? I know it's done, because some of you do it. :-)That would be nice because I only know how to point to the forum page on the DigitalMars site and that only takes you to a particular message and not the thread.
Apr 17 2005
Ben Hinkle wrote:"J C Calvarese" <jcc7 cox.net> wrote in message news:d3ume6$2h3g$1 digitaldaemon.com...Oops, I misunderstood. I don't think I've seen anyone do that (maybe it doesn't work for me since I use Thunderbird). Would it show up in a newsreader or a web-browser? Or do you mean one of the archive pages, such as http://www.digitalmars.com/d/archives/digitalmars/D/13965.html? There's a separate main page for each newsgroup (but Walter hasn't run his update process in a while, so not all of the newsgroups even have a page yet): http://www.digitalmars.com/d/archives/digitalmars/D/index.html http://www.digitalmars.com/d/archives/digitalmars/D/dtl/index.html http://www.digitalmars.com/d/archives/digitalmars/D/bugs/index.html http://www.digitalmars.com/d/archives/D/gnu/index.html http://www.digitalmars.com/d/archives/index.html -- jcc7 http://jcc_7.tripod.com/d/Ben Hinkle wrote: ...I meant all I know how to do is this: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/6809 How can I get a link to the whole thread instead of just a message in the thread?If you go to http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D, and click on the "Subject" tab, you can see the message titles. Since they're alphabetized, the first page currently has entries for "" (no subject), "!(null is hkey) ??", and other subjects which begin with punctuation symbols. You'll probably need to click the "More" button a few times to get close to what you're looking for. (Is that what you want or did I answer the wrong question?)P.S. Anyone advise on how to get a clickable message link from an entry in Outlook Express? I know it's done, because some of you do it. :-)That would be nice because I only know how to point to the forum page on the DigitalMars site and that only takes you to a particular message and not the thread.
Apr 17 2005
J C Calvarese wrote:Ben Hinkle wrote:Man, we should collect money to give him a Linux box. ;-) They do stuff like that by themselves."J C Calvarese" <jcc7 cox.net> wrote in message news:d3ume6$2h3g$1 digitaldaemon.com...Oops, I misunderstood. I don't think I've seen anyone do that (maybe it doesn't work for me since I use Thunderbird). Would it show up in a newsreader or a web-browser? Or do you mean one of the archive pages, such as http://www.digitalmars.com/d/archives/digitalmars/D/13965.html? There's a separate main page for each newsgroup (but Walter hasn't run his update process in a while, so not all of the newsgroups even have a page yet):Ben Hinkle wrote: ...I meant all I know how to do is this: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/6809 How can I get a link to the whole thread instead of just a message in the thread?If you go to http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D, and click on the "Subject" tab, you can see the message titles. Since they're alphabetized, the first page currently has entries for "" (no subject), "!(null is hkey) ??", and other subjects which begin with punctuation symbols. You'll probably need to click the "More" button a few times to get close to what you're looking for. (Is that what you want or did I answer the wrong question?)P.S. Anyone advise on how to get a clickable message link from an entry in Outlook Express? I know it's done, because some of you do it. :-)That would be nice because I only know how to point to the forum page on the DigitalMars site and that only takes you to a particular message and not the thread.http://www.digitalmars.com/d/archives/digitalmars/D/index.html http://www.digitalmars.com/d/archives/digitalmars/D/dtl/index.html http://www.digitalmars.com/d/archives/digitalmars/D/bugs/index.html http://www.digitalmars.com/d/archives/D/gnu/index.html http://www.digitalmars.com/d/archives/index.html
Apr 18 2005
I agree - I don't think it is possible either, but I figured I'd ask since many people on this list can run a forum site in their sleep and might know a trick to get the thread link. I only mentioned it because Matthew innocently asked the question about how to get OE to produce links - which I don't know how to do either. When I want to reference a message I have to go fire up the dmd web site and find the message and grab the URL.I meant all I know how to do is this: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/6809 How can I get a link to the whole thread instead of just a message in the thread?Oops, I misunderstood. I don't think I've seen anyone do that (maybe it doesn't work for me since I use Thunderbird). Would it show up in a newsreader or a web-browser?no.Or do you mean one of the archive pages, such as http://www.digitalmars.com/d/archives/digitalmars/D/13965.html?I already have a Linux box - or more accurately I made my Windows box dual-boot. I flip back and forth about my preferred boot system. Some months I wind up working on Linux more, sometimes Windows more.There's a separate main page for each newsgroup (but Walter hasn't run his update process in a while, so not all of the newsgroups even have a page yet):Man, we should collect money to give him a Linux box. ;-) They do stuff like that by themselves.yup. I'm aware of those. I often search them for reference links.http://www.digitalmars.com/d/archives/digitalmars/D/index.html http://www.digitalmars.com/d/archives/digitalmars/D/dtl/index.html http://www.digitalmars.com/d/archives/digitalmars/D/bugs/index.html http://www.digitalmars.com/d/archives/D/gnu/index.html http://www.digitalmars.com/d/archives/index.html
Apr 18 2005
Ben Hinkle wrote:I meant get a Linux box for Walter, so he didn't have to _remember_ to update the newsgroups every time. :-)I already have a Linux box - or more accurately I made my Windows box dual-boot. I flip back and forth about my preferred boot system. Some months I wind up working on Linux more, sometimes Windows more.There's a separate main page for each newsgroup (but Walter hasn't run his update process in a while, so not all of the newsgroups even have a page yet):Man, we should collect money to give him a Linux box. ;-) They do stuff like that by themselves.
Apr 18 2005
Georg Wrede wrote:Ben Hinkle wrote:I don't expect Walter to update the archives every day, but once a month would be nice. ;)I meant get a Linux box for Walter, so he didn't have to _remember_ to update the newsgroups every time.I already have a Linux box - or more accurately I made my Windows box dual-boot. I flip back and forth about my preferred boot system. Some months I wind up working on Linux more, sometimes Windows more.There's a separate main page for each newsgroup (but Walter hasn't run his update process in a while, so not all of the newsgroups even have a page yet):Man, we should collect money to give him a Linux box. ;-) They do stuff like that by themselves.:-)-- jcc7 http://jcc_7.tripod.com/d/
Apr 18 2005
"Georg Wrede" <georg.wrede nospam.org> wrote in message news:4263B525.2090800 nospam.org...I meant get a Linux box for Walter, so he didn't have to _remember_ to update the newsgroups every time.Jan and I have been talking about automating it a bit.
Apr 30 2005
On Mon, 18 Apr 2005 08:51:47 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I just grab the first part of the url i.e. http://www.digitalmars.com/drn-bin/wwwnews? add the newsgroup name http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/ add the article id (I get this from the headers of the message I want to reference, i.e. your message to which I replied has "Xref: digitalmars.com digitalmars.D:21910" giving me http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21910 It would be nice if the client did all this work for me, it could do from "http://www.digitalmars.com/drn-bin/wwwnews?" and the Xref header. ReganI agree - I don't think it is possible either, but I figured I'd ask since many people on this list can run a forum site in their sleep and might know a trick to get the thread link. I only mentioned it because Matthew innocently asked the question about how to get OE to produce links - which I don't know how to do either. When I want to reference a message I have to go fire up the dmd web site and find the message and grab the URL.I meant all I know how to do is this: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/6809 How can I get a link to the whole thread instead of just a message in the thread?Oops, I misunderstood. I don't think I've seen anyone do that (maybe it doesn't work for me since I use Thunderbird). Would it show up in a newsreader or a web-browser?
Apr 18 2005
I think there are two (or more) proposals here. My idea doesn't involve a particular interface, rather heterogeneity is supported as a natural consequence of the requirement for all types in the array (or whatever) to be related polymorphically. I'm pretty sure what I proposed in March - "A proposal for a new, improved opCmp() [WAS: Round-up of the excuses for keeping Object.opCmp, and rebuttals to them]" (d0lsv5$1496$1 digitaldaemon.com) - still accurately represents my thoughts.I went and checked (btw, it would've been nice to mention that the thread started in September 2004 :) I see at least this problem:As it stands above, a heterogeneous array of instances of these types, say [b1, b2, d1, md1, b3, md2, b4] would be sortable because Base derives opCmp(). Moreover, it would be sorted solely by the implementation of Base.opCmp() for all instances irrespective of their actual type.This means that either Base must know all its subclasses (which is like total crap), or that all subclasses must implement opCmp(Base), which is about the same as implementing opCmp(Object), its just a different base class. Furthermore, suppose I create a Number->[Int, Float] hierarchy and use it throughout my code. Later, I need to interface with some library, but that library has its own Num->[Integer, Double] hierarchy. I see no reason why they shouldn't be comparable, but they can't be, if there's no opCmp in Object.. xs0
Apr 15 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote..."Sean Kelly" <sean f4.ca> wrote in message news:d3pqsk$1jsl$1 digitaldaemon.com...RedoingIn article <d3pq4b$1jhe$1 digitaldaemon.com>, Ben Hinkle says...I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work?Aye.The interface would presumably be Comparable.opCmp(Comparable), correct?large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.Moving the methods to interfaces *almost* works, and the changes really aren't too bad on the library side (I gave this a whirl with Ares--there's a branched version on my website if you're interested). But this approach also requires changes to portions of DMD that aren't shipped in source form, so estimating their scope is somewhat difficult. Maybe someone with GDC experience could chime in?I thought the primary complaint against opCmp was that people would defineaclass Foo with Foo.opCmp(Foo) and expect it to work.I thought it was the fact that classes should not be Comparable by default, since it makes no sense to compare them if not explicitly supported. There's also the small issue of apparently being incompatable with a compacting-GC. Further, in the interests of robustness and correctness, there should be a compile-time error for attempts to compare an aggregate that does not explicitly implement opCmp(). The interface can potentially move opEquals() out of the root object also, such that it would be a compile-time error to apply '==' upon a class without an explicit opEquals() implementation. This makes for notably more robust code, as was discussed at length recently. We're talking about the root object here. It should be engineered in such a manner whereby it /prevents/ pedestrian faults. It should certainly not breed them :-) There are limitations using the interface approach; perhaps the main one is the method declaration, as you pointed out. The best overall suggestion I've heard so far was from Matthew ~ but that requires a change to the compiler. The interface approach would, on the surface, potentially work without any internal compiler changes. There's the tradeoff. - Kris
Apr 15 2005
Personally I have no problem with a default behavior if it has enough practical benefits. The debatable part is narrowed down to "enough", "practical" and "benefits". :-)I thought the primary complaint against opCmp was that people would define a class Foo with Foo.opCmp(Foo) and expect it to work.I thought it was the fact that classes should not be Comparable by default, since it makes no sense to compare them if not explicitly supported.There's also the small issue of apparently being incompatable with a compacting-GC.This one doesn't worry me too much because the GC and Object.opCmp are compiler-dependent - though I know Sean is working on a pluggable API for the GC. It would be nice to not have to worry about it at all.Further, in the interests of robustness and correctness, there should be a compile-time error for attempts to compare an aggregate that does not explicitly implement opCmp(). The interface can potentially move opEquals() out of the root object also, such that it would be a compile-time error to apply '==' upon a class without an explicit opEquals() implementation. This makes for notably more robust code, as was discussed at length recently. We're talking about the root object here. It should be engineered in such a manner whereby it /prevents/ pedestrian faults. It should certainly not breed them :-) There are limitations using the interface approach; perhaps the main one is the method declaration, as you pointed out. The best overall suggestion I've heard so far was from Matthew ~ but that requires a change to the compiler. The interface approach would, on the surface, potentially work without any internal compiler changes. There's the tradeoff.Presumably the TypeInfo for Object (ti_C.d) and arrays of objects (ti_AC.d) would try casting to Comparable and throw if it failed? That seems the most reasonable behavior. That way the code class Foo {} void main() { Foo[] x,y; x.length = 2; y.length = 2; x < y; } would compile but throw at run-time. The alternative would be to change how array comparison works more fundamentally. Similarly the AA implementation would have to change to not use the TypeInfo compare hook at all.
Apr 15 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3pq4b$1jhe$1 digitaldaemon.com..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3pcr2$19r3$1 digitaldaemon.com...Not at all. It's a great idea. I myself have only a semi-rigorous idea of what's to be involved. Kris is, I think, the top expert on this topic. I think a proper discussion of what's involved is a great idea. Kris, do you want to kick it off?"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".
Apr 15 2005
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3psf3$1l16$1 digitaldaemon.com..."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3pq4b$1jhe$1 digitaldaemon.com...? Yer arse!"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3pcr2$19r3$1 digitaldaemon.com...Not at all. It's a great idea. I myself have only a semi-rigorous idea of what's to be involved. Kris is, I think, the top expert on this topic."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".I think a proper discussion of what's involved is a great idea. Kris, do you want to kick it off?Okay. Here we are again at Wibbly Stadium, where the vast crowd of -- two -- are anxious for the match to begin ... Ref blows his whistle! Match begins ~ Kris takes the centre-kick and ... passes the ball to Matthew! Seriously though. Sean just posted that he's actually tried the Interface approach with Ares, so I suggest we take this conversation over there instead. I'll happily weight in on the topic, but let's see what Sean has. BTW; as far as resolutions go, I fully agree with Matthew's (earlier) take on it. But the compiler would have to change for that to happen. If that's kosher, then whoopee. Otherwise we have to look for an alternate. What Sean is attempting appears to be one reasonable option.
Apr 15 2005
"Kris" <fu bar.com> wrote in message news:d3ptks$1lkj$1 digitaldaemon.com..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3psf3$1l16$1 digitaldaemon.com...Before we get into this, and potentially waste many more hours on challenging, enlightening, but eventually fruitless debate, I want to hear from Walter as to his _feeling_ on how close we are to 1.0, and therefore how amenable he's going to be to making significant language changes at this point. Otherwise, we really are just spending time we don't have for nothing more than a couple of chapters of "Imperfect D". Walter, can you characterise your position? Specifically, 1. Do you believe that there are any "serious flaws" in the D specification as it stands? 2. If the answer is no, do you have a degree of certainty that is unlikely to be overridden by any observations any of us might make? 3. If the answer to either 1 or 2 is yes, do you nonetheless have a need to expedite 1.0 despite any/all such "major flaws"? Obviously, if we get (X, Yes, Y) or (X, Y, Yes), then there's no point having the debate."Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:d3pq4b$1jhe$1 digitaldaemon.com...? Yer arse!"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:d3pcr2$19r3$1 digitaldaemon.com...Not at all. It's a great idea. I myself have only a semi-rigorous idea of what's to be involved. Kris is, I think, the top expert on this topic."Ben Hinkle" <bhinkle mathworks.com> wrote in message news:d3p9qh$17hr$1 digitaldaemon.com...I'd like to see a more complete description of what would change before making up my mind. If we just remove Object.opCmp obviously many things won't work (eg, aa's, sorting, dynamic array operations, maybe more) so what exactly won't work and what will have to change to get it to work? Redoing large chunks of the TypeInfo system isn't trivial IMO. Maybe I'm just being thick but I'd like to see more details.But what's the attraction with addressing the symptoms of a disease, when we can prevent the disease? I'm not being sarcastic, I really want to know why people prefer this approach? Does it have _any_ advantages?2. Leave the current DMD behaviour in, and document it properly.I would add 2a: leave it in, document it and add a warning to dmd and dlint for classes that define an opCmp that shadows Object.opCmp. In fact a general warnings about shadowing member functions in base classes should say "Foo.opCmp(Foo) shadows Object.opCmp(Object)". For the common case of Object.opCmp it should give a nicer warning that should say something like "Foo.opCmp(Foo) shadows Object.opCmp(Object). Consider defining Foo.opCmp(Object) for associative arrays, sorting and other uses".I think a proper discussion of what's involved is a great idea. Kris, do you want to kick it off?Okay. Here we are again at Wibbly Stadium, where the vast crowd of -- two -- are anxious for the match to begin ... Ref blows his whistle! Match begins ~ Kris takes the centre-kick and ... passes the ball to Matthew! Seriously though. Sean just posted that he's actually tried the Interface approach with Ares, so I suggest we take this conversation over there instead. I'll happily weight in on the topic, but let's see what Sean has. BTW; as far as resolutions go, I fully agree with Matthew's (earlier) take on it. But the compiler would have to change for that to happen. If that's kosher, then whoopee. Otherwise we have to look for an alternate. What Sean is attempting appears to be one reasonable option.
Apr 15 2005
Matthew wrote:Walter, can you characterise your position? Specifically, 1. Do you believe that there are any "serious flaws" in the D specification as it stands? 2. If the answer is no, do you have a degree of certainty that is unlikely to be overridden by any observations any of us might make? 3. If the answer to either 1 or 2 is yes, do you nonetheless have a need to expedite 1.0 despite any/all such "major flaws"? Obviously, if we get (X, Yes, Y) or (X, Y, Yes), then there's no point having the debate.You'd better ask Walter off-line. The chances of him finding your particular post (soon enough), may be slim. So, get the answer, and post it here, thanks.
Apr 17 2005