D - Operator overloading: A way to make everybody happy?
- OddesE (41/41) Jan 22 2002 Ok, so one more time about operator overloading... :)
- Sean L. Palmer (10/51) Jan 22 2002 That could be an easy way to deal with the syntax part of it. Sounds
- Walter (12/20) Jan 22 2002 pure
-
Roberto Mariottini
(13/20)
Jan 23 2002
"Walter"
ha scritto nel messaggio - Walter (6/12) Jan 23 2002 optimizing
- Roberto Mariottini (14/26) Jan 24 2002 Ok, but this little word can work like C "register" one:
- Walter (10/21) Jan 24 2002 It isn't that hard to do the final optimization. You just look to see if
- OddesE (130/138) Jan 24 2002 pure
- Juan Carlos Arevalo Baeza (72/87) Jan 22 2002 Actually, there might be.
- Juarez Rudsatz (62/62) Jan 25 2002 This form could be a very good way of solving the problem for classes.
- Russ Lewis (26/35) Jan 25 2002 Override Add(Object), and add an in-contract that the class be of type
- OddesE (20/39) Jan 25 2002 It is not possible to overload operators for basic types, at least
- Sean L. Palmer (38/50) Jan 26 2002 Unfortunately to provide an interface, you need a vtable. But most of t...
- Robert W. Cunningham (8/39) Jan 26 2002 I do lots of image processing (especially color space conversions and
- Russell Borogove (11/22) Jan 26 2002 While my needs are the same as yours, and float 4-element
- Walter (28/28) Feb 12 2002 I've been thinking a lot about operator overloading.
- D (24/41) Feb 12 2002 Why?
- Pavel Minayev (17/43) Feb 12 2002 I think that most people here would be happy to be able to overload
- Russ Lewis (16/22) Feb 12 2002 I would like to see the compiler provide the remaining logical operators...
- Pavel Minayev (9/20) Feb 12 2002 I meant && and ||.
- Russ Lewis (21/28) Feb 12 2002 True. Many of the common operators can be generated from each other. I...
- Pavel Minayev (7/12) Feb 12 2002 think
- Walter (6/16) Feb 12 2002 if only
- Pavel Minayev (8/9) Feb 12 2002 Hmmm... operator cmp?
- Walter (4/13) Feb 13 2002 No, it would return an int <0, 0, or >0. That makes it more efficiently
- Pavel Minayev (4/6) Feb 13 2002 Either way, it'd make things simplier in many cases. Provide cmp, and
- Russ Lewis (10/11) Feb 12 2002 True, but that is only for things that are reasonably ordered. Some thi...
- Pavel Minayev (5/8) Feb 12 2002 things
- Walter (6/12) Feb 13 2002 things
- Pavel Minayev (5/7) Feb 13 2002 knows
- Sean L. Palmer (8/27) Feb 12 2002 collected
- Roberto Mariottini (38/57) Feb 13 2002 collected
- Russ Lewis (40/56) Feb 12 2002 Hmmm....D beat me to the punch. But there's a chance for intelligent
- Walter (20/52) Feb 12 2002 associated
- Russ Lewis (10/14) Feb 12 2002 You could simply define that for built-in types :+: is exactly equivalen...
- Pavel Minayev (4/6) Feb 12 2002 to
- Roberto Mariottini (12/18) Feb 13 2002 equivalent
- Pavel Minayev (8/16) Feb 13 2002 Then I don't see much reason in adding something to state an overloaded
- OddesE (7/23) Feb 16 2002 lexical
- Walter (6/15) Feb 12 2002 for
- Robert W. Cunningham (4/5) Feb 12 2002 Umm, we could go straight for "D++", couldn't we? (And no, I'm under no
- Sean L. Palmer (24/52) Feb 12 2002 Right. One of the beauties of templates is being able to write T a = b ...
- Pavel Minayev (9/19) Feb 12 2002 restrict
- Robert W. Cunningham (62/90) Feb 12 2002 I prefer declaring a new or overloaded operator to EXACTLY resemble a fu...
- D (13/23) Feb 04 2002 Operatoror overloading is an error gnashing at the bit to happen. There...
- Sean L. Palmer (33/43) Feb 04 2002 Your first paragraph shows you to be closed minded. By that argument,
- D (56/79) Feb 04 2002 Pointers have their place because they improve efficiency. Operator
- OddesE (28/107) Feb 05 2002 won't
- D (8/11) Feb 06 2002 Re: What ops to use for operator overloading for cross and dot products.
- Pavel Minayev (11/14) Feb 06 2002 a
- D (13/21) Feb 07 2002 Paul, left to themselves members of the C religion would change nothing,
- Russ Lewis (22/26) Feb 04 2002 (please excuse my slight flamishness coming...)
-
D
(11/16)
Feb 04 2002
I agree. But well controlled, well designed situations
occur. ... - Serge K (2/5) Feb 05 2002 According to IEEE 754,
- Russell Borogove (8/15) Feb 05 2002 Just an anecdote, but I've run into a compiler that evaluated
- Roberto Mariottini (8/13) Feb 06 2002 taken
- D (12/27) Feb 07 2002 What the hell is a case insensitive string. Now that is a dum idea. Ca...
- Roberto Mariottini (16/26) Feb 07 2002 I think they are all good ideas.
- D (43/57) Feb 09 2002 Clearly not. Case insensitive strings provide no advantage.
- Juan Carlos Arevalo Baeza (30/40) Feb 08 2002 That'll be in your opinion, sir!
- D (24/28) Feb 09 2002 As I recognized, case insensitivity is indeed a good thing. A native ty...
- D (10/15) Feb 06 2002 Really? I didn't know that.
- Pavel Minayev (4/7) Feb 06 2002 irrational
- D (5/13) Feb 07 2002 Why is that Paul. Are you unable to change -0.0 into 0.0?
- OddesE (75/86) Feb 04 2002 is
- D (30/54) Feb 04 2002 Consider this piece of code
- Pavel Minayev (5/9) Feb 04 2002 I do. If I use your library, I'd expect + to add vectors.
- D (11/22) Feb 05 2002 Yet you see .+ being applied to a variable, perhaps a vector, perhaps no...
- Roberto Mariottini (9/18) Feb 05 2002 that
- D (4/8) Feb 05 2002 hidden
- OddesE (93/152) Feb 05 2002 Consider this pieces of code:
- D (147/258) Feb 06 2002 Yup I do see difficulty with your code. It's difficult to read because...
- OddesE (190/456) Feb 07 2002 you
- Immanuel Scholz (169/431) Mar 06 2002 Hm. Without either operator overloading or adding new ops, I have
- Pavel Minayev (22/54) Mar 06 2002 Hey hey hey, stop!.. let it be there, just leave it to us gurus =)
-
OddesE
(46/50)
Mar 07 2002
"Pavel Minayev"
wrote in message - Pavel Minayev (13/20) Mar 07 2002 You don't actually "destroy" anything in D. Even operator
- Russ Lewis (10/19) Mar 08 2002 Walter may have to correct my memory here, but I think that delete
- Russ Lewis (15/18) Mar 08 2002 If you allow infix function calls, then they're not even operators. You
- Pavel Minayev (7/16) Mar 08 2002 Could be. But I thought a separate syntax for operators would
- Russ Lewis (11/20) Mar 08 2002 Right. That function I proposed was something that RETURNS a pointer......
- Pavel Minayev (19/24) Mar 08 2002 No, I mean that since StdIn is a class, you don't need
- Russ Lewis (8/17) Mar 08 2002 Oops, right again. :(
- Immanuel Scholz (12/19) Mar 08 2002 Hm, I tend to have pointers in classes without the need to destroy
- Pavel Minayev (11/17) Mar 08 2002 Well if D would support variants (or object packaging as seen
- Immanuel Scholz (5/22) Mar 08 2002 -> has a different meaning. Although it is not used in D, I prefer anoth...
- Pavel Minayev (7/10) Mar 08 2002 I remember >>> was unsigned shift. -=> just looks somewhat
- Immanuel Scholz (10/21) Mar 08 2002 another
- Pavel Minayev (16/20) Mar 08 2002 ...unless the author of the language and the community STRONGLY
- Roland (5/8) Mar 08 2002 while you are reconsidering the way stream are implemented, i personally
-
Russell Borogove
(10/18)
Mar 08 2002
- Walter (17/21) Mar 10 2002 I remember back when C was new and Pascal was the old guard. Many C
Ok, so one more time about operator overloading... :) I read all the posts about operator overloading but I'm still a bit unsure about it...Do I want it, or don't I... I like about operator overloading the fact that you can add, subtract, compare or assign objects to one another much the same way as you can with normal primitive types. I hate some uses of operator overloading which seem really confusing to me. I always disliked the way cout and cin work. But maybe there is some middle ground? A compromise that could make everybody happy? Here is my idea: Think of Java, if you know it. It contains interfaces just like D. One of these interfaces is called Clonable. If you want your object to be copied to another, you implement Clonable. Now what if we could combine these kinds of interfaces with a form of predefined operator overloading. You would have a few predefined interfaces: IComparable, IAssignable, ISortable, IAddable, ISubtractable, IMultiplyable, IDividable...you get the idea. D would be able to check if an object implemented any of these interfaces and would automagically provide the suitable operators. I have already tried to implement something like this in C++ and I actually got IAssignable and IComparable to work, but when I tried to add more I got into trouble with multiple inheritance. Just a thought, but I think this might be a solution that would make everybody happy! P.S: There is another thread about templates which contains some sort of a variation on this: Constrained Genericity (template suggestion) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Jan 22 2002
That could be an easy way to deal with the syntax part of it. Sounds promising. I assume the operator would just map to a "normal" looking pure virtual function, such as Addable Add(Addable other), which could then be overridden. Unfortunately in D all functions are virtual, so the calling overhead will be large, but at least it would be possible to accomplish the goal of making a class work like a built-in type. Sean "OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a2k8u8$fao$1 digitaldaemon.com...Ok, so one more time about operator overloading... :) I read all the posts about operator overloading but I'm still a bit unsure about it...Do I want it, or don't I... I like about operator overloading the fact that you can add, subtract, compare or assign objects to one another much the same way as you can with normal primitive types. I hate some uses of operator overloading which seem really confusing to me. I always disliked the way cout and cin work. But maybe there is some middle ground? A compromise that could make everybody happy? Here is my idea: Think of Java, if you know it. It contains interfaces just like D. One of these interfaces is called Clonable. If you want your object to be copied to another, you implement Clonable. Now what if we could combine these kinds of interfaces with a form of predefined operator overloading. You would have a few predefined interfaces: IComparable, IAssignable, ISortable, IAddable, ISubtractable, IMultiplyable, IDividable...you get the idea. D would be able to check if an object implemented any of these interfaces and would automagically provide the suitable operators. I have already tried to implement something like this in C++ and I actually got IAssignable and IComparable to work, but when I tried to add more I got into trouble with multiple inheritance. Just a thought, but I think this might be a solution that would make everybody happy! P.S: There is another thread about templates which contains some sort of a variation on this: Constrained Genericity (template suggestion) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Jan 22 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a2kevr$j2g$1 digitaldaemon.com...That could be an easy way to deal with the syntax part of it. Sounds promising. I assume the operator would just map to a "normal" lookingpurevirtual function, such as Addable Add(Addable other), which could then be overridden. Unfortunately in D all functions are virtual, so the calling overhead will be large, but at least it would be possible to accomplish the goal ofmakinga class work like a built-in type. SeanIt is an interesting idea. While D defines all functions to be virtual, a good optimizing compiler can de-virtualize (!) any functions which are not overridden by a derived class. This is one example where D simplifies programming and reduces errors. In my C++ work, I do this manually (then I add a derived class, forget to add "virtual", and have a subtle bug. Argh!). Since an optimizing D compiler will de-virtualize all calls it can, it can potentially have many *fewer* virtual calls than the equivalent C++ program.
Jan 22 2002
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:a2km7g$o9f$1 digitaldaemon.com...[...]While D defines all functions to be virtual, a good optimizing compilercande-virtualize (!) any functions which are not overridden by a derivedclass.This is one example where D simplifies programming and reduces errors. InmyC++ work, I do this manually (then I add a derived class, forget to add "virtual", and have a subtle bug. Argh!). Since an optimizing D compiler will de-virtualize all calls it can, it can potentially have many *fewer* virtual calls than the equivalent C++ program.Here Java has a point: a 'final' class cannot be derived, so the optimizing compiler can de-virtualize all functions it can. When you try to derive from this class the compiler signal an error, so you can remove the little 'final' word and recompile safely. Ciao
Jan 23 2002
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:a2ls2g$1hvv$1 digitaldaemon.com...Here Java has a point: a 'final' class cannot be derived, so theoptimizingcompiler can de-virtualize all functions it can. When you try to derive from this class the compiler signal an error, soyoucan remove the little 'final' word and recompile safely.True, but to me that 'final' keyword is there to compensate for a weakness in the optimizer. It's unnecessary.
Jan 23 2002
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:a2nt3r$2v4f$3 digitaldaemon.com..."Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:a2ls2g$1hvv$1 digitaldaemon.com...Ok, but this little word can work like C "register" one: - You don't need an optimizer to do easy optimization. Consider that not every compiler has a (good) optimizer, especially alpha or beta compilers ;-) - A final class can be safely optimized even in debug releases, this will ease debugging. - The average optimizer is simpler to write. - A good optimizer can optimize even non-final classes (and even ignore final ones), as you stated, and as the 'register' keyword works in C. PS: I suppose there is no 'register' keyword in D, right? CiaoHere Java has a point: a 'final' class cannot be derived, so theoptimizingcompiler can de-virtualize all functions it can. When you try to derive from this class the compiler signal an error, soyoucan remove the little 'final' word and recompile safely.True, but to me that 'final' keyword is there to compensate for a weakness in the optimizer. It's unnecessary.
Jan 24 2002
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:a2p5j5$qlp$1 digitaldaemon.com...Ok, but this little word can work like C "register" one: - You don't need an optimizer to do easy optimization. Consider that not every compiler has a (good) optimizer, especially alpha or beta compilers ;-)It isn't that hard to do the final optimization. You just look to see if there are any derived classes, and if any of those derived classes override it.- A final class can be safely optimized even in debug releases, this will ease debugging. - The average optimizer is simpler to write.True, but I propose to simplify the language, and am willing to put a little more burden on the compiler to get that. You can remind me that I propose that D be easy to write a compiler for, and I respond that it isn't necessary for a compiler to implement this optimization!- A good optimizer can optimize even non-final classes (and even ignore final ones), as you stated, and as the 'register' keyword works in C. PS: I suppose there is no 'register' keyword in D, right?Correct. C compilers haven't been dependent on it for over a decade.
Jan 24 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a2kevr$j2g$1 digitaldaemon.com...That could be an easy way to deal with the syntax part of it. Sounds promising. I assume the operator would just map to a "normal" lookingpurevirtual function, such as Addable Add(Addable other), which could then be overridden. Unfortunately in D all functions are virtual, so the calling overhead will be large, but at least it would be possible to accomplish the goal ofmakinga class work like a built-in type. SeanThat is indeed exactly what I was thinking of. In my opinions there are at least three benefits to using such an approach: 1. You have a standardized way of creating "operators". If you would implement IAssignable, the operator = would work for your class. If you implement IAddable, then operator + would also work. Combining the two would automatically give you operator += as well. Because the routines are standardized, and because D would make smart combinations of routines to give you combined operators such as +=, you would have to implement less functions to support more operators and errors would be made less frequently. 2. Everyone can choose. If the interface IAddable would contain a pure virtual method Add(), this would be standard. So people can choose wheter to use Add() or +, knowing they will always be both fully supported and work exactly the same, or both of them won't be supported at all. Hell, using DML you could even allow both forms to be exchanged into one another depending on a preferences setting. 3. You can detect wheter a class supports a certain type of operator. Using RTTI you can determine if a class IS A IAddable or not. This might be *very* valuable. This could also be used to force a class to support an operator. How about: COrderedList.Insert (ISortable element) ? I also see some problems for this approach though: 1. Speed. It might be too slow to implement operator overloading this way. But I really don't know how good or bad a compiler might optimise this. I imagine it would be possible for the compiler to change obj + obj to obj.Add (obj) at compile time, but I don't know if this is in fact possible. 2. Operator 'dependencies'... Think of ISortable, it would probably have a method IsLess () or something, but it doesn't really make sense to implement that without implementing IComparable's IsEqual(). Now this problem isn't new, it is just an old problem that isn't solved. In C++ it is also possible to overload < but not ==. You could try to make ISortable inherit from IComparable, so implementing IsLess forces you to implement IsEqual too. I tried this in my C++ experiment but ran into trouble with virtual inheritance. I think that it should be possible using interfaces though... To give you more of a feeling of how it would work, I'll post some sample code. I'm typing this in my newsreader, so please forgive me my 'spelling'. :) interface IAssignable { void Assign (Object obj); void Assign (int i); void Assign (bool b); void Assign (double d); void Assign (char c); // ... It gets dull, but you get the idea // One Assign for Object's and one for // each standard type. } interface IAddable { void Add (Object obj); // ... } interface ISubtractable { void Subtract (Object obj); // ... } interface IDividable { void Divide (Object obj); // ... } interface IMutiplyable { void Multiply (Object obj); // ... } interface IComparable { bool IsEqual (Object obj); // ... } interface ISortable: IComparable { bool IsLess (Object obj); // ... } class CMyObject: IComparable { public int m_i; this (int i) {m_i = i}; bool IsEqual (Object obj) { CMyObject myObj = cast (CMyObject) obj; if (myObj == null) return false; return (this.m_i == myObj.m_i); } bool IsLess (Object obj) { CMyObject myObj = cast (CMyObject) obj; if (myObj == null) return false; return (this.m_i < myObj.m_i); } } // And how you would use it: CMyObject obj1 = new CMyObject (10); CMyObject obj2 = new CMyObject (13); if (obj1 < obj2) // Would call: // if (obj1.Less (obj2)) if (obj1 <= obj2) // Would call: // if ((obj1.Less (obj2)) || (obj1.IsEqual (obj2))) if (obj1 > obj2) // Would call: // if ((! obj1.Less (obj2)) && (! obj1.IsEqual (obj2))) if (obj1 >= obj2) // Would call: // if ((! obj1.Less (obj2))) Well that's about it. Greets! -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Jan 24 2002
"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a2k8u8$fao$1 digitaldaemon.com...But maybe there is some middle ground? A compromise that could make everybody happy?Actually, there might be.Think of Java, if you know it. It contains interfaces just like D. One of these interfaces is called Clonable. If you want your object to be copied to another, you implement Clonable. Now what if we could combine these kinds of interfaces with a form of predefined operator overloading. You would have a few predefined interfaces: IComparable, IAssignable, ISortable, IAddable, ISubtractable, IMultiplyable, IDividable...you get the idea. D would be able to check if an object implemented any of these interfaces and would automagically provide the suitable operators.This is actually close to the concept of a "class" in Haskell. Haskell is a very interesting language for anyone who's into programming languages. It's designed from the ground up to be a pure functional language, which usually makes the imperative programmer queasy, but it's actually a very usable and mature language at this point. So, let me show a bit what Haskell calls classes. I'll change the syntax so as to make it more D-like or C++-like: --- typeclass Eq(a) { bool operator ==(a, a); bool operator !=(a, a); // Minimal complete defintion: // (==) or (!=) // [JCAB] These are default definitions... bool operator ==(a x, a y) { return not(x != y); } bool operator !=(a x, a y) { return not(x == y); } } --- This defines the class of all types (a is a type parameter) that have equality comparison in them. Then, you can define your own types, like a 3D vector: --- class Vector3D { float x, y, z; } --- And then (separately) give the vector the equality class: --- typeclassinstance Eq(Vector3D) { bool operator ==(Vector3D v0, Vector3D v1) { return v0.x == v1.x && v0.y == v1.y && v0.z == v1.z; } // operator != gets implemented from the default. } --- Of course, the implementation of something like this in D would follow more what Stijn was saying. In Haskell, it is assumed that polymorphic functions (and operators) like those defined in a type class like that can have an extra "hidden" parameter called the dictionary (you can assume it's like an extra virtual function table pointer) for each type class used in the implementation of the function. Type classes in Haskell can require that the type reference also implement other type classes (they call it inheritance, which it is after a fashion). The standard set of Haskell classes is: class Bounded a class Enum a class Eq a class (Fractional a) => Floating a class (Num a) => Fractional a class Functor f class (Real a, Enum a) => Integral a class Monad m class (Eq a, Show a, Eval a) => Num a class (Eq a) => Ord a class Read a class (Num a, Ord a) => Real a class (RealFrac a, Floating a) => RealFloat a class (Real a, Fractional a) => RealFrac a class Show a where => means "is required for". BTW, Haskell allows the programmer to use any sequence of symbol characters as operators, like +++ or <=|=>. And define their precedence and associativity. Salutaciones, JCAB
Jan 22 2002
This form could be a very good way of solving the problem for classes. But what the main purpose of operator overloading ? For me is defining new operations over simple types. The are not strong meaning doing : computer a, b, c; a = new computer(1,2); a = new computer(1,7); c = a + b; For example candidates could be Date and Time, Grades , Minutes, Seconds Celsius <-> Fahrenheit Meters <-> Foots Kilo, Pounds, etc... Matematic types like complex ( already added ) and so on Geometric types Matrix types , and etc How could this be done with interfaces. "OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a2k8u8$fao$1 digitaldaemon.com... Ok, so one more time about operator overloading... :) I read all the posts about operator overloading but I'm still a bit unsure about it...Do I want it, or don't I... I like about operator overloading the fact that you can add, subtract, compare or assign objects to one another much the same way as you can with normal primitive types. I hate some uses of operator overloading which seem really confusing to me. I always disliked the way cout and cin work. But maybe there is some middle ground? A compromise that could make everybody happy? Here is my idea: Think of Java, if you know it. It contains interfaces just like D. One of these interfaces is called Clonable. If you want your object to be copied to another, you implement Clonable. Now what if we could combine these kinds of interfaces with a form of predefined operator overloading. You would have a few predefined interfaces: IComparable, IAssignable, ISortable, IAddable, ISubtractable, IMultiplyable, IDividable...you get the idea. D would be able to check if an object implemented any of these interfaces and would automagically provide the suitable operators. I have already tried to implement something like this in C++ and I actually got IAssignable and IComparable to work, but when I tried to add more I got into trouble with multiple inheritance. Just a thought, but I think this might be a solution that would make everybody happy! P.S: There is another thread about templates which contains some sort of a variation on this: Constrained Genericity (template suggestion) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Jan 25 2002
Override Add(Object), and add an in-contract that the class be of type computer: class computer : IAddable { Object Add(Object other) in { assert(other.class == computer); } body { .... } } The compiler can optimize out the vast majority of cases, where it knows that the 2nd argument is of class computer. If you pass something else, it can alert user at compile time: "error: argument passed to computer.Add(Object) breaks in-contract." For the few cases where the compiler can't know ahead of time, you do a trivial runtime check and throw a BrokenContractException (or whatever) if needed. Juarez Rudsatz wrote:This form could be a very good way of solving the problem for classes. But what the main purpose of operator overloading ? For me is defining new operations over simple types. The are not strong meaning doing : computer a, b, c; a = new computer(1,2); a = new computer(1,7); c = a + b; How could this be done with interfaces.-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Jan 25 2002
"Juarez Rudsatz" <juarez correio.com> wrote in message news:a2rqhr$1oln$1 digitaldaemon.com...This form could be a very good way of solving the problem for classes. But what the main purpose of operator overloading ? For me is defining new operations over simple types. The are not strong meaning doing :It is not possible to overload operators for basic types, at least not in C++ or any other language I know.computer a, b, c; a = new computer(1,2); a = new computer(1,7); c = a + b;For example candidates could be Date and Time,Date and Time are usually implemented as doubles or something, so you can add and subtract them using normal operators. No need for overloading.Grades , Minutes, Seconds Celsius <-> Fahrenheit Meters <-> Foots Kilo, Pounds, etc...Same here, depending on the implementation, these are usually implemented as doubles or ints. No need to do any overloading, you can simply add them.Matematic types like complex ( already added ) and so onGeometric typesYou mean point etc? Define a class.Matrix typesYou wil need a class., and etc How could this be done with interfaces.Define a class, then implement the interfaces for the operator you need. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Jan 25 2002
"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a2san3$1spl$1 digitaldaemon.com...Unfortunately to provide an interface, you need a vtable. But most of the uses I find for operator overloading can't tolerate that kind of extra baggage. Vectors and Matrices, for example. A struct in D could work, but structs can't provide interfaces. I personally would be ok with operator overloading only being available for structs, not classes, but I'm not likely to get even that. ;( Maybe Walter will generalize the complex type enough that it can be turned into a useful 3 or 4 component vector. In 3d graphics we don't generally need double precision (though it could be useful in some situations). We can make arrays of 3 or 4 of those into matrices on our own, and I wouldn't mind having to use functions on just matrices. But vector math needs operator syntax in a bad way. If I can just get Walter to provide this type natively I'd be extremely happy (hopefully one of these days it could be optimized for SIMD processors too) type vector4 float& operator [0..3] float& .x , .y , .z , .w // these accessors would be nice vector4 operator + ( vector4,vector4 ) // add components vector4 operator - ( vector4,vector4 ) vector4 operator * ( vector4,vector4 ) vector4 operator * ( vector4,float ) vector4& operator += ( vector4 ) vector4& operator -= ( vector4 ) vector4& operator *= ( vector4 ) vector4& operator *= ( float ) float .length intrinsic float dot(vector4, vector4) But it'd probably be nice to have vector2 and vector3 also. int flavors could be nice too and could use probably 2,3,4, or 8 elements. Alot of processors have register types like this, but the nice thing about it is that it can all be emulated on the main FPU if necessary. It's pretty lightweight, I doubt it's hard to implement (no harder than the complex type, anyway) and people that don't need it can ignore it. People that do need it will be pleased. ;) SeanGeometric typesYou mean point etc? Define a class.Matrix typesYou wil need a class., and etc How could this be done with interfaces.Define a class, then implement the interfaces for the operator you need.-- Stijn
Jan 26 2002
"Sean L. Palmer" wrote:... Maybe Walter will generalize the complex type enough that it can be turned into a useful 3 or 4 component vector. In 3d graphics we don't generally need double precision (though it could be useful in some situations). We can make arrays of 3 or 4 of those into matrices on our own, and I wouldn't mind having to use functions on just matrices. But vector math needs operator syntax in a bad way. If I can just get Walter to provide this type natively I'd be extremely happy (hopefully one of these days it could be optimized for SIMD processors too) type vector4 float& operator [0..3] float& .x , .y , .z , .w // these accessors would be nice vector4 operator + ( vector4,vector4 ) // add components vector4 operator - ( vector4,vector4 ) vector4 operator * ( vector4,vector4 ) vector4 operator * ( vector4,float ) vector4& operator += ( vector4 ) vector4& operator -= ( vector4 ) vector4& operator *= ( vector4 ) vector4& operator *= ( float ) float .length intrinsic float dot(vector4, vector4) But it'd probably be nice to have vector2 and vector3 also. int flavors could be nice too and could use probably 2,3,4, or 8 elements. Alot of processors have register types like this, but the nice thing about it is that it can all be emulated on the main FPU if necessary. It's pretty lightweight, I doubt it's hard to implement (no harder than the complex type, anyway) and people that don't need it can ignore it. People that do need it will be pleased. ;) SeanI do lots of image processing (especially color space conversions and multispectral interpolations), and I presently make use of the free (as in Beer) Intel libraries. <drool> If D were to offer vectors as Sean proposes, then the possibility of obtaining screaming native language performance for image processing without the overhead of library calls would exist. </drool> Maybe as a future language extension? -BobC
Jan 26 2002
Sean L. Palmer wrote:"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a2san3$1spl$1 digitaldaemon.com... I personally would be ok with operator overloading only being available for structs, not classes, but I'm not likely to get even that. ;( Maybe Walter will generalize the complex type enough that it can be turned into a useful 3 or 4 component vector. In 3d graphics we don't generally need double precision (though it could be useful in some situations). We can make arrays of 3 or 4 of those into matrices on our own, and I wouldn't mind having to use functions on just matrices. But vector math needs operator syntax in a bad way.While my needs are the same as yours, and float 4-element vectors and float 4x4-element matrices would cover it, the astrophysicists will laugh at our puny 23-bit mantissas and ask where the hell the vectors of double and extended are. Apart from the SIMD issues, though, the fatter vectors should be mostly a cut-and-paste operation on Walter's part. I do agree that the vector that fits in the CPU's SIMD registers (4x32-bit float in most cases) is the most important one to offer, though. -Russell B
Jan 26 2002
I've been thinking a lot about operator overloading. 1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates. 2) Overloaded operator functions should be inlineable, which lets out interfaces. 3) I just don't like the idea of operator functions having hidden arguments: int operator+(int y); A binary operator function should, gosh darn it, have TWO operands: static int operator+(Foo x, int y); 4) I don't see a point to smart pointers and such in a garbage collected language. Overloadable operators should be restricted to arithmetic operators. 5) Operator overloading should only be used to provide arithmetic operations on user defined arithmetic types. None of that << and >> for iostreams. I know many people like that, but a shift is not a stream operation. It just isn't. 6) I see no way to have the compiler enforce (5). Anyone caught violating (5) should be forced to carry the Stone of Shame. 7) Note (3) means no virtual operator functions. To do that, you'd need: static int operator+(Foo x, int y) { return x.myadd(y); } so no great loss. 8) If there are to be conversion operators, they will not participate in implicit conversions, only explicit ones. None of this is implemented or specified yet, it's just some thoughts.
Feb 12 2002
Walter <walter digitalmars.com> wrote in message news:a4aril$ue9$2 digitaldaemon.com...I've been thinking a lot about operator overloading. 1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates.Why?2) Overloaded operator functions should be inlineable, which lets out interfaces.In the best of all worlds yes. But that is a limitation of the object paradigm, not operator notation. The fact is, without new operators, the user is going to be forced to perform the same operations with standard function calls anyhow. So functionally there is no substantive difference.3) I just don't like the idea of operator functions having hiddenarguments:int operator+(int y);I've never understood why this is a requirement. Use a dummy argument similar to "this" in such cases.4) I don't see a point to smart pointers and such in a garbage collected language. Overloadable operators should be restricted to arithmetic operators.I disagree. Restricting them would cause people to look for ways around the restrictions, and would also limit their usefulness in abstract logical systems.5) Operator overloading should only be used to provide arithmeticoperationson user defined arithmetic types. None of that << and >> for iostreams. I know many people like that, but a shift is not a stream operation. It just isn't.Shift operators are used for IO streams because there is no facility for creating new operators.with arbitrary names.8) If there are to be conversion operators, they will not participate in implicit conversions, only explicit ones.All converstions should be explicit anyhow. Implicit conversion promotes error.
Feb 12 2002
"Walter" <walter digitalmars.com> wrote in message news:a4aril$ue9$2 digitaldaemon.com...I've been thinking a lot about operator overloading. 1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates.I think that most people here would be happy to be able to overload just the built-in operators... adding custom ones is quite a lot of work, and the result doesn't worth it (IMO).3) I just don't like the idea of operator functions having hiddenarguments:int operator+(int y); A binary operator function should, gosh darn it, have TWO operands: static int operator+(Foo x, int y);Agreed. Operators should only be declared outside of classes.4) I don't see a point to smart pointers and such in a garbage collected language. Overloadable operators should be restricted to arithmetic operators.I suppose you mean binary + - * / & | ^ ~ and unary ++ -- ~ ! and all the op= operators? The question is, should logical operators be overloaded?5) Operator overloading should only be used to provide arithmeticoperationson user defined arithmetic types. None of that << and >> for iostreams. I know many people like that, but a shift is not a stream operation. It just isn't. 6) I see no way to have the compiler enforce (5). Anyone caught violating (5) should be forced to carry the Stone of Shame.Yep, right. There's no way to check how operators are used. Smart guys won't do that. Those who do... it's their problems =)7) Note (3) means no virtual operator functions. To do that, you'd need: static int operator+(Foo x, int y) { return x.myadd(y); } so no great loss.Absolutely.8) If there are to be conversion operators, they will not participate in implicit conversions, only explicit ones.Which really kills the idea. It's simplier to have the conversion function then, toInt()/toDouble()/toString() etc.None of this is implemented or specified yet, it's just some thoughts.<<< waiting patiently >>>
Feb 12 2002
Pavel Minayev wrote:I would like to see the compiler provide the remaining logical operators if only a few are defined. That is, if you define operator==(Foo,int); and operator<(Foo,int); (or any other combination of equality and inequality operators) the compiler should be able to provide the rest. Of course, it won't always be 100% optimized...but if it's not, you can provide the rest of the operators yourself. I just always hated having to have 4 extra useless functions just to define != <= >= and > for every class. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]4) I don't see a point to smart pointers and such in a garbage collected language. Overloadable operators should be restricted to arithmetic operators.I suppose you mean binary + - * / & | ^ ~ and unary ++ -- ~ ! and all the op= operators? The question is, should logical operators be overloaded?
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C690E8D.37852B1 deming-os.org...I meant && and ||.The question is, should logical operators be overloaded?I would like to see the compiler provide the remaining logical operatorsif onlya few are defined. That is, if you define operator==(Foo,int); and operator<(Foo,int); (or any other combination of equality and inequality operators) thecompilershould be able to provide the rest. Of course, it won't always be 100% optimized...but if it's not, you can provide the rest of the operators yourself. I just always hated having to have 4 extra useless functionsjust todefine != <= >= and > for every class.can supply them if you want, but if you don't, they are generated automatically from +, - and op.
Feb 12 2002
Pavel Minayev wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C690E8D.37852B1 deming-os.org...Oh :)I meant && and ||.The question is, should logical operators be overloaded?can supply them if you want, but if you don't, they are generated automatically from +, - and op.True. Many of the common operators can be generated from each other. I think that you should be able to supply just a few of them and have the complier automatically provide implementations for the rest. For instance, a-b can be redone as a+(-b), which in most cases is not the optimal solution performance-wise, but it allows rapid development of simple classes. You should be able to do it in many different ways, as well. Sometimes it's easiest to provide = and +, other times it's easiest (and often more efficient) to provide = and +=. The compiler should provide the missing operators if it can. Walter, I know that this means some extra complexity for you, but I would guess that it wouldn't be *too* bad. Each operator can have a library of available automatic implementations...depending on which operators are provided by the programmer, the compiler drops in pretty standard code for each. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C694E30.7FE96594 deming-os.org...True. Many of the common operators can be generated from each other. Ithinkthat you should be able to supply just a few of them and have the complier automatically provide implementations for the rest. For instance, a-b canberedone as a+(-b), which in most cases is not the optimal solution performance-wise, but it allows rapid development of simple classes.This might not be a good idea - not so obvious to many people =) It is clear that + can be used to implement += and ++. But a+(-b) just doesn't fit sometimes...
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C690E8D.37852B1 deming-os.org...I would like to see the compiler provide the remaining logical operatorsif onlya few are defined. That is, if you define operator==(Foo,int); and operator<(Foo,int); (or any other combination of equality and inequality operators) thecompilershould be able to provide the rest. Of course, it won't always be 100% optimized...but if it's not, you can provide the rest of the operators yourself. I just always hated having to have 4 extra useless functionsjust todefine != <= >= and > for every class.If just a cmp() was provided, that can be used for all the comparisons.
Feb 12 2002
"Walter" <walter digitalmars.com> wrote in message news:a4bm6j$1a5o$2 digitaldaemon.com...If just a cmp() was provided, that can be used for all the comparisons.Hmmm... operator cmp? enum Relation { Less, Equal, Greater } // builtin Relation operator cmp(vector a, vector b) { ... }
Feb 12 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a4bqaq$1buk$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a4bm6j$1a5o$2 digitaldaemon.com...No, it would return an int <0, 0, or >0. That makes it more efficiently implementable.If just a cmp() was provided, that can be used for all the comparisons.Hmmm... operator cmp? enum Relation { Less, Equal, Greater } // builtin Relation operator cmp(vector a, vector b) { ... }
Feb 13 2002
"Walter" <walter digitalmars.com> wrote in message news:a4d8gg$1ult$3 digitaldaemon.com...No, it would return an int <0, 0, or >0. That makes it more efficiently implementable.Either way, it'd make things simplier in many cases. Provide cmp, and other comparison ops are already there...
Feb 13 2002
Walter wrote:If just a cmp() was provided, that can be used for all the comparisons.True, but that is only for things that are reasonably ordered. Some things may have a property of equality/inequality but not ordering. In that case, you want to supply == and != but not < > <= >= Think (literally) apples and oranges :) -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C6979F9.D014E2C8 deming-os.org...True, but that is only for things that are reasonably ordered. Somethingsmay have a property of equality/inequality but not ordering. In thatcase,you want to supply == and != but not < > <= >=That's why I suggest the special "operator cmp".
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C6979F9.D014E2C8 deming-os.org...Walter wrote:thingsIf just a cmp() was provided, that can be used for all the comparisons.True, but that is only for things that are reasonably ordered. Somemay have a property of equality/inequality but not ordering. In thatcase,you want to supply == and != but not < > <= >= Think (literally) apples and oranges :)Object.cmp() exists already, and I figure just use that. And everyone knows that apples come before oranges <g>.
Feb 13 2002
"Walter" <walter digitalmars.com> wrote in message news:a4d8gh$1ult$4 digitaldaemon.com...Object.cmp() exists already, and I figure just use that. And everyoneknowsthat apples come before oranges <g>.You mean that operators can only be overloaded for Objects? Not even structs?
Feb 13 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C690E8D.37852B1 deming-os.org...Pavel Minayev wrote:collected4) I don't see a point to smart pointers and such in a garbageif onlyI would like to see the compiler provide the remaining logical operatorslanguage. Overloadable operators should be restricted to arithmetic operators.I suppose you mean binary + - * / & | ^ ~ and unary ++ -- ~ ! and all the op= operators? The question is, should logical operators be overloaded?a few are defined. That is, if you define operator==(Foo,int); and operator<(Foo,int); (or any other combination of equality and inequality operators) thecompilershould be able to provide the rest. Of course, it won't always be 100% optimized...but if it's not, you can provide the rest of the operators yourself. I just always hated having to have 4 extra useless functionsjust todefine != <= >= and > for every class.YES!!! GOD, YES!! Sean
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> ha scritto nel messaggio news:3C690E8D.37852B1 deming-os.org...Pavel Minayev wrote:collected4) I don't see a point to smart pointers and such in a garbageif onlyI would like to see the compiler provide the remaining logical operatorslanguage. Overloadable operators should be restricted to arithmetic operators.I suppose you mean binary + - * / & | ^ ~ and unary ++ -- ~ ! and all the op= operators? The question is, should logical operators be overloaded?a few are defined. That is, if you define operator==(Foo,int); and operator<(Foo,int); (or any other combination of equality and inequality operators) thecompilershould be able to provide the rest. Of course, it won't always be 100% optimized...but if it's not, you can provide the rest of the operators yourself. I just always hated having to have 4 extra useless functionsjust todefine != <= >= and > for every class.In my classes I often use as example the operator <= (_the_ order operator for mathematics): all other comparisons can be made with this (if the order is total). In C++: bool operator <=(MyClass a, MyClass b) { ... implement this } // theese are "automatic" inline bool operator == (MyClass a, MyClass b) { return (a <= b) && (b <= a); } inline bool operator < (MyClass a, MyClass b) { return (a <= b) && !(a == b); } // theese are simplicistic inline bool operator != (MyClass a, MyClass b) { return !(a == b); } inline bool operator > (MyClass a, MyClass b) { return !(a <= b); } inline bool operator >= (MyClass a, MyClass b) { return !(a < b); } OK, this work if the order is total, so (a<=b) && (b <= a) implies a == b . Ciao
Feb 13 2002
Hmmm....D beat me to the punch. But there's a chance for intelligent conversation yet! Walter wrote:I've been thinking a lot about operator overloading. 1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates.Are you suggesting that a special operator (like :+:) would always be associated with the related operator function operator+ ? While I personally like having the same operators, I think this might be an excellent balance...it makes it clear that the operator is not a compiler operator, but it allows an inline syntax. We still have to deal with the issues of things like dot-product vs. cross-product in vectors. What if we used the same syntax for inline function names? Basically, if you defined a function name with 2 arguments, you could call it as func(arg1,arg2) or arg1 :func: arg2. Similarly, for those for whom a trailing unary operator is useful (like factorial), you could call a single-function argument with similary syntax arg :unary-func: Each of these syntaxes would be EXACTLY equivalent to the old C function call syntax, func(arg1,arg2) and unary-func(arg), respectively. class Vector { static Vector cp(Vector a,Vector b); static double dp(Vector a,Vector b); } long fact(int i); Vector foo,bar; ... double d = a :dp: b; Vector baz = a :cp: b; long fred = 6 :fact: ; It's not pretty, but it allows an inline syntax of a sort without allowing wild creation of unlimited functions.2) Overloaded operator functions should be inlineable, which lets out interfaces.I'm uncomfortable about this (losing interfaces) in general, but I'm not totally sure why. I would desire some more details about why interfaces get in the way.3) I just don't like the idea of operator functions having hidden arguments: int operator+(int y); A binary operator function should, gosh darn it, have TWO operands: static int operator+(Foo x, int y);It would sure make overloading the other way around (int + Foo) easier.5) Operator overloading should only be used to provide arithmetic operations on user defined arithmetic types. None of that << and >> for iostreams. I know many people like that, but a shift is not a stream operation. It just isn't.No reason that ALL operators have to be overridable right now. You could stick to the basic operators and add support for stuff like << and >> if people show great desire to use them.8) If there are to be conversion operators, they will not participate in implicit conversions, only explicit ones.I agree :) -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C690DAF.995AB2CB deming-os.org...associated1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates.Are you suggesting that a special operator (like :+:) would always bewith the related operator function operator+ ? While I personally like having the same operators, I think this might be an excellent balance...itmakesit clear that the operator is not a compiler operator, but it allows aninlinesyntax.The trouble is you couldn't write a template that could be instantiated for both builtin types and user defined types.We still have to deal with the issues of things like dot-product vs. cross-product in vectors. What if we used the same syntax for inlinefunctionnames? Basically, if you defined a function name with 2 arguments, youcouldcall it as func(arg1,arg2) or arg1 :func: arg2. Similarly, for thoseforwhom a trailing unary operator is useful (like factorial), you could callasingle-function argument with similary syntax arg :unary-func: Eachofthese syntaxes would be EXACTLY equivalent to the old C function callsyntax,func(arg1,arg2) and unary-func(arg), respectively. class Vector { static Vector cp(Vector a,Vector b); static double dp(Vector a,Vector b); } long fact(int i); Vector foo,bar; ... double d = a :dp: b; Vector baz = a :cp: b; long fred = 6 :fact: ; It's not pretty, but it allows an inline syntax of a sort without allowingwildcreation of unlimited functions.Perhaps this could be in a future version of D, but let's defer that for now.totally2) Overloaded operator functions should be inlineable, which lets out interfaces.I'm uncomfortable about this (losing interfaces) in general, but I'm notsure why. I would desire some more details about why interfaces get inthe way. I just don't see any advantage to using interfaces for this, and an interface requires a vptr.
Feb 12 2002
Walter wrote:The trouble is you couldn't write a template that could be instantiated for both builtin types and user defined types.You could simply define that for built-in types :+: is exactly equivalent to + Or am I missing the point here?Perhaps this could be in a future version of D, but let's defer that for now.ok. It's nice to think that the language isn't static, and that we have the time to slowly learn what the truly useful features are! :) -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 12 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C697B1B.1B10E356 deming-os.org...You could simply define that for built-in types :+: is exactly equivalentto+ Or am I missing the point here?What about the ":+-*/:" operator, then? =)
Feb 12 2002
"Pavel Minayev" <evilone omen.ru> ha scritto nel messaggio news:a4c0oi$1efk$1 digitaldaemon.com..."Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C697B1B.1B10E356 deming-os.org...equivalentYou could simply define that for built-in types :+: is exactlytoI think you're missing the point. They are talking about needing a lexical sign when using an overloaded operator. So, in this view, every operator can be overloaded, but you must write something like :operator: (or something else) to state lexically that you are using an overloaded operator. No new operators can be "created" on the fly in this schema. Ciao+ Or am I missing the point here?What about the ":+-*/:" operator, then? =)
Feb 13 2002
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:a4do8b$279j$1 digitaldaemon.com...I think you're missing the point. They are talking about needing a lexical sign when using an overloaded operator. So, in this view, every operator can be overloaded, but you must write something like :operator: (or something else) to state lexically that you are using an overloaded operator. No new operators can be "created" on the fly in this schema.Then I don't see much reason in adding something to state an overloaded operator explicitly. In most cases, I don't really care. I use + to add vectors just as I would add ints, and I'm pretty happy with that. If it is built-in, fine. If it is provided by some module, I should be able to use it as if it was built-in. Just my POV...
Feb 13 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a4dutu$2avp$1 digitaldaemon.com..."Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:a4do8b$279j$1 digitaldaemon.com...lexicalI think you're missing the point. They are talking about needing astatesign when using an overloaded operator. So, in this view, every operator can be overloaded, but you must write something like :operator: (or something else) toTotally agreed. If the lexical sign was standard, like it was *always* :op:, I could live with it. I wouldn't like it however, it just looks confusing.lexically that you are using an overloaded operator. No new operators can be "created" on the fly in this schema.Then I don't see much reason in adding something to state an overloaded operator explicitly. In most cases, I don't really care. I use + to add vectors just as I would add ints, and I'm pretty happy with that. If it is built-in, fine. If it is provided by some module, I should be able to use it as if it was built-in. Just my POV...
Feb 16 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C697B1B.1B10E356 deming-os.org...Walter wrote:forThe trouble is you couldn't write a template that could be instantiatedtoboth builtin types and user defined types.You could simply define that for built-in types :+: is exactly equivalent+ Or am I missing the point here?thePerhaps this could be in a future version of D, but let's defer that for now.ok. It's nice to think that the language isn't static, and that we havetime to slowly learn what the truly useful features are! :)If there are too many features, we're back in the same boat as C++!
Feb 12 2002
Walter wrote:If there are too many features, we're back in the same boat as C++!Umm, we could go straight for "D++", couldn't we? (And no, I'm under no illusions of who "we" refers to.) -BobC
Feb 12 2002
"Walter" <walter digitalmars.com> wrote in message news:a4aril$ue9$2 digitaldaemon.com...I've been thinking a lot about operator overloading. 1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates.Right. One of the beauties of templates is being able to write T a = b + c; when you don't even know what class b and c are, so long as it provides operator = and operator +, it'll compile.2) Overloaded operator functions should be inlineable, which lets out interfaces.Right. When you need operator overloading you usually can't afford a virtual function call.3) I just don't like the idea of operator functions having hiddenarguments:int operator+(int y); A binary operator function should, gosh darn it, have TWO operands: static int operator+(Foo x, int y);I agree. It should be explicit. I also can't see why you shouldn't be able to override operators using only basic types. So what if I want to implement <<= for floats? Let me.4) I don't see a point to smart pointers and such in a garbage collected language. Overloadable operators should be restricted to arithmetic operators.With smart pointers it's not just about refcounting... You can also restrict the pointer from being incremented or changed (prevents bugs when returning a pointer to just one thing, such as a global singleton). You can use them as accessors (if you want to talk to object X, you have to get a lock first... so obtaining one of these XAccessor objects which are smart pointers into X, automatically locks the X, and is the only way for outside code to use X, since all its methods are private to everything but the XAccessor, which forwards calls to it).5) Operator overloading should only be used to provide arithmeticoperationson user defined arithmetic types. None of that << and >> for iostreams. I know many people like that, but a shift is not a stream operation. It just isn't.I could live with that.6) I see no way to have the compiler enforce (5). Anyone caught violating (5) should be forced to carry the Stone of Shame. 7) Note (3) means no virtual operator functions. To do that, you'd need: static int operator+(Foo x, int y) { return x.myadd(y); } so no great loss. 8) If there are to be conversion operators, they will not participate in implicit conversions, only explicit ones.Also tolerable.None of this is implemented or specified yet, it's just some thoughts.Glad to see you're thinking about it. Sean
Feb 12 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a4bq9a$1buc$1 digitaldaemon.com...With smart pointers it's not just about refcounting... You can alsorestrictthe pointer from being incremented or changed (prevents bugs whenreturninga pointer to just one thing, such as a global singleton). You can usethemas accessors (if you want to talk to object X, you have to get a lock first... so obtaining one of these XAccessor objects which are smart pointers into X, automatically locks the X, and is the only way foroutsidecode to use X, since all its methods are private to everything but the XAccessor, which forwards calls to it).Oh yes, and there are also iterators - kinda pointers as well =)With operator overloading and templates, D would easily beat bothNone of this is implemented or specified yet, it's just some thoughts.Glad to see you're thinking about it.
Feb 12 2002
Walter wrote:I've been thinking a lot about operator overloading. 1) The idea of 'special' operators for overloading, like :+: being the overloadable version of +, is a good idea, but it fails when used with templates. 2) Overloaded operator functions should be inlineable, which lets out interfaces. 3) I just don't like the idea of operator functions having hidden arguments: int operator+(int y); A binary operator function should, gosh darn it, have TWO operands: static int operator+(Foo x, int y);I prefer declaring a new or overloaded operator to EXACTLY resemble a function declaration. Where, buy default, most functions are "prefix" (the function name comes first, followed by arguments), operators can be infix (function name between arguments, arguments limited to exactly two) or even postfix (function name follows all arguments). Let's allow for the whole gamut! M4 is smart enough to handle such notation, and I've used it with several languages where I was desperate to use non-prefix function call notations. In the following, please excuse my use of caps and long names: I do not advocate their use as-is, but I want to make it clear what I'm doing. So, given the following: int foo( int, int) {...}; and int x = foo(1,2); We could easily have: INFIX_OPERATOR int foo(IN int, IN int) {...}; and x = 1 foo 2; Or even this: INFIX_OPERATOR myType +(IN myType, IN myType) {...}; and myType x, y, z; ... x = y + z; IMO, the context makes the intent clear and easily parseable. Now, let's talk about our favorite C feature, assignment operators. Can we declare those as well? Let's try: ASSIGNMENT_OPERATOR myType +=(IN OUT myType, IN myType) {...}; The ASSIGNMENT_OPERATOR is similar to INFIX_OPERATOR, except that the first parameter must be an IN OUT parameter. This notation would also allow: myType a, b, c, d; d += a += c += b; Yes, of course, assignments are valid on the right hand side. To preclude this behavior, you'd need to define the function as returning void. Then the above statement would issue a type error for all assignments before the last one. (Strange, but true...) I see no need for any explicit "overload" notation. If someone decides to re-define integer addition, then the compiler should issue a warning ("Built-in operator being redefined."), but then let things proceed. If turning off all implicit conversion is required when this feature is used, so be it: Caveat Emptor! I, for one, would IMMEDIATELY use this feature to implement the "smart integer" features (similar to having NAN in D's floats) I was seeking in a long ago thread. This notation should also be "template safe", for quite a large set of ways to define templates. Should we discuss templates next?4) I don't see a point to smart pointers and such in a garbage collected language. Overloadable operators should be restricted to arithmetic operators.No, why not let it all hang out? Let the compiler spew warning ad nauseum. But don't deny us the power to royally screw things up!5) Operator overloading should only be used to provide arithmetic operations on user defined arithmetic types. None of that << and >> for iostreams. I know many people like that, but a shift is not a stream operation. It just isn't.My prior comment applies!6) I see no way to have the compiler enforce (5). Anyone caught violating (5) should be forced to carry the Stone of Shame.No, they should be forced to endure "The Constant Stream Of Compiler Whining And Complaining". Sort of like what "gcc -Wall" does to my code... ;^)7) Note (3) means no virtual operator functions. To do that, you'd need: static int operator+(Foo x, int y) { return x.myadd(y); } so no great loss.I think my proposed8) If there are to be conversion operators, they will not participate in implicit conversions, only explicit ones.Agreed! The price for such power should be to force the user to be extremely explicit about what they are doing. Once you overload a predefined operator, the compiler should do no additional favors for you. Other than complain, of course!None of this is implemented or specified yet, it's just some thoughts.And very good ones. I do NOT believe any such features of D need to be "efficient" or "optimizable". If they are, that would be great. All I ask is that they be "possible". -BobC
Feb 12 2002
Operatoror overloading is an error gnashing at the bit to happen. There is <NO> valid justification for providing it. There are arguments, but they are ALL invalid, because code reliability must trump programming convenience. The problem with operator overloading is that it can be highly confusing. What Isn't highly confusing however, and what does provide the same benefit is providing the ability to create your own operators. Existing operators have limited usefulness, even for simple vector operations where there are two types of product. What existing two operators are you going to redefine for them? Operator Overloading is very, very bad news. OddesE <OddesE_XYZ hotmail.com> wrote in message news:a2k8u8$fao$1 digitaldaemon.com...Ok, so one more time about operator overloading... :) I read all the posts about operator overloading but I'm still a bit unsure about it...Do I want it, or don't I... I like about operator overloading the fact that you can add, subtract, compare or assign objects to one another much the same way as you can with normal primitive types. I hate some uses of operator overloading which seem really confusing to me. I always disliked the way cout and cin work.
Feb 04 2002
Your first paragraph shows you to be closed minded. By that argument, pointers must be removed from the language, as well as anything that can be remotely dangerous such as typecasting. By the time you're done you won't have much of a language left. I bet you have problems figuring out what happens when you add a char to a float and then add the result to an int. The behavior of the operator is governed by the types operated upon and the type conversion rules of the language. It gets a little more complex with operator overloading on user types, but not to the point of unusability. I'm not in favor of stripping away language utility to make up for the deficiencies of the lowest common denominator programmer. Your entire argument is founded on that. At least people can be trained proper coding technique. But it's difficult to add functionality to your compiler in most cases (GCC at least allows it, but still not easy). So removing functionality is just going to cause language holes to exist that will give people great big excuses to use a language that has all the functionality they need, even if that language is C++ and allows you to shoot yourself in the foot. The main problem with operator overloading is that people don't bother to look up the declaration of the variables they're dealing with. For this I blame hacks like Hungarian notation. I'm sure it's something that a strong IDE with one-button or tooltip browse info could solve nicely. In any case, I expect people on my team to verify that their code works before checking it in. If you get operator overloading wrong, you'll notice as soon as you run it because the behavior won't be what you expected. (try to assign the result of a dot product to a vector, or the result of a cross product to a float, and you'll get a type mismatch of some kind at compile time) Sean "D" <s_nudds hotmail.com> wrote in message news:a3liu5$ruq$1 digitaldaemon.com...Operatoror overloading is an error gnashing at the bit to happen. There is<NO> valid justification for providing it. There are arguments, but they are ALL invalid, because code reliability must trump programming convenience. The problem with operator overloading is that it can be highly confusing. What Isn't highly confusing however, and what does provide the samebenefitis providing the ability to create your own operators. Existing operators have limited usefulness, even for simple vector operations where there are two types of product. What existing two operators are you going to redefine for them?
Feb 04 2002
Sean L. Palmer writes:Your first paragraph shows you to be closed minded. By that argument, pointers must be removed from the language, as well as anything that canberemotely dangerous such as typecasting. By the time you're done you won't have much of a language left.Pointers have their place because they improve efficiency. Operator overloading provides no such advantage. It is simply a convenience feature for a minute number of situations that in most situations is abused thereby reducing code quality and maintainance. Defining new operators however is a different story. New operators can provide the same utility as existing ones without the associated problems of precidence and predefined meaning that limits the usefulness of the C/C++ implemntation. Members of the C religion like to argue that their God is the only God. When they accuse me of having a closed mind, I laugh. Sean L. Palmer writes:I bet you have problems figuring out what happens when you add a char to a float and then add the result to an int.I do, because in crap languages like C/C++ the sign of char is not defined in the standard, the Char may be signed or unsigned and which is left up to the compiler. What is also wrong with C/C++ is that char is considered numeric at all. That is the height of stupidity. Rather characters should be relegated to characters, an only available as numbers if they are explicity cast as such. Members of the C faith will whine. Let them whine. Sean L. Palmer writes:I'm not in favor of stripping away language utility to make up for the deficiencies of the lowest common denominator programmer.Clearly you do favour such a thing, since if you did not then youi would be programmig in assembler where you can create what you wish, when you wish. With assembler you have absolute freedom. So by selecting any HLL or MLL you have already decided to make a tradeoff. Your whine therefore has no significance, other than to show a reluctance to accept reason. Sean L. Palmer writes:At least people can be trained proper coding technique. But it's difficult to add functionality to your compiler inmostcases (GCC at least allows it, but still not easy). So removing functionality is just going to cause language holes to exist that willgivepeople great big excuses to use a language that has all the functionality they need, even if that language is C++ and allows you to shoot yourselfinthe foot.No. Language holes exist as a result of features that can not be completely implemented due to compiler constraints, or compile time requirements. Just as not every mathematical function has an easily computable inverse, not every design characteristic of a language can be fully implemented in concept across the language. Those areas where the implementation becomes difficult are the areas where there are holes in the language. One of the holes in the C language is the foolish method chosen to implement autoincrement, and the restrictions placed on the use of the operation in complex equations. Rather than have the compiler spend the time to properly implement the function, the morons who invented the C language (may they eternally burn in hell), decided to place the onus on the programmer to use the feature "properly". I.E. to use the feature in a manner in which the compiler doesn't fail. Sean L. Palmer writes:The main problem with operator overloading is that people don't bother to look up the declaration of the variables they're dealing with.Wrong. The main problem with operator overloading is that the given meanings of the exiting operators do not lend themselves to the operations that typically need to be performed. This results in programmers doing things like using the division operator to compare strings, and stupid things like that. Sean L. Palmer writes:In any case, I expect people on my team to verify that their code works before checking it in. If you get operator overloading wrong, you'llnoticeas soon as you run it because the behavior won't be what you expected.(tryto assign the result of a dot product to a vector, or the result of acrossproduct to a float, and you'll get a type mismatch of some kind at compile time)There are two kinds of product for vectors. Which of the two existing operators are you going to use to specify them?
Feb 04 2002
"D" <s_nudds hotmail.com> wrote in message news:a3nl7n$2ao0$1 digitaldaemon.com...Sean L. Palmer writes:won'tYour first paragraph shows you to be closed minded. By that argument, pointers must be removed from the language, as well as anything that canberemotely dangerous such as typecasting. By the time you're done youfeaturehave much of a language left.Pointers have their place because they improve efficiency. Operator overloading provides no such advantage. It is simply a conveniencefor a minute number of situations that in most situations is abusedtherebyreducing code quality and maintainance. Defining new operators however is a different story. New operators can provide the same utility as existing ones without the associated problemsofprecidence and predefined meaning that limits the usefulness of the C/C++ implemntation. Members of the C religion like to argue that their God is the only God. When they accuse me of having a closed mind, I laugh. Sean L. Palmer writes:aI bet you have problems figuring out what happens when you add a char totofloat and then add the result to an int.I do, because in crap languages like C/C++ the sign of char is not defined in the standard, the Char may be signed or unsigned and which is left upthe compiler. What is also wrong with C/C++ is that char is considered numeric at all. That is the height of stupidity. Rather characters should be relegated to characters, an only available as numbers if they are explicity cast assuch.Members of the C faith will whine. Let them whine. Sean L. Palmer writes:beI'm not in favor of stripping away language utility to make up for the deficiencies of the lowest common denominator programmer.Clearly you do favour such a thing, since if you did not then youi wouldprogrammig in assembler where you can create what you wish, when you wish. With assembler you have absolute freedom. So by selecting any HLL or MLL you have already decided to make atradeoff.Your whine therefore has no significance, other than to show a reluctancetoaccept reason. Sean L. Palmer writes:functionalityAt least people can be trained proper coding technique. But it's difficult to add functionality to your compiler inmostcases (GCC at least allows it, but still not easy). So removing functionality is just going to cause language holes to exist that willgivepeople great big excuses to use a language that has all thecompletelythey need, even if that language is C++ and allows you to shoot yourselfinthe foot.No. Language holes exist as a result of features that can not beimplemented due to compiler constraints, or compile time requirements. Just as not every mathematical function has an easily computable inverse, not every design characteristic of a language can be fully implemented in concept across the language. Those areas where the implementation becomes difficult are the areas where there are holes in the language. One of the holes in the C language is the foolish method chosen toimplementautoincrement, and the restrictions placed on the use of the operation in complex equations. Rather than have the compiler spend the time to properly implement the function, the morons who invented the C language(maythey eternally burn in hell), decided to place the onus on the programmertouse the feature "properly". I.E. to use the feature in a manner in which the compiler doesn't fail. Sean L. Palmer writes: > The main problem with operator overloading is that people don't bothertocompilelook up the declaration of the variables they're dealing with.Wrong. The main problem with operator overloading is that the given meanings of the exiting operators do not lend themselves to the operations that typically need to be performed. This results in programmers doing things like using the division operator to compare strings, and stupid things like that. Sean L. Palmer writes:In any case, I expect people on my team to verify that their code works before checking it in. If you get operator overloading wrong, you'llnoticeas soon as you run it because the behavior won't be what you expected.(tryto assign the result of a dot product to a vector, or the result of acrossproduct to a float, and you'll get a type mismatch of some kind atThe one you use most. The other you use a named function for. Without operator overloading you will always have to use a named function to describe mathematical operations. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mailtime)There are two kinds of product for vectors. Which of the two existing operators are you going to use to specify them?
Feb 05 2002
Re: What ops to use for operator overloading for cross and dot products. OddesE <OddesE_XYZ hotmail.com> wrote in message news:a3pf92$4ul$1 digitaldaemon.com...The one you use most. The other you use a named function for. Without operator overloading you will always have to use a named function to describe mathematical operations.Translation.... Operator overloading as provided by C++ is inadequate for even simple vector operations, which was it's primary reason for existance. I rest my case. Operator overloading is essentially useless. Allowing the programmer to define their own operators on the other hand is a valuable addition to a language.
Feb 06 2002
"D" <s_nudds hotmail.com> wrote in message news:a3qtmm$2694$1 digitaldaemon.com...I rest my case. Operator overloading is essentially useless. Allowing the programmer to define their own operators on the other hand isavaluable addition to a language.You are the only one in the group who has such an opinion. All others either don't use operator overloading at all, or want to be able to overload standard operators. Seems like you're outnumbered here, and since we have representatives from many areas of IT here, I guess it's an answer to a logical question, "What do you prefer", apllied to the entire target audience of D. Your arguments are not conceiving - noone had changed his mind. I believe the discussion is closed here. I'm out, at least. Period.
Feb 06 2002
Paul, left to themselves members of the C religion would change nothing, because they are sheep who generally don't know any better. There are a plethora of langauges that resemble C, and each have been created to appeal to the irrational and inferior dictates of the C religionists. If the author of D wishes to make the same mistakes as all of the others, and as a result have his langauge relegated to the same disgarded heap, that is his choice. I don't recommend following in the footsteps of abject failure. Why do you? Pavel Minayev <evilone omen.ru> wrote in message news:a3r4l9$2993$1 digitaldaemon.com...You are the only one in the group who has such an opinion. All others either don't use operator overloading at all, or want to be able to overload standard operators. Seems like you're outnumbered here, and since we have representatives from many areas of IT here, I guess it's an answer to a logical question, "What do you prefer", apllied to the entire target audience of D. Your arguments are not conceiving - noone had changed his mind. I believe the discussion is closed here. I'm out, at least. Period.
Feb 07 2002
D wrote:Operatoror overloading is an error gnashing at the bit to happen. There is <NO> valid justification for providing it. There are arguments, but they are ALL invalid, because code reliability must trump programming convenience.(please excuse my slight flamishness coming...) In a well controlled, well designed situation, programming convenience OFTEN LEADS TO CODE RELIABILITY. When the code is easy to write and read, and most importantly WHEN IT DOES WHAT IT SEEMS LIKE IT DOES, the two are one and the same. This whole idea that operator overloading = code confusion is vaporous. What operator overloading is a convenient shortcut into a certain function syntax. You could argue that "function naming is a bug-prone feature" because a programmer can write a function named one thing that does another. IT IS THE RESPONSIBILITY OF THE CODE REVIEWERS, IN CONSULTATION WITH THE ORIGINAL PROGRAMMER, TO ENSURE GOOD CODE DESIGN. Don't leave out an incredibly useful feature just because some people misuse it. If it's hard to implement in the compiler, I can understand that - we want a small, reliable compiler. But if it's easy to implement and we're not doing it out of some desire to "protect the user from himself"...well, I didn't become a programmer because I was content with what was "safe and easy." -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Feb 04 2002
Russ Lewis writes:In a well controlled, well designed situation, programming convenienceOFTENLEADS TO CODE RELIABILITY. When the code is easy to write and read, and most importantly WHEN IT DOES WHAT IT SEEMS LIKE IT DOES, the two are one and the same.I agree. But well controlled, well designed situations <rarely> occur. So operator overloading <rarely> improves code reliability and clarity. Operator overloading is inferior in every respect to the ability to provide new operators. Providing new operators provides all of the benefits, and allows the programmer to avoid all of the pitfalls. I wouild make one exception. Equality. Equality can at all times be taken to be byte by byte identical. for comparison, and byte by byte assignment for assignment.
Feb 04 2002
I wouild make one exception. Equality. Equality can at all times be taken to be byte by byte identical. for comparison, and byte by byte assignment for assignment.According to IEEE 754, -0.0 == +0.0, but have different binary representation.
Feb 05 2002
Serge K wrote:Just an anecdote, but I've run into a compiler that evaluated (-0.0 == +0.0) as false. I discovered this while porting code from a compiler that evaluated it as true. Let me tell you, that was a fun one, especially since the the only manifestation was "some of the rotating objects in the world rotate around the wrong axis." -Russell BI wouild make one exception. Equality. Equality can at all times be taken to be byte by byte identical. for comparison, and byte by byte assignment for assignment.According to IEEE 754, -0.0 == +0.0, but have different binary representation.
Feb 05 2002
"Serge K" <skarebo programmer.net> ha scritto nel messaggio news:a3ql6l$21ts$1 digitaldaemon.com...takenI wouild make one exception. Equality. Equality can at all times beassignmentto be byte by byte identical. for comparison, and byte by byteAnt it's not the only example. CaseInsensitiveString s = "CIAO", t = "ciao"; if (s == t) ...for assignment.According to IEEE 754, -0.0 == +0.0, but have different binary representation.
Feb 06 2002
What the hell is a case insensitive string. Now that is a dum idea. Case insensitive comparison. That is a smart idea. In any case, If there was such a thing as a case insensitive string, then make an exception. I fail to see the difficulty. By the way Roberto. if a case insensitive string is printed, is it printed in upper or lower case? Also Robert, you can create a case insensitive string simply by changing the case to all upper or all lower during the load. Since the case is insensitive, altering the case during the load is not relevant is it? Roberto Mariottini <rmariottini lycosmail.com> wrote in message news:a3qtn7$2697$1 digitaldaemon.com..."Serge K" <skarebo programmer.net> ha scritto nel messaggio news:a3ql6l$21ts$1 digitaldaemon.com...takenI wouild make one exception. Equality. Equality can at all times beassignmentto be byte by byte identical. for comparison, and byte by byteAnt it's not the only example. CaseInsensitiveString s = "CIAO", t = "ciao"; if (s == t) ...for assignment.According to IEEE 754, -0.0 == +0.0, but have different binary representation.
Feb 07 2002
"D" <s_nudds hotmail.com> ha scritto nel messaggio news:a3tvf5$r6f$1 digitaldaemon.com...What the hell is a case insensitive string. Now that is a dum idea. Case insensitive comparison. That is a smart idea.I think they are all good ideas.In any case, If there was such a thing as a case insensitive string, then make an exception. I fail to see the difficulty.An exception is OK, if it's an exception. If it becomes a rule (i.e. there are other examples than CIString) then we must handle it somehow.By the way Roberto. if a case insensitive string is printed, is it printed in upper or lower case? Also Robert, you can create a case insensitive string simply by changingthecase to all upper or all lower during the load. Since the case is insensitive, altering the case during the load is not relevant is it?I'm thinking of Windows file names: they are case insensitive, but they preserve case. So, if an user wants to open "myfile.txt", but the system find "MyFile.txt", the open should be successful. On the other hand, when the file is opened, it is shown as "MyFile.txt" as it actually is. Ciao
Feb 07 2002
"D" <s_nudds hotmail.com> ha scritto nel messaggio news:a3tvf5$r6f$1 digitaldaemon.com...CaseWhat the hell is a case insensitive string. Now that is a dum idea.Roberto Mariottini writes:insensitive comparison. That is a smart idea.I think they are all good ideas.Clearly not. Case insensitive strings provide no advantage.printedBy the way Roberto. if a case insensitive string is printed, is itRoberto Mariottini writes:in upper or lower case? Also Robert, you can create a case insensitive string simply by changingthecase to all upper or all lower during the load. Since the case is insensitive, altering the case during the load is not relevant is it?I'm thinking of Windows file names: they are case insensitive, but they preserve case.I am well aware of case insensitity. Case sensitivity is one of the major failings of C and Unix in general. WORDS DO NOT CHANGE THEIR MEANING IF THEIR CASE CHANGES. Hence labels should not change their meaning either. D should be case insensitive. Case insensitivity is best performed through a case insensitive compare function, or through conveting the source and target strings to a common case before a typical case sensitive conversion. Now before someone blathers that such conversions are ineffiicent, the truth of the matter is that there is no difference in computational efficiency since with a case insensitive string, ultimately both the source and destination will need to be converted to a common case internally on a character by character basis during the comparison. Case insensitive strings would also require the inclusion of an additional string functions in the default library for every string operation where case differences must be ignored, thus increasing the minimal footprint for the resulting programs. The only advantage a native case insensitive string type has over a normal string type is that a case insensitive string will carry with it a flag that indicates that it is case insensitive. I admit that carrying such a flag is convenient. However, as long as we are carrying a single flag along with the string, there is no additional cost to us for carrying a generalized flag variable along with the string. A single byte can contain 8 or 16, general purpose flags, or be used for other identification purposes. One could use the register as an integer for the storage of an offset into the string, or an object reference, or anything else the programmer desires. So, it is clear that if case insensitivity is seen as important, a general purpose integer typed tag be associated with each string instead.
Feb 09 2002
"D" <s_nudds hotmail.com> wrote in message news:a3tvf5$r6f$1 digitaldaemon.com...What the hell is a case insensitive string. Now that is a dum idea.That'll be in your opinion, sir! Man, you've got to learn to control your wording, or else we're going to have a problem.Case insensitive comparison. That is a smart idea.I use case insensitive strings every day. They are not dumb. A case insensitice string is one that compares with disregard to case. So that, if "istring" is a case insensitive string, istring s1 = "D is better than C"; istring s2 = "D IS BETTER THAN C"; s1 == s2; // this is true. I agree that case-insensitivity is normally related to the comparisons themselves, not to the strings. But sometimes, it is a property of the strings. I use them in Win32 especially because I have a special string class that holds path names (call it pathname). And in Win32, path names are always case-insensitive. I see that as a property of the path as a whole, not of the comparisons applied to it. Makes for cleaner code in the end, because I don't need to remember that paths need different comparison functions.In any case, If there was such a thing as a case insensitive string, then make an exception. I fail to see the difficulty.The difficulty is that, if every time it makes sense to make an exception you need to modify the language, the language gets bloated. It's best to be able to define extensions externally. In my opinion! ;-)By the way Roberto. if a case insensitive string is printed, is it printed in upper or lower case? Also Robert, you can create a case insensitive string simply by changingthecase to all upper or all lower during the load. Since the case is insensitive, altering the case during the load is not relevant is it?:) That's the dark side of case insensitive strings. Personally, I use the Windows file system way: case is stored as given, but comparisons don't use it. It's the same as ignoring part of a structure in its comparison operators. It does make for some awkward situations, I'll grant you that. Salutaciones, JCAB
Feb 08 2002
As I recognized, case insensitivity is indeed a good thing. A native type case insensensitive string is not. As you indicate in those instances where they are convenient, they can be created by defining a new type. Good programming languages do not have holes. Questions do not arrise as to how a specific situation will be handled. Good programming languages follow a design philosophy which indicate the path taken when or more logical options are available. That is language consistancy. Case invariant strings raise too many questions as to how specific instances will be handled. They increase the minimum footprint of the language. To be implemented properly an insensitivity flag must be stored along with the string, and if that is to be the case, on a cost/benefit basis it is better to break out the insensitivity flag to a general purpose flags register or integer so that it can be used for other purposes. Juan Carlos Arevalo Baeza <jcab roningames.com> wrote in message news:a419m3$2kgj$1 digitaldaemon.com...:) That's the dark side of case insensitive strings. Personally, I use the Windows file system way: case is stored as given, but comparisonsdon'tuse it. It's the same as ignoring part of a structure in its comparison operators. It does make for some awkward situations, I'll grant you that.
Feb 09 2002
Really? I didn't know that. Don't follow IEEE 754 specifiations as it is an ill conceived and irrational standard. If the language is to have ouitput structures, I would seem appropariate that in the assignment phase from a standard struct that the conversion of -0 to +0 be made. Serge K <skarebo programmer.net> wrote in message news:a3ql6l$21ts$1 digitaldaemon.com...takenI wouild make one exception. Equality. Equality can at all times beassignmentto be byte by byte identical. for comparison, and byte by bytefor assignment.According to IEEE 754, -0.0 == +0.0, but have different binary representation.
Feb 06 2002
"D" <s_nudds hotmail.com> wrote in message news:a3qts2$26e1$1 digitaldaemon.com...Really? I didn't know that. Don't follow IEEE 754 specifiations as it is an ill conceived andirrationalstandard.Yeah, and then you can throw your FPU away and forget about it...
Feb 06 2002
Why is that Paul. Are you unable to change -0.0 into 0.0? I thought you were a programmer. Am I mistaken? Pavel Minayev <evilone omen.ru> wrote in message news:a3r4g9$298b$2 digitaldaemon.com..."D" <s_nudds hotmail.com> wrote in message news:a3qts2$26e1$1 digitaldaemon.com...Really? I didn't know that. Don't follow IEEE 754 specifiations as it is an ill conceived andirrationalstandard.Yeah, and then you can throw your FPU away and forget about it...
Feb 07 2002
"D" <s_nudds hotmail.com> wrote in message news:a3liu5$ruq$1 digitaldaemon.com...Operatoror overloading is an error gnashing at the bit to happen. Thereis<NO> valid justification for providing it. There are arguments, but they are ALL invalid, because code reliability must trump programming convenience.I wouldn't say that code reliability is that much at stake with operator overloading. Consider the next piece of code: MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1, Var3))); Then consider the same code using operator overloading: MyClass result = Var1 + Var1 * Var3; Now I doubt that there will be many people telling me the first snippet is more readable than the second. After I wrote it, I had to examine it 4 times to make sure I had it correct, with all the braces and the order of the arguments. I am not talking about how *writable* the code is, mind you, that does not seem very important to me. Everyone will testify that the second part is more easy to write, with less characters and less parenthesis, but I don't care about that. I almost never use acronyms like w8 4 me, RTFM, IMHO, WYSISYG etcetera, because, even though they are easier to write, they are more difficult to read. But when code is easier to *read* as well as write, I think that leads to more reliable code!The problem with operator overloading is that it can be highly confusing. What Isn't highly confusing however, and what does provide the samebenefitis providing the ability to create your own operators.Mmmm.... So you don't understand what A + B or C * D means, but you do understand all of the very complex operators that exist in math today, as well as the ones that I personally come up with? This just doesn't make sense to me...Existing operators have limited usefulness, even for simple vector operations where there are two types of product. What existing two operators are you going to redefine for them?This example is mentioned often, and it is indeed a very good one. Matrix math is a very important part of programming and indeed there should be a standard for such things. This doesn't put an end to the discussion though...Are there many different ways to interpret A = B, or if (A == B)? These are the operators used and overloaded most often, and they are valid operations for almost any class you can come up with. What is more readable to you: if (! A.Cmp (B)) or if (A == B) I especially love the fact that there is a ! operator in the first expression, that to me is quitte counter-intuitive, and that the ==, !=, < and > operators are mixed together, even though some classes support testing for equality, but not for sortability. When A.Cmp(B) returns -1, does that mean A is smaller than B, or that it is just not equal to it? You gotta love that ambiguity! If a simple test for equality isn't unambiguis and is counter intuitive, that tells a long story.Operator Overloading is very, very bad news.There are some very bad things that *can* be done with operator overloading, but there are also some very good. What my proposal (which you said nothing about) tries to do, is use the best things of both worlds. It eliminates a lot of the mistakes that can be made using operator overloading, such as overloading == but not !=, it allows for both forms of coding to be used (and even exchanged using DML) and it could create more readable code. Walter, *please* create some basic interfaces like IAssignable, IComparable and ISortable! It would make D code from different users look and behave the same. We could test if a class supports ISortable and there would be much less different ways of doing the same thing. Also, please ditch Cmp(). Testing for equality and sortability are different things that shouldn't be mixed like C does. Even if you don't want to make a decision about operator overloading just yet, interfaces like this would leave the door open while gaining important benefits right away! If you never add operator overloading to the language we at least all use the same ways of assigning one object to another, or comparing them or testing which one is larger than the other etc. I would hate to see some people define assignment functions as Assign(), others as Copy() and again others as Clone(). -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 04 2002
OddesE <OddesE_XYZ hotmail.com> wrote in messageI wouldn't say that code reliability is that much at stake with operator overloading. Consider the next piece of code: MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1,Var3)));Then consider the same code using operator overloading: MyClass result = Var1 + Var1 * Var3;Consider this piece of code define op var1 .* var3 = MyClass::Multiply(Var1,Var3) define op var1. .+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 .+ Var1 .* Var3 I fail to see your complaint Mr OdessE. Perhaps you can explain it to me. OdessE writes:Now I doubt that there will be many people telling me the first snippet is more readable than the second.Now I dount that there will be many people telling me that MyClass::result = Var1 .+ Var1 .* Var3 is any less readable than MyClass result = Var1 + Var1 * Var3; OdessE writes:After I wrote it, I had to examine it 4 times to make sure I had it correct, with all the braces and the order of the arguments.I had no such burden.confusing.The problem with operator overloading is that it can be highlyOdessE writes:What Isn't highly confusing however, and what does provide the samebenefitis providing the ability to create your own operators.Mmmm.... So you don't understand what A + B or C * D means, but you do understand all of the very complex operators that exist in math today, as well as the ones that I personally come up with?Clearly no one can, since the meaning of + and * are dependent on the types of A, B, C and D. You may claim to know the meaning, but if so, you are lying to yourself. OdessE writes:if (! A.Cmp (B)) or if (A == B)It depends on what A and B are.and what you are trying to do. Perhaps A and B are objects, the == syntax can have three equally appropriate meanigns. A is numerically identical to B, A is functionally identical to B, A and B are the same object. With one equal sign, how do you intend to distingish between these three poetntial meanings? How do you intend to implement more than one of them at a time? I await your response.OdessE writes:Operator Overloading is very, very bad news.There are some very bad things that *can* be done with operator overloading, but there are also some very good.The bad outweighs to good. <period>
Feb 04 2002
"D" <s_nudds hotmail.com> wrote in message news:a3nmm4$2b86$1 digitaldaemon.com...Now I dount that there will be many people telling me that MyClass::result = Var1 .+ Var1 .* Var3 is any less readable than MyClass result = Var1 + Var1 * Var3;I do. If I use your library, I'd expect + to add vectors. I would have never think of .+, before reading the docs to the point where it's mentioned.
Feb 04 2002
"D" <s_nudds hotmail.com> wrote in messagePavel Minayev <evilone omen.ru> wrote in message news:a3o1gc$2fji$1 digitaldaemon.com...Now I dount that there will be many people telling me that MyClass::result = Var1 .+ Var1 .* Var3 is any less readable than MyClass result = Var1 + Var1 * Var3;I do. If I use your library, I'd expect + to add vectors. I would have never think of .+, before reading the docs to the point where it's mentioned.Yet you see .+ being applied to a variable, perhaps a vector, perhaps not. This visual cue tells you that you had better pay careful attention to that statement because it is using user defined operators and probably aggregate variables. With MyClass result = Var1 + Var1 * Var3; on the other hand there are no visual cues and the expression could very well be a simple one that does not need further investigation. Visual cues are a good thing. They aid us in avoiding error.
Feb 05 2002
"D" <s_nudds hotmail.com> ha scritto nel messaggio news:a3o85r$2jck$1 digitaldaemon.com...Yet you see .+ being applied to a variable, perhaps a vector, perhaps not. This visual cue tells you that you had better pay careful attention tothatstatement because it is using user defined operators and probablyaggregatevariables. With MyClass result = Var1 + Var1 * Var3; on the other hand there are no visual cues and the expression could very well be a simple one that does not need further investigation. Visual cues are a good thing. They aid us in avoiding error.I must admit you have a point here, but that little dot can be easily hidden inside a big expression. Any other idea? I think it's useful to know if I'm calling an overloaded operator or not, but adding the littlest dot definitely isn't the solution. Ciao
Feb 05 2002
Roberto Mariottini <rmariottini lycosmail.com> wrote in message news:a3okd3$2oil$1 digitaldaemon.com...I must admit you have a point here, but that little dot can be easilyhiddeninside a big expression. Any other idea? I think it's useful to know if I'm calling an overloaded operator or not, but adding the littlest dot definitely isn't the solution.I toyed with the idea of bracketing them <+> <-> etc..
Feb 05 2002
"D" <s_nudds hotmail.com> wrote in message news:a3nmm4$2b86$1 digitaldaemon.com...OddesE <OddesE_XYZ hotmail.com> wrote in messageConsider this pieces of code: define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3) define op var1 $* var3 = MyClass::Multiply(Var1,Var3) define op var1. $+ var3 = MyClass::Add(Var1.Var3) define op var1 * var3 = MyClass::Multiply(Var1,Var3) define op var1. + var3 = MyClass::Add(Var1.Var3) define op var1 &* var3 = MyClass::Multiply(Var1,Var3) define op var1. &+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 *+ Var1 ** Var3 MyClass::result = Var1 $+ Var1 $* Var3 MyClass::result = Var1 + Var1 * Var3 MyClass::result = Var1 &+ Var1 &* Var3 Now you tell me that you don't see any problems in this? How am I supposed to know what strange character sequence a programmer selected to convey a plus operation? You could use some kind of standard, but what is the point? Why do you think people can easily abuse normal operator overloading, but replacing the normal operator sign that everyone knows with some weird sign nobody knows wil leviate this problem? Who keeps me from doing this: define op var1 .* var3 = MyClass::Add (Var1,Var3) define op var1. .+ var3 = MyClass::Multiply (Var1.Var3) MyClass::result = Var1 .+ Var1 .* Var3 Now do you still understand this example? I really don't see any big differences in this. Your solution does not prevent the abuse you keep talking about. Ok, so maybe if people see .= they will look it up in the docs. Or maybe they just assume it is assign. At least with the normal = there is a defined meaning what the operator *should* do. Now it could be anything. I think the code just got much _less_ self-documenting!I wouldn't say that code reliability is that much at stake with operator overloading. Consider the next piece of code: MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1,Var3)));Then consider the same code using operator overloading: MyClass result = Var1 + Var1 * Var3;Consider this piece of code define op var1 .* var3 = MyClass::Multiply(Var1,Var3) define op var1. .+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 .+ Var1 .* Var3 I fail to see your complaint Mr OdessE. Perhaps you can explain it to me.OdessE writes:I am telling it. I never saw an operator .+ before. Not in Delphi/Java/C/C++, nor in math. How am I supposed to know what it means? I could *assume* it means plus, but I wouldn't know it. At least with normal + I know what it normally means (in math or other languages).Now I doubt that there will be many people telling me the first snippet is more readable than the second.Now I dount that there will be many people telling me that MyClass::result = Var1 .+ Var1 .* Var3 is any less readable than MyClass result = Var1 + Var1 * Var3;OdessE writes:Good for you, but you are contradicting yourself with this cowboy-coder comment. So if you know what it means than it is not a problem eh? You still didn't say that MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1, Var3))); is more readable than MyClass result = Var1 + Var1 * Var3; probably because it just isn't.After I wrote it, I had to examine it 4 times to make sure I had it correct, with all the braces and the order of the arguments.I had no such burden.typesconfusing.The problem with operator overloading is that it can be highlyOdessE writes:What Isn't highly confusing however, and what does provide the samebenefitis providing the ability to create your own operators.Mmmm.... So you don't understand what A + B or C * D means, but you do understand all of the very complex operators that exist in math today, as well as the ones that I personally come up with?Clearly no one can, since the meaning of + and * are dependent on theof A, B, C and D.And clearly no one can now the meaning of .+ and .* At least with normal operators I know what they usually do and have a reference in math or other languages to draw experience on.You may claim to know the meaning, but if so, you are lying to yourself.If I write a function CString MyClass::ToString(), are you going to trust me that it will convert MyClass to a string? If you don't, good luck spending the rest of your life trying to read in the (sometimes nonexistent) documentation of code trying to figure out what bloody obvious functions do. If you do, how can you be sure I didn't write the function in such a way that it formats your hard-drive? The fact is you can't. I could even have written misleading documentation that tells you that my function converts MyClass to a CString, when in fact it just wipes your disc. Are you really saying you are manually checking the code of every third party function you ever use? Functions should have descriptive names and they should do what you expect of them. If they don't, the code is effectively broken. Everyone knows what string1 = string2 + string3 is supposed to do. If you don't you can always still look it up. At least with normal operators there is a common base of experience people can draw from.OdessE writes:andif (! A.Cmp (B)) or if (A == B)It depends on what A and B are.and what you are trying to do. Perhaps AB are objects, the == syntax can have three equally appropriate meanigns.Ais numerically identical to B, A is functionally identical to B, A and B are the same object. With one equal sign, how do you intend to distingish between these three poetntial meanings? How do you intend to implement more than one of themata time? I await your response.I don't really see how Cmp solves these issues better then operator overloading. And if you compare two numbers to see if they are equal, do you try to find out if the are the same instance of an int? Draw from experience. int A = 10; int B = 10; int C = 0; if (A == B) C = A; B = 5; What value does C have?No it doesn't. Period. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mailOdessE writes:Operator Overloading is very, very bad news.There are some very bad things that *can* be done with operator overloading, but there are also some very good.The bad outweighs to good. <period>
Feb 05 2002
OddesE <OddesE_XYZ hotmail.com> wrote in message news:a3ph43$61j$1 digitaldaemon.com...Consider this pieces of code: define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3) define op var1 $* var3 = MyClass::Multiply(Var1,Var3) define op var1. $+ var3 = MyClass::Add(Var1.Var3) define op var1 * var3 = MyClass::Multiply(Var1,Var3) define op var1. + var3 = MyClass::Add(Var1.Var3) define op var1 &* var3 = MyClass::Multiply(Var1,Var3) define op var1. &+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 *+ Var1 ** Var3 MyClass::result = Var1 $+ Var1 $* Var3 MyClass::result = Var1 + Var1 * Var3 MyClass::result = Var1 &+ Var1 &* Var3Yup I do see difficulty with your code. It's difficult to read because you have chosen to define the same function for multiply and add a total of 5 times. Very poor programming practice. Consider the equivalent defined only once.... define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 *+ Var1 ** Var3 Reasonably readable but flawed. I find it odd that you would see the need to create a new operator by combining two thers. Still purposely trying to write obfuscated code I guess. Here is a superior alternative. define op var1 :* var3 = MyClass::Multiply(Var1,Var3) define op var1. :+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 :+ Var1 :* Var3 Yes, quite readable now that the purposeful obfuscation has been removed. Odesse writes:How am I supposed to know what strange character sequence a programmer selected to convey a plus operation?One presumes that programmers will take care in selecting meaninful names for their operators just as they are preseumed to select meaninful names for their functions. Also, since operator overloading is abolished, there is a 1:1 mapping of operators to function (with the exception of equality). So all we need do is keep a our list of operators handy and we can understand any function presented to us. It's as simple as that. Odesse writes:You could use some kind of standard, but what is the point?No standards are needed. :V+ is a nice enough name for vector add. If vector operators are the only things added the programmer might select :+ Matrix multiplication might could be indicated by :M* or :MtxMul, or whatever name the programmer sees fit to use. Odesse writes::Why do you think people can easily abuse normal operator overloading, but replacing the normal operator sign that everyone knows with some weird sign nobody knows wil leviate this problem?Primarily because as you yoursef showed in another thread, they aer forced to by the limited number of existing operators. Odesse writes:Who keeps me from doing this: define op var1 .* var3 = MyClass::Add (Var1,Var3) define op var1. .+ var3 = MyClass::Multiply (Var1.Var3) MyClass::result = Var1 .+ Var1 .* Var3Absolutely nothing. Do you regularly program in that manner? Do you label your functions with names like "aelfkie" and "xxxxxxx"? Chosing appropriat labels is one aspect of proper programming. Odesse writes:I really don't see any big differences in this. Your solution does not prevent the abuse you keep talking about.There are 4 differences. 1. Existing operators do not change their meaning and therefore all lines containing existing operators can be taken at face value rather than being suspect of hiding some unsuspected behaviour. 2. There is a 1:1 relationship between operator and function which enables the programmer to use a simple operator table to figure out what a specific equation means 3. I recommend that all new operators have the same precedence. Hence there is no confusion in the order of operations, and no unnatural consequences to what would otherwise be automatic reordering. 4. New operators would provide visual cues that readily distinguish them from existing operators, thereby allowing the programmer to readily identify new program behaviour. Odesse writes:Ok, so maybe if people see .= they will look it up in the docs. Or maybe they just assume it is assign. At least with the normal = there is a defined meaning what the operator *should* do. Now it could be anything. I think the code just got much _less_ self-documenting!Now they could presume it is an assignment, but the colon at the front of the operator indicates new behaviour that distinguishes it from simple assignment. You may elect to ignore visual cues like that, but I would not. On the other hand with overloading you wouldn't see := (colon equal) you would see = (equal) Which is identical to = (equal) Yet the first equal under your regime of operator overloading would have a meaning that is entirely different than the second equal symbol,. Your system, no visual cues. Your system is inferior.Odesse writes:OdessE writes:Now I doubt that there will be many people telling me the first snippet is more readable than the second.Now I dount that there will be many people telling me that MyClass::result = Var1 .+ Var1 .* Var3 is any less readable than MyClass result = Var1 + Var1 * Var3;I am telling it. I never saw an operator .+ before. Not in Delphi/Java/C/C++, nor in math. How am I supposed to know what it means?You go to the top of the module, find the definition and read it. Alternately you pull out your quick reference chart and read it. Alternately you rememher what it means and continue with the interpretation. I fail to see your difficulty. Odesse writes:I could *assume* it means plus, but I wouldn't know it. At least with normal + I know what it normally means (in math or other languages).You can assume many things. The colon in front of the label is a visual cue that you may not assume anythign. Assume at your own peril.Nope, it's not a problem because you can easily remember what it means as well. Most importantly the colon at the front of the label is your cue that unusual behaviour is taking place. Odesse writes:OdessE writes:Good for you, but you are contradicting yourself with this cowboy-coder comment. So if you know what it means than it is not a problem eh?After I wrote it, I had to examine it 4 times to make sure I had it correct, with all the braces and the order of the arguments.I had no such burden.You still didn't say that MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1,Var3)));is more readable than MyClass result = Var1 + Var1 * Var3; probably because it just isn't.Yes, the first statement is more readable than the second because in the case of the second statement we are not told what + and * do. We only know that they perform some unknown operation, and that operation depends on the variable types which are not specified. Hence we can say nothing about the second function. However in the case of :+ and :* there is a 1:1 correspondance between function and operator label so knowing that :* = Myclass::Multiply(Var1,Var3) :+ = Myclass::Add(Var1,Var3) We know everything we need to know about the equation. It's really quite simple. I fail to see your objection.Odesse writes:typesconfusing.The problem with operator overloading is that it can be highlyOdessE writes:What Isn't highly confusing however, and what does provide the samebenefitis providing the ability to create your own operators.Mmmm.... So you don't understand what A + B or C * D means, but you do understand all of the very complex operators that exist in math today, as well as the ones that I personally come up with?Clearly no one can, since the meaning of + and * are dependent on theof A, B, C and D.And clearly no one can now the meaning of .+ and .*Since there is a 1:1 correspondance of label and funtion, you consult your opcode table. You can not do this with + and * since there are no visual clues that + and * are doing anything outside their ordinary meaning. a = b + c d = e + f In your inferior system of operator overloading the first example above may be doing a simple addition,. while the second could be adding a graphic to a web page an uploading the result to a server. Quite foolish. Odesse writes:At least with normal operators I know what they usually do and have a reference in math or other languages to draw experience on.And you can still use that by creating new operators with names similar to the existing operators. :+ in place of + for example. But you have the advantage of creating new operators with more appropriate labels as well For example :dot or :cross for dot and cross products If the colon were more visible on this screen I would have used colon period, for dot product and colon x for cross product. So all of the advantages of operator overloading exist while all of the failures of C++ style operator overloading can be avoided. Operator overloading is clearly inferior. .meanigns.It depends on what A and B are.and what you are trying to do. Perhaps AandB are objects, the == syntax can have three equally appropriateABis numerically identical to B, A is functionally identical to B, A andthemare the same object. With one equal sign, how do you intend to distingish between these three poetntial meanings? How do you intend to implement more than one ofatOdesse writes:a time? I await your response.I don't really see how Cmp solves these issues better then operator overloading. And if you compare two numbers to see if they are equal, do you try tofindout if the are the same instance of an int? Draw from experience.That may very well be a requirement yes. That int may very well be a semiphore used for synchronization, or used by the program to tell if it is looking at an instance of itself. Once again I fail to see your complaint. Odesse writes:int A = 10; int B = 10; int C = 0; if (A == B) C = A; B = 5; What value does C have?If this langauge allows all operators to be overloaded even for the base types then we do not know the answer because somewhere elsewhere in the program the operators may have hand their meaning altered. Odesse, your argument has been obliterated by common sense. At this point you are simply embarrasing yourself. I recommend you stop before damaging your reputation further.
Feb 06 2002
"D" <s_nudds hotmail.com> wrote in message news:a3r33g$28jj$1 digitaldaemon.com...OddesE <OddesE_XYZ hotmail.com> wrote in message news:a3ph43$61j$1 digitaldaemon.com...youConsider this pieces of code: define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3) define op var1 $* var3 = MyClass::Multiply(Var1,Var3) define op var1. $+ var3 = MyClass::Add(Var1.Var3) define op var1 * var3 = MyClass::Multiply(Var1,Var3) define op var1. + var3 = MyClass::Add(Var1.Var3) define op var1 &* var3 = MyClass::Multiply(Var1,Var3) define op var1. &+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 *+ Var1 ** Var3 MyClass::result = Var1 $+ Var1 $* Var3 MyClass::result = Var1 + Var1 * Var3 MyClass::result = Var1 &+ Var1 &* Var3Yup I do see difficulty with your code. It's difficult to read becausehave chosen to define the same function for multiply and add a total of 5times.I actually did not do that. 5 other programmers did that. Some of them were on other teams, others were with other companies that we use libraries of. All these declarations were in different files and were part of different libraries. Unfortunately they all do the same thing, they all add two strings. All these programmers noticed the lack of string support in language X but, since it did include adding new operators, they invented one of their own. Unfortunately I have to memorize them all, or find different libraries.Very poor programming practice. Consider the equivalent defined only once.... define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3)You try to convince hundreds of programmers to use your style... Math already has defined these operators, but no, you can't use those...Invent some of your own...MyClass::result = Var1 *+ Var1 ** Var3 Reasonably readable but flawed. I find it odd that you would see the need to create a new operator by combining two thers. Still purposely trying to write obfuscated code I guess.No I just had no clue, like all programmers according to you.Here is a superior alternative. define op var1 :* var3 = MyClass::Multiply(Var1,Var3) define op var1. :+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 :+ Var1 :* Var3 Yes, quite readable now that the purposeful obfuscation has been removed.What does the : mean? Where is the standard? What prevents other companies from using entirely different standards? How am I supposed to remember all this? I am not as good as you at memorizing tables with useless data...Odesse writes:Great, all these lists and tables. Let's name our variables var1, var2 and var3, then keep a list of what they mean.How am I supposed to know what strange character sequence a programmer selected to convey a plus operation?One presumes that programmers will take care in selecting meaninful names for their operators just as they are preseumed to select meaninful names for their functions. Also, since operator overloading is abolished, there is a 1:1 mapping of operators to function (with the exception of equality). So all we need do is keep a our list of operators handy and we can understand any function presented to us. It's as simple as that.Odesse writes:Your opinion. I don't agree. I still don't mean what the colon stands for. I could guess at the V, but I don't like guessing what code does, I like knowing so from experience and common sense.You could use some kind of standard, but what is the point?No standards are needed. :V+ is a nice enough name for vector add.If vector operators are the only things added the programmer might select:+ Ditch the colon, of which I don't understand the meaning, and what is left?Matrix multiplication might could be indicated by :M* or :MtxMul, or whatever name the programmer sees fit to use.Ah yes, :MtxMul... Starts to sound a lot like a regular function name doesn't it? What is the point?Odesse writes::Yes, but why replace the existing ones with substitutes that do exactly the same, such as :V+ ? Adding a sqrt operator is a different matter altogether, there doesn't exist one in the programming language at the moment.Why do you think people can easily abuse normal operator overloading, but replacing the normal operator sign that everyone knows with some weird sign nobody knows wil leviate this problem?Primarily because as you yoursef showed in another thread, they aer forced to by the limited number of existing operators.Odesse writes:I don't, but you keep saying that programmers are clueless and do such things. I am asking you how your method prevents this.Who keeps me from doing this: define op var1 .* var3 = MyClass::Add (Var1,Var3) define op var1. .+ var3 = MyClass::Multiply (Var1.Var3) MyClass::result = Var1 .+ Var1 .* Var3Absolutely nothing. Do you regularly program in that manner?Do you label your functions with names like "aelfkie" and "xxxxxxx"? Chosing appropriat labels is one aspect of proper programming. Odesse writes:With operator overloading (if used right) they don't change their meaning either. + means to add something. You are just changing the something you want to add. You could define operator+ to multiply it's parameters ofcourse, but you could do that using any of the constructs we are talking about.I really don't see any big differences in this. Your solution does not prevent the abuse you keep talking about.There are 4 differences. 1. Existing operators do not change their meaning and therefore all lines containing existing operators can be taken at face value rather than being suspect of hiding some unsuspected behaviour.2. There is a 1:1 relationship between operator and function which enables the programmer to use a simple operator table to figure out what a specific equation meansI don't like those tables, and with normal operators you don't need them, you already know what + means.3. I recommend that all new operators have the same precedence. Hencethereis no confusion in the order of operations, and no unnatural consequences to what would otherwise be automatic reordering.A yes: Assuming a class int64 with operators defined for adding and multiplication: int64 a, b, c; a := a :+ b :* c; Now you will get different results then you would expect from plus and multiply operations... It just doesn't make sense that all math knowledge becomes invalid when using operators.4. New operators would provide visual cues that readily distinguish them from existing operators, thereby allowing the programmer to readilyidentifynew program behaviour.The behaviour for + is not new, it is still adding two entities. You are just allowing new types to be added.Odesse writes:What new behaviour? What strange things are you doing tou your variable?Ok, so maybe if people see .= they will look it up in the docs. Or maybe they just assume it is assign. At least with the normal = there is a defined meaning what the operator *should* do. Now it could be anything. I think the code just got much _less_ self-documenting!Now they could presume it is an assignment, but the colon at the front of the operator indicates new behaviour that distinguishes it from simple assignment.You may elect to ignore visual cues like that, but I would not. On the other hand with overloading you wouldn't see := (colon equal) you would see = (equal) Which is identical to = (equal) Yet the first equal under your regime of operator overloading would have a meaning that is entirely different than the second equal symbol,.Right, entirely different. No relation whatsoever. Are you kidding me? I am assigning one variable to another, since when does the assignment of objects of a class have nothing in commom with assigning integers or floats? Should we also use different operators for addition of all basic types? The have "nothing in common" after all...Your system, no visual cues. Your system is inferior.interpretation.Odesse writes:OdessE writes:Now I doubt that there will be many people telling me the first snippet is more readable than the second.Now I dount that there will be many people telling me that MyClass::result = Var1 .+ Var1 .* Var3 is any less readable than MyClass result = Var1 + Var1 * Var3;I am telling it. I never saw an operator .+ before. Not in Delphi/Java/C/C++, nor in math. How am I supposed to know what it means?You go to the top of the module, find the definition and read it. Alternately you pull out your quick reference chart and read it. Alternately you rememher what it means and continue with theI fail to see your difficulty.Usability. The code should be as self-documenting as possible. I shouldn't need a quick reference chart, or at least as less as possible.Odesse writes:Do you never assume anything about other people's code? If someone makes a list class and gives it a Add function, I will assume it means adding something to the list. I am not going to assume it means removing elements. When you are programming with an API, say Win32, how do you find out what function to use? When you need to create a window, do you really read all the documentation for all API functions, or are you going to assume that CreateWindowEx will create a window, and then just check it's documentation to see what parameters you need? Assumptions are always made, either conciously or unconciously. The trick is to make sure those assumptions are correct, by having operations do what you would expect them to do.I could *assume* it means plus, but I wouldn't know it. At least with normal + I know what it normally means (in math or other languages).You can assume many things. The colon in front of the label is a visual cue that you may not assume anythign. Assume at your own peril.Excuse me, what colon? I was talking about an example with named functions, that is why I was mentioning how the braces were confusing to me: MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1,Var3))); That was the function I was talking about. Where is the colon?Nope, it's not a problem because you can easily remember what it means as well. Most importantly the colon at the front of the label is your cue that unusual behaviour is taking place.OdessE writes:Good for you, but you are contradicting yourself with this cowboy-coder comment. So if you know what it means than it is not a problem eh?After I wrote it, I had to examine it 4 times to make sure I had it correct, with all the braces and the order of the arguments.I had no such burden.Odesse writes:Yes we are, by our math teachers when we go to school. You know what plus is supposed to do. You also know what Add() is supposed to do. If they really do it is a different matter. If you can't grasp what + is supposed to do, why would Add() be more clear? I don't know what House1 = House2 + House3; is supposed to do, but then again I don't know what House1.Assign (House::Add (House2, House3)); is supposed to do either. Do you? Maybe add the windows in the house?You still didn't say that MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1,Var3)));is more readable than MyClass result = Var1 + Var1 * Var3; probably because it just isn't.Yes, the first statement is more readable than the second because in the case of the second statement we are not told what + and * do.We only know that they perform some unknown operation, and that operation depends on the variable types which are not specified.In D the type of all variables is always specified. The meaning of the Add() operation on the other hand might not be specified, since it is not required by the languag that it is documented. All we know is that it is a static function which takes two arguments of a certain type and returns another argument of that same type. But we also know that of the + operator. What is the difference?Hence we can say nothing about the second function.Nor about the first. All we can do is read the documentation, use our common sense in interpreting well known symbols or variable names and look at the definition or implementation of the functions involved.However in the case of :+ and :* there is a 1:1 correspondance between function and operator label so knowing that :* = Myclass::Multiply(Var1,Var3) :+ = Myclass::Add(Var1,Var3) We know everything we need to know about the equation.No we don't. We still don't know what Multiply() does, at least not when we "may not assume anythign" like you say. We just added an extra layer of complexity. I now have to remember that :* calls Multiply and find out what Multiply does.It's really quite simple. I fail to see your objection.Strange. I see your objections, I just don't agree with them. Do you mean to say you really don't understand what is being said?sameconfusing.The problem with operator overloading is that it can be highlyWhat Isn't highly confusing however, and what does provide theyourOdesse writes:typesbenefitOdessE writes:is providing the ability to create your own operators.Mmmm.... So you don't understand what A + B or C * D means, but you do understand all of the very complex operators that exist in math today, as well as the ones that I personally come up with?Clearly no one can, since the meaning of + and * are dependent on theof A, B, C and D.And clearly no one can now the meaning of .+ and .*Since there is a 1:1 correspondance of label and funtion, you consultopcode table.Great all these tables.You can not do this with + and * since there are no visual clues that +and* are doing anything outside their ordinary meaning. a = b + c d = e + f In your inferior system of operator overloading the first example abovemaybe doing a simple addition,. while the second could be adding a graphic to a web page an uploading the result to a server. Quite foolish.It could also format your harddisk. But so could your :+ operator. There are some visual cues that the operator is overloaded, because the parameters used with it are non-standard. The operator itself looks the same, but so it should. You are performing a standard operation with it, you are just performing it on non-standard parameters. Hence the visual cue should come from the parameters.Odesse writes:They are confusing. Especially the fact that everyone can, and will, define different operators to perform the same operation on the same types of variables (say vectors, strings, the boundschecked pointer you would like) is going to cause a lot of confusion.At least with normal operators I know what they usually do and have a reference in math or other languages to draw experience on.And you can still use that by creating new operators with names similar to the existing operators. :+ in place of + for example.But you have the advantage of creating new operators with more appropriate labels as well For example :dot or :cross for dot and cross products If the colon were more visible on this screen I would have used colon period, for dot product and colon x for cross product.? You are already using the colon. :cross looks like a function, not an operator. What is the use of operators if they have names? You might as well define :add instead of +. The idea behind operator overloading is to use the notation of the problem domain. If you are describing a mathematical addition you want to use the mathematical operator to describe that operation.So all of the advantages of operator overloading exist while all of the failures of C++ style operator overloading can be avoided.None of the advantages exist. You lose the biggest advantage, the fact that you can use operators from math to represent the mathematical operations you want to perform. What you are left with is essentialy a way to hide descriptive function names behind strange self-defined and thus arbitrary symbols such as :V+. Just a shame you defined :V+ for Vector math as in matrices and vectors, while someone else defined it to concatenate java style vectorss. On the other hand, I defined the addition for math vectors as :+ because it was the only one I needed, while you thought that one was more appropriate for your bounded pointer. Do you really mean to say you don't see how this might cause confusion?Operator overloading is clearly inferior. .AIt depends on what A and B are.and what you are trying to do. Perhapsandandmeanigns.B are objects, the == syntax can have three equally appropriateAis numerically identical to B, A is functionally identical to B, ABthreeare the same object. With one equal sign, how do you intend to distingish between theseTo check if the objects were one and the same, you would compare the references, not the object they are pointing to. To check wheter the objects contain the same information you would check the objects themselves.thempoetntial meanings? How do you intend to implement more than one ofata time? I await your response.Odesse writes:How do you do this in C/C++? You mean int a; int *pa int *pb; pa = &a; pb = &b; if (*pa == *pb) // same number in instances of int if (pa == pb) // same instance of int I don't see why operator overloading would make this more difficult. Anyhow, you are not comparing the same objects. In the first case you are comparing two ints. In the second case you are comparing two references or pointers to ints. By definition, each instance of an object is a unique entity. When you use classes, the operator to compare the pointers to the classes would be automatically defined, so you compare using that. To compare not the pointers or references, but the objects themselves, you need to use Cmp() or an overloaded operator. Your argument does not hold, simply because you are saying that the comparison operator can have different meanings when applied to the same type, when in the example you give they are actually applied to different types, objects (the ints) and references to these objects. So it makes sense that the same operation applied to variables of different types yields different results.I don't really see how Cmp solves these issues better then operator overloading. And if you compare two numbers to see if they are equal, do you try tofindout if the are the same instance of an int? Draw from experience.That may very well be a requirement yes. That int may very well be a semiphore used for synchronization, or used by the program to tell if it is looking at an instance of itself. Once again I fail to see your complaint.Odesse writes:No one is saying that operators should be overloaded for operations between base types, so we *do* know what value C has. You are avoiding the conclusion. If we compare objects we want to know if they contain the same information. If we want to know if two references point to the same object, we compare the references, not the objects themselves. These are two different operations on two different types, hence they yield two different results. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mailint A = 10; int B = 10; int C = 0; if (A == B) C = A; B = 5; What value does C have?If this langauge allows all operators to be overloaded even for the base types then we do not know the answer because somewhere elsewhere in the program the operators may have hand their meaning altered.
Feb 07 2002
"OddesE" <OddesE_XYZ hotmail.com> schrieb im Newsbeitrag news:a3uudo$2amb$1 digitaldaemon.com..."D" <s_nudds hotmail.com> wrote in message news:a3r33g$28jj$1 digitaldaemon.com...Hm. Without either operator overloading or adding new ops, I have seen this issue again. There are plenty of functions meaning the same, but spelling different, even in a library from the same concern: CArray::RemoveAll CListCtrl::DeleteAllItems CMap::RemoveAllItems ( I believe? Couldn't remember) ... These are exact the same problem if you have none of both, operator overloading or new operators (And the problem is worse, since "size" and "Size" are different things ;-) There could be a String:: concatenate add concat cat All with proper, logical meanings (and CaSEs).OddesE <OddesE_XYZ hotmail.com> wrote in message news:a3ph43$61j$1 digitaldaemon.com...youConsider this pieces of code: define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3) define op var1 $* var3 = MyClass::Multiply(Var1,Var3) define op var1. $+ var3 = MyClass::Add(Var1.Var3) define op var1 * var3 = MyClass::Multiply(Var1,Var3) define op var1. + var3 = MyClass::Add(Var1.Var3) define op var1 &* var3 = MyClass::Multiply(Var1,Var3) define op var1. &+ var3 = MyClass::Add(Var1.Var3) MyClass::result = Var1 *+ Var1 ** Var3 MyClass::result = Var1 $+ Var1 $* Var3 MyClass::result = Var1 + Var1 * Var3 MyClass::result = Var1 &+ Var1 &* Var3Yup I do see difficulty with your code. It's difficult to read becausehave chosen to define the same function for multiply and add a total of 5times.I actually did not do that. 5 other programmers did that. Some of them were on other teams, others were with other companies that we use libraries of. All these declarations were in different files and were part of different libraries. Unfortunately they all do the same thing, they all add two strings. All these programmers noticed the lack of string support in language X but, since it did include adding new operators, they invented one of their own. Unfortunately I have to memorize them all, or find different libraries.Maybe operator defining is just simple a step away from functional call to the infix-notation of functions. There were really times, I wanted to have something like: midsum = a :avg: b :avg: c :avg: d; instead of midsum = a.avg(b.avg(c.avg(d)));Very poor programming practice. Consider the equivalent defined only once.... define op var1 ** var3 = MyClass::Multiply(Var1,Var3) define op var1. *+ var3 = MyClass::Add(Var1.Var3)You try to convince hundreds of programmers to use your style... Math already has defined these operators, but no, you can't use those...Invent some of your own...removed.MyClass::result = Var1 :+ Var1 :* Var3 Yes, quite readable now that the purposeful obfuscation has beenWhat does the : mean? Where is the standard? What prevents other companies from using entirely different standards? How am I supposed to remember all this? I am not as good as you at memorizing tables with useless data...I agree with "D" (exept his name... "D"... can I call you troll? ;-). It is surely a very very powerful feature, if you can completly hide a new datatype to the user, providing him with the same operators he always used. If they are implemented good, and no mistake is done, the user of your classes can become a very good feeling. But this is not reality. Too much I saw bad implementations of operators, since someone either used them in different meaning. --------------------------- 1. Bad case: Someone thinks it looks pretty: As example I saw once the operator << overloaded in a stack- implementation to push something onto the stack and >> to pop something. The author was very proud of this nonsens: p << 4; Looks good, if you know that << is push, but is terrible, if you do not and think << has to be bitwise-shift-left or something like a stream-operator (you see, even in the C++-Standardlibrary there are an inconsistenz use of <<). --------------------------- 2. Bad case: Someone misunderstood the real meaning of an operator: The equality-operator is a big problem to overload (as stated somewhere above). Should it equals to object identity or to value identity? Another big thing is operator new. Maybe 8 out of 10 implementations of this operator I saw turned out to have at least one bug in them. It is powerful, but dangerous! So I really do not recommend to allow operator overloading (although I use it really frequently in C++ ;-) Now to adding new operators: The point is, they cannot harm existing operators, so there could no confusing things. This meens, the user cannot be fooled to think, he does use a built-in type but is using a class you support. This has dis- but also has advantages. But you can, if you do it right, give almost the feeling to the user, that it is a built-in type. He only has to remember to add, e.g. a ":" before the usual operators. And second, you can define your shortcuts, for which they are no operator currently exist, as example to push to the stack, you could use p <=- 2; and p -=> a Looks pretty nice too, but cannot be mistaken with << and >>.Great, all these lists and tables. Let's name our variables var1, var2 and var3, then keep a list of what they mean.This would be as stupid as defining :!2$-> of two strings to concatination. I think you can find bad variable names as you can find bad operator names. Maybe it is easier to find bad variable names, but this doesn't affect the thing, that a :+ b :+ c is always more readable than a.add(b.add(c)) (at last IMHO)Here I have to agree to Odysseus, err, Odesse ;) I think code conventions will do the thing, now or later.No standards are needed. :V+ is a nice enough name for vector add.Your opinion. I don't agree. I still don't mean what the colon stands for. I could guess at the V, but I don't like guessing what code does, I like knowing so from experience and common sense.The point (to me, at least) is the INFIX-NOTATION! It is even much better to write a add (b add c) mul d Than a.add(b.add(c).mul(d)) Maybe because I never coded in Lisp before, but I think many other coders will agree with me.Matrix multiplication might could be indicated by :M* or :MtxMul, or whatever name the programmer sees fit to use.Ah yes, :MtxMul... Starts to sound a lot like a regular function name doesn't it? What is the point?Because they cannot be confused with ordinary once. I think this is a really important face (and THE fact, that Walter did not include operator overloading in the draft)Primarily because as you yoursef showed in another thread, they aer forced to by the limited number of existing operators.Yes, but why replace the existing ones with substitutes that do exactly the same, such as :V+ ?It prevent this not. But overloading did not prevent the user from Foo Foo::operator+(Foo f) { return value * f.value; } The exception is, that you see, that the operator .+ is user-defined (note the point before the +) and you do not see that same from operator+, if not explicit looking at the types. So you generally do not expect a problem.Odesse writes:I don't, but you keep saying that programmers are clueless and do such things. I am asking you how your method prevents this.Who keeps me from doing this: define op var1 .* var3 = MyClass::Add (Var1,Var3) define op var1. .+ var3 = MyClass::Multiply (Var1.Var3) MyClass::result = Var1 .+ Var1 .* Var3Absolutely nothing. Do you regularly program in that manner?For operator+ it might be clear. But as example operator<<. Is it a shift-left or a output-into-stream? Such operators already received more than one meaning, and it will become more (as I showed above on "stack push")...1. Existing operators do not change their meaning and therefore all lines containing existing operators can be taken at face value rather than being suspect of hiding some unsuspected behaviour.With operator overloading (if used right) they don't change their meaning either. + means to add something. You are just changing the something you want to add. You could define operator+ to multiply it's parameters ofcourse, but you could do that using any of the constructs we are talking about.enables2. There is a 1:1 relationship between operator and function whichWhat means equal to you? bitwise equal or object identity (e.g. it IS the same reference)? As example to the impact: If you say bitwise, you are not Java-conform. Java-coder expect this to be equality of object identity.the programmer to use a simple operator table to figure out what a specific equation meansI don't like those tables, and with normal operators you don't need them, you already know what + means.Hm, I disagree. What is the disadvantage to intreduce precedence-values? E.g. they range from 0 to 100?3. I recommend that all new operators have the same precedence. Hence there is no confusion in the order of operations, and no unnatural consequences to what would otherwise be automatic reordering.A yes: Assuming a class int64 with operators defined for adding and multiplication: int64 a, b, c; a := a :+ b :* c; Now you will get different results then you would expect from plus and multiply operations... It just doesn't make sense that all math knowledge becomes invalid when using operators.Odesse is right.This the last time I will write this: It is not clear. Maybe in most cases for +. But not for all other operators. Not enough, you did not expect errors in +, because you are fooled that + is build-in. But they can be errors in operator+4. New operators would provide visual cues that readily distinguish them from existing operators, thereby allowing the programmer to readily identify new program behaviour.The behaviour for + is not new, it is still adding two entities. You are just allowing new types to be added.aYet the first equal under your regime of operator overloading would haveAssignment is not that basic: If you have a class with a pointer in it, would you copy the simple pointer, so that both classes refer to the same object or would you also copy the data behind the pointer? This is a common problem, you cannot decide generally. It make even be true, that you need both behaviour in the same programm. Some coder build then member functions like .clone(). Some do not. You do not surely know, what the class is doing you use if you call operator=...meaning that is entirely different than the second equal symbol,.Right, entirely different. No relation whatsoever. Are you kidding me? I am assigning one variable to another, since when does the assignment of objects of a class have nothing in commom with assigning integers or floats? Should we also use different operators for addition of all basic types? The have "nothing in common" after all...Yeah. operator overloading can be REAL powerful. I like it. It is good. But only as long as you use it right. I think this weapon is much too powerful. New operators don't have some of the problems of overloading, or at least the user is aware, that there might be Problems.Odesse writes:Yes we are, by our math teachers when we go to school. You know what plus is supposed to do. You also know what Add() is supposed to do. If they really do it is a different matter. If you can't grasp what + is supposed to do, why would Add() be more clear? I don't know what House1 = House2 + House3; is supposed to do, but then again I don't know what House1.Assign (House::Add (House2, House3)); is supposed to do either. Do you? Maybe add the windows in the house?You still didn't say that MyClass result.Assign(MyClass::.Add (Var1, MyClass::Multiply (Var1,Var3)));is more readable than MyClass result = Var1 + Var1 * Var3; probably because it just isn't.Yes, the first statement is more readable than the second because in the case of the second statement we are not told what + and * do.Hm. I would not think that .+ is a multiplication. It looks somelike a addition. I recognized this without a table...Odesse writes:Great all these tables.And clearly no one can now the meaning of .+ and .*Since there is a 1:1 correspondance of label and funtion, you consult your opcode table.aYou can not do this with + and * since there are no visual clues that +and* are doing anything outside their ordinary meaning. a = b + c d = e + f In your inferior system of operator overloading the first example abovemaybe doing a simple addition,. while the second could be adding a graphic toYes, but those could NOT the build-in + operator for build-in types. And thats the point the troll wanted to make.web page an uploading the result to a server. Quite foolish.It could also format your harddisk. But so could your :+ operator.There are some visual cues that the operator is overloaded, because the parameters used with it are non-standard. The operator itself looks the same, but so it should. You are performing a standard operation with it, you are just performing it on non-standard parameters. Hence the visual cue should come from the parameters.But you do not see that "a" is a class. It could be a integer?similarAt least with normal operators I know what they usually do and have a reference in math or other languages to draw experience on.And you can still use that by creating new operators with namesdefineto the existing operators. :+ in place of + for example.They are confusing. Especially the fact that everyone can, and will,different operators to perform the same operation on the same types of variables (say vectors, strings, the boundschecked pointer you would like) is going to cause a lot of confusion.This is right. One of the disadvantages of new operators. But anyway, it is a disadvantage of functions too. Count how many similar functions there are to copy memory...wereBut you have the advantage of creating new operators with more appropriate labels as well For example :dot or :cross for dot and cross products If the colonxmore visible on this screen I would have used colon period, for dot product and colonoperatorsfor cross product.? You are already using the colon. :cross looks like a function, not an operator. What is the use ofif they have names? You might as well define :add instead of +. The idea behind operator overloading is to use the notation of the problem domain. If you are describing a mathematical addition you want to use the mathematical operator to describe that operation.And infix. You cannot write infix-notation with function calling convention...PerhapsIt depends on what A and B are.and what you are trying to do.You only have one operator==. Maybe you decide, somehow, that equality by value is what you mean. But somebody else (maybe a java-guru) did expect this as the last thing in his mind. Who has right? C++ recommends using compare by value, other similar languages does not.To check if the objects were one and the same, you would compare the references, not the object they are pointing to. To check wheter the objects contain the same information you would check the objects themselves.A and B are objects, the == syntax can have three equally appropriate meanigns. A is numerically identical to B, A is functionally identical to B, A and B are the same object. With one equal sign, how do you intend to distingish between these three poetntial meanings? How do you intend to implement more than one of them at a time? I await your response.How do you do this in C/C++? You mean int a; int *pa int *pb; pa = &a; pb = &b; if (*pa == *pb) // same number in instances of int if (pa == pb) // same instance of int I don't see why operator overloading would make this more difficult.Comparing the instances is much more faster than comparing the values. If you write a class which time is essential, you may want to compares it by instance (So you do not have to call operator= for each class member). But maybe other users of your class expect it comparing by value? Although in some languages, as I stated above, comparing by instance is the normal way, and using a .equals() is the unusual... There are NO well-known standards uppon all operators.programOdesse writes:int A = 10; int B = 10; int C = 0; if (A == B) C = A; B = 5; What value does C have?If this langauge allows all operators to be overloaded even for the base types then we do not know the answer because somewhere elsewhere in theLogical ideas and abstracts may not be the reality. The operator overloading IS still a big pool of errors that do more harm than good. Imi -- Oh dear, its 4:30am, I hope my better side don't kill me for usenetting so long...the operators may have hand their meaning altered.No one is saying that operators should be overloaded for operations between base types, so we *do* know what value C has. You are avoiding the conclusion. If we compare objects we want to know if they contain the same information. If we want to know if two references point to the same object, we compare the references, not the objects themselves. These are two different operations on two different types, hence they yield two different results.
Mar 06 2002
"Immanuel Scholz" <digital-mars kutzsche.net> wrote in message news:a66n7e$1nne$1 digitaldaemon.com...So I really do not recommend to allow operator overloading (although I use it really frequently in C++ ;-)Hey hey hey, stop!.. let it be there, just leave it to us gurus =)This meens, the user cannot be fooled to think, he does use a built-in type but is using a class you support. This has dis- but also has advantages. But you can, if you do it right, give almost the feeling to the user, that it is a built-in type. He only has to remember to add, e.g. a ":" before the usual operators.But who'd stop some coder from overloading operator *+-/ then? And what would it mean? Your guess...a :+ b :+ c is always more readable than a.add(b.add(c)) (at last IMHO)And a ~ b ~ c would be even more readable, IMO.It is even much better to write a add (b add c) mul d Than a.add(b.add(c).mul(d)) Maybe because I never coded in Lisp before, but I think many other coders will agree with me.In general, I agree. So user-defined operators are great, but let's forbid them to be usual identifiers. So: Vector operator cross (Vector a, Vector b) { ... } a = b cross c;Because they cannot be confused with ordinary once. I think this is a really important face (and THE fact, that Walter did not include operator overloading in the draft)In fact, the programmer very frequently doesn't care whether it is the "ordinary" operator or a user-defined... all he wants to know is that a + b will always add b to a, be they integers, vectors, matrices, or dates...For operator+ it might be clear. But as example operator<<. Is it a shift-left or a output-into-stream? Such operators already received more than one meaning, and it will become more (as I showed above on "stack push")...Walter clearly stated that, if operator overloading is to be implemented, things like using << for output will be strictly prohibited by him personally. I second that. =)This the last time I will write this: It is not clear. Maybe in most cases for +. But not for all other operators. Not enough, you did not expect errors in +, because you are fooled that + is build-in. But they can be errors in operator+There can be errors in operator :+ as well. Also, all operators have rather strict meaning. If only we get the "input" and "output" operators in D, it would be great!You do not surely know, what the class is doing you use if you call operator=...I suggest forbid overloading = at all. = should copy references, never objects.
Mar 06 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a66s4k$1ph2$1 digitaldaemon.com... <SNIP>In general, I agree. So user-defined operators are great, but let's forbid them to be usual identifiers. So: Vector operator cross (Vector a, Vector b) { ... } a = b cross c;I agree with this. My standpoints in this discussion have become rather settled, and I am afraid I won't easily change them anymore, unless someone comes up with some really good and new argument. 1. I support operator overloading for standard operators. As to operators == and =, I agree that there could be ambiguity between comparing / assigning by reference or by value, but this could be resolved: MyClass a, b; *a = *b; if (*a == *b) // By value a = b; if (a == b) // by reference, or &a = &b; if (&a == &b); Whatever, essentially a notation that says by reference or by value is needed. Assignment by value means deep copy, otherwise destroying one object will render both invalid, not what you would expect in 99% of the cases. -, +, /, and * are usually well defined and all you need. Operators such as new, delete and << and >> could be forbidden. 2. I support infix notation with precedence for arbitrary functions, this will allow for creating new operator-like behaviour and is all you need most of the time for special functions such as dot product and cross product. I agree with Pavel that normal function naming rules should be applied, I am against using :+: to add two entities, because it can, and will lead to hundreds of different versions of plus operators all doing the same but looking very different. Immanuel was saying in a previous post that this can also be done with normal functions, but that just proofes my point. :+: offers no significant advantages over add because there is no standard there either. Math however is as standard as standards get, and so is +. Please do not allow %, +, -, /, * etc. to define new operators, it will not make programming more easy at all! -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Mar 07 2002
"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a68s84$872$1 digitaldaemon.com...Whatever, essentially a notation that says by reference or by value is needed. Assignment by value means deep copy, otherwise destroying one object will render both invalid, not what you would expect in 99% of the cases.You don't actually "destroy" anything in D. Even operator delete doesn't do that if it isn't safe, AFAIK - or am I wrong, Walter?-, +, /, and * are usually well defined and all you need. Operators such as new, delete and << and >> could be forbidden.I would leave << and >> there for things like bignum. new and delete should be restricted. Also, I'd add two more built-in operators, "in" and "out". These could be used for streams, stacks, queues, and anything similar that allows to put values in and take them out: int foo, bar; stdout out "Hello, world!\n" out "foo = " out foo out \n; stdin in foo in bar;
Mar 07 2002
Pavel Minayev wrote:"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a68s84$872$1 digitaldaemon.com...Walter may have to correct my memory here, but I think that delete forces destruction of the object. The reason I think that is that I remember arguing with Walter about it, because I thought that it was a bad idea :) -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]Whatever, essentially a notation that says by reference or by value is needed. Assignment by value means deep copy, otherwise destroying one object will render both invalid, not what you would expect in 99% of the cases.You don't actually "destroy" anything in D. Even operator delete doesn't do that if it isn't safe, AFAIK - or am I wrong, Walter?
Mar 08 2002
Pavel Minayev wrote:Also, I'd add two more built-in operators, "in" and "out". These could be used for streams, stacks, queues, and anything similar that allows to put values in and take them out:If you allow infix function calls, then they're not even operators. You just define int stdio::out(char[]) to write. For the input side, you have to change the usage a little to get pointers, but then you define: stdio *stdio::in(int*); stdio *stdio::in(char[]); etc. Maybe I'm missing something...but it seems like it should work, AFAIK. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 08 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C88F341.A4FB9F7E deming-os.org...If you allow infix function calls, then they're not even operators. You just define int stdio::out(char[])Could be. But I thought a separate syntax for operators would be better... well, actually I don't care. Let's leave this to Walter to decide. =)to write. For the input side, you have to change the usage a little to get pointers, but then you define: stdio *stdio::in(int*); stdio *stdio::in(char[]); etc. Maybe I'm missing something...but it seems like it should work, AFAIK.Er... "stdio" is already a pointer. Remember, there are no stack objects in D!
Mar 08 2002
Pavel Minayev wrote:Right. That function I proposed was something that RETURNS a pointer...so that your chain calls could work (it returns 'this'): stdin in &foo in buf; Of course, this would only work if the infix funciton notation allows pointers on the left side. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]to write. For the input side, you have to change the usage a little to get pointers, but then you define: stdio *stdio::in(int*); stdio *stdio::in(char[]); etc. Maybe I'm missing something...but it seems like it should work, AFAIK.Er... "stdio" is already a pointer. Remember, there are no stack objects in D!
Mar 08 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C8909C6.3DEB9FBF deming-os.org...Right. That function I proposed was something that RETURNS a pointer...so that your chain calls could work (it returns 'this'): stdin in &foo in buf;No, I mean that since StdIn is a class, you don't need to use * to state it as a pointer: class StdIn { StdIn read(out int n) // returns a reference to StdIn { ... return this; } } StdIn stdin; stdin read foo read bar read etc; Also, "in" and "out" are reserved D keywords, so they can't be used as function names.Of course, this would only work if the infix funciton notation allowspointerson the left side.I'd be pretty happy to have built-in input/output operators and the ability to overload them, for now.
Mar 08 2002
Pavel Minayev wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3C8909C6.3DEB9FBF deming-os.org...Oops, you're right :(Right. That function I proposed was something that RETURNS a pointer...so that your chain calls could work (it returns 'this'): stdin in &foo in buf;No, I mean that since StdIn is a class, you don't need to use * to state it as a pointer:Also, "in" and "out" are reserved D keywords, so they can't be used as function names.Oops, right again. :( -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Mar 08 2002
"OddesE" <OddesE_XYZ hotmail.com> schrieb im Newsbeitrag news:a68s84$872$1 digitaldaemon.com...Whatever, essentially a notation that says by reference or by value is needed. Assignment by value means deep copy, otherwise destroying one object will render both invalid, not what you would expect in 99% of the cases.Hm, I tend to have pointers in classes without the need to destroy them at ~this, because the main meaning of pointer is (for me), a reference to an object, the class did not own.-, +, /, and * are usually well defined and all you need. Operators such as new, delete and << and >> could be forbidden.I agree. If D allows only to overload "safe" operators, maybe we get some of the advantages together. Whoever, I recommend to allow defining other infix-notation-operators, because this can become VERY handy. As example, I could not believe, that stream-output without infix notation would let to any happy coder ;-) Imi
Mar 08 2002
"Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message news:a6a6n6$q8a$1 digitaldaemon.com...I agree. If D allows only to overload "safe" operators, maybe we get some of the advantages together. Whoever, I recommend to allow defining other infix-notation-operators, because this can become VERY handy. As example, I could not believe, that stream-output without infix notation would let to any happy coder ;-)Well if D would support variants (or object packaging as seen stdout.print("Hello, world!", 666, 123.456); But I guess operator overloading is a better solution. Some kind of operators, like "in" and "out" I've suggested in earlier post, or maybe something like <- and -> ? char[] name; stdin -> name; stdout <- "Hello, " <- name <- "!\n";
Mar 08 2002
"Pavel Minayev" <evilone omen.ru> schrieb im Newsbeitrag news:a6a95d$r51$1 digitaldaemon.com..."Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message news:a6a6n6$q8a$1 digitaldaemon.com...-> has a different meaning. Although it is not used in D, I prefer another symbol. Maybe -=> or >>> ?I agree. If D allows only to overload "safe" operators, maybe we get some of the advantages together. Whoever, I recommend to allow defining other infix-notation-operators, because this can become VERY handy. As example, I could not believe, that stream-output without infix notation would let to any happy coder ;-)Well if D would support variants (or object packaging as seen stdout.print("Hello, world!", 666, 123.456); But I guess operator overloading is a better solution. Some kind of operators, like "in" and "out" I've suggested in earlier post, or maybe something like <- and -> ? char[] name; stdin -> name; stdout <- "Hello, " <- name <- "!\n";
Mar 08 2002
"Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message news:a6ainp$umk$1 digitaldaemon.com...-> has a different meaning. Although it is not used in D, I prefer another symbol. Maybe -=> or >>> ?I remember >>> was unsigned shift. -=> just looks somewhat weird. And what's the problem with -> ? Yes, it had a special meaning in C, but it's not used in D now, and it's quite mnemonic - an arrow pointing "to" or "from" the stream...
Mar 08 2002
"Pavel Minayev" <evilone omen.ru> schrieb im Newsbeitrag news:a6amrk$1091$1 digitaldaemon.com..."Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message news:a6ainp$umk$1 digitaldaemon.com...another-> has a different meaning. Although it is not used in D, I preferHuh... Yes. -} and {- ? or [- and -] or (- and -) ... ? :-)symbol. Maybe -=> or >>> ?I remember >>> was unsigned shift. -=> just looks somewhat weird.And what's the problem with -> ? Yes, it had a special meaning in C, but it's not used in D now, and it's quite mnemonic - an arrow pointing "to" or "from" the stream...The Problem I would have is, that other coder would begin implementing operators after meanings, they saw before, and not after the meaning in the new language. If you are able to overload <<, I bet, some coder disagree with D-conventions and overload << to stream-output... Imi, the paranoic one. (The world is bad... %-) )
Mar 08 2002
"Immanuel Scholz" <digitals-mars kutzsche.net> wrote in message news:a6an6p$10ft$1 digitaldaemon.com...The Problem I would have is, that other coder would begin implementing operators after meanings, they saw before, and not after the meaning in the new language. If you are able to overload <<, I bet, some coder disagree with D-conventions and overload << to stream-output......unless the author of the language and the community STRONGLY DISCOURAGES such use of operators << and >>. Such guys could overload << and >> for themselves, but hopefully libraries which define these operators for such purposes will be boycotted. Also, the simplest way to enfore using operators other than << and >> would be to use their D replacements in Phobos. If streams would use, say, <- and ->, and most programs use streams for some purpose, there probably wouldn't be anybody stupid enough to turn against the mainstream and overload << and >> just to follow C++ conventions... if every D user from the very beginning knows that <- is output and -> is input, it will be very hard to convince them to use some other scheme... Also, define -> to be a _binary_ operator, and there is no way to overload it so it is the same as in C. =)
Mar 08 2002
Pavel Minayev a écrit :if every D user from the very beginning knows that <- is output and -> is input, it will be very hard to convince them to use some other scheme...while you are reconsidering the way stream are implemented, i personally 'feel' better -> as an output and <- as an input..(sorry for the trouble). roland
Mar 08 2002
Roland wrote:Pavel Minayev a écrit :<dripping_sarcasm> Clearly this potential confusion is a compelling argument for eliminating operator overloading, I/O, and the characters '-', '>', and '<' from the language. </dripping_sarcasm> (This isn't at all intended as an attack on your preferences for I/O operators, Roland, but as a snipe at the operator overloading fascists.) -RBif every D user from the very beginning knows that <- is output and -> is input, it will be very hard to convince them to use some other scheme...while you are reconsidering the way stream are implemented, i personally 'feel' better -> as an output and <- as an input..(sorry for the trouble).
Mar 08 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a6anls$10lr$1 digitaldaemon.com......unless the author of the language and the community STRONGLY DISCOURAGES such use of operators << and >>. Such guys could overload << and >> for themselves, but hopefully libraries which define these operators for such purposes will be boycotted.I remember back when C was new and Pascal was the old guard. Many C programmers would write: #define BEGIN { #define END } and other such to make their C look like familiar Pascal'ish. After a couple years of that, it became clear to the entire C community that such was the wrong way to go about programming in C, and the practice disappeared under a torrent of ridicule. It's only natural that programmers moving from C++ to D will start out by programming C++ in D (after all, it's long been recognized that you can write FORTRAN in any language, so why not C++ in D?), and only after a while with the C++isms will get discarded. I myself sometimes catch myself doing things the C++ way in D, and have to go back and rewrite it. For example, I was using memset() when an array assignment was the D way.
Mar 10 2002