D - Operator Overloading vote
- Burton Radons (80/80) Aug 08 2002 I've accidentally implemented operator overloading in my port. It was
- Walter (5/85) Aug 08 2002 In general, I am leaning towards using simple names like add, mul, sub, ...
- Mark Evans (12/12) Aug 08 2002 We should ask C++ experts who write numerical libraries what kind of ope...
- Mark Evans (9/9) Aug 08 2002 In numerical work one typically prefers classes that know how to hand of...
- Mark Evans (2/2) Aug 09 2002 (Although the rope class may be something like what is required...refere...
- Roberto Mariottini (18/21) Aug 09 2002 etc.
- Walter (6/26) Aug 11 2002 be
- Pavel Minayev (77/164) Aug 08 2002 -1
- Patrick Down (46/170) Aug 08 2002 +1
- anderson (42/122) Aug 08 2002 +1
- C.R.Chafer (75/126) Aug 09 2002 [portions snipped to reduce length]
- C.R.Chafer (17/17) Aug 09 2002 For comments additional format (should be just as easy to parse - and th...
- Sean L. Palmer (20/37) Aug 09 2002 I'd be just fine with this:
- Juan Carlos Arevalo Baeza (8/11) Aug 13 2002 This is my favorite syntax, too. For clarity, and to ease parsing, I'...
- Sean L. Palmer (53/133) Aug 09 2002 -1
- Juarez Rudsatz (77/146) Aug 09 2002 +1
- Mark Evans (3/3) Aug 09 2002 Perhaps helpful ideas:
- cblack01 (19/25) Aug 10 2002 +1
- Walter (8/35) Aug 11 2002 You do have a good point.
- Pavel Minayev (5/12) Aug 12 2002 In general, you're right. But me personally, I don't care much about
- Sean L. Palmer (66/78) Aug 13 2002 It doesn't; it deals with the public interface of the class just like
- Dario (33/108) Aug 13 2002 Probably, the simplest solution is to have user-defined opeators at glob...
- anderson (6/25) Aug 13 2002 The major problem with that is, you open a portal for hackers and bad
- Dario (17/44) Aug 13 2002 rejected
- Pavel Minayev (12/16) Aug 13 2002 Why not? You have the interface for the class, so what's the problem?
- Burton Radons (12/32) Aug 13 2002 Hm. Well, since security is intended as protection for the end-user,
- anderson (26/58) Aug 13 2002 Good idea, still kinda breaks data abstraction. However, it means strong
- Pavel Minayev (7/17) Aug 14 2002 If there's something that is forbidden, there will be someone who needs
- anderson (12/29) Aug 15 2002 Parhaps if with statements are included:
- Pavel Minayev (5/14) Aug 14 2002 This one seems to be a neat solution to all problems! No friend declarat...
- anderson (28/108) Aug 13 2002 Yes, I was considering this last week. This was when I was talking about
- Pavel Minayev (15/15) Aug 13 2002 On Tue=2C 13 Aug 2002 21=3A53=3A49 +0800 =22anderson=22 =3Canderson=40fi...
- Walter (6/11) Aug 13 2002 (and
- Walter (24/30) Aug 11 2002 It just occurred to me (I apologize if I missed someone else posting it)
- anderson (20/52) Aug 11 2002 Right, but what about?
- Walter (3/19) Aug 11 2002 It should give an ambiguity error.
- Dario (54/134) Aug 13 2002 -0
- Burton Radons (85/168) Aug 16 2002 +0, -1, +1, +1, +0, -1, +1, +0 = 2.5/8 = +0.3125
- Burton Radons (2/10) Aug 16 2002 Oops. This sums to zero.
- Pavel Minayev (5/13) Aug 17 2002 Citing myself: =)
- Burton Radons (20/38) Aug 17 2002 Through a simple combination of eq and cmp (with bugs, indubitably):
- Walter (7/8) Aug 18 2002 I think it will work right if:
- Pavel Minayev (2/7) Aug 18 2002 Then cmp() needs to be defined as "float cmp(a, b)".
- Walter (4/11) Aug 19 2002 wrote:
- Pavel Minayev (4/7) Aug 20 2002
- Walter (4/5) Aug 20 2002 Correct. But if you overload it, you can change the return type - but be
- Joe Battelle (19/21) Aug 20 2002 Um, I think overload is too strong a word for this. "Fudge" might be mo...
- Walter (8/13) Aug 21 2002 return
- Pavel Minayev (22/22) Aug 20 2002 On Tue=2C 20 Aug 2002 11=3A33=3A34 -0700 =22Walter=22 =3Cwalter=40digita...
- Walter (25/27) Aug 21 2002 The
- Pavel Minayev (7/12) Aug 21 2002 process() doesn't need to know anything of NaNs - but it relies on the
- Martin M. Pedersen (7/10) Aug 21 2002 Hi,
- Pavel Minayev (15/15) Aug 21 2002 On Wed=2C 21 Aug 2002 22=3A11=3A45 +0100 =22Martin M=2E Pedersen=22
- Sean L. Palmer (32/34) Aug 22 2002 Have cmp() return an enum:
- Pavel Minayev (3/12) Aug 22 2002 A nice idea.
- Martin M. Pedersen (6/8) Aug 22 2002 Hi,
- Walter (5/21) Aug 23 2002 The behavior of < and > is defined for NaNs, so there would have two be ...
- Burton Radons (7/18) Aug 21 2002 I don't have a problem with making this change, but I think it should be...
- Walter (7/13) Aug 21 2002 Always returning float has a problem for embedded systems which may want...
- Burton Radons (12/28) Aug 21 2002 Uh, okay, but if float is supported in comparison then float will be
- Walter (8/21) Aug 23 2002 to
- Pavel Minayev (3/11) Aug 17 2002 Now, the question is, what is "static" doing in the syntax? =)
- anderson (5/5) Aug 17 2002 One thing I dissagree with is the way you conducted this survay. Next ti...
- anderson (6/11) Aug 17 2002 Whoops
- Toyotomi (3/8) Aug 21 2002 I'm scared of voting... it's too much like a committee...
-
Walter
(6/7)
Aug 21 2002
I think democratically designed languages tend to be failures
. - Toyotomi (5/12) Aug 21 2002 Glad you see the first bit that way.
- Carlos Santander B. (141/141) Nov 13 2003 Should we vote this again? I mean, there're some complaining about how
- davepermen (170/170) Nov 14 2003 1) "add", "mul", "div", etc.
- Sean L. Palmer (35/79) Nov 21 2003 use my
- davepermen (10/15) Nov 22 2003 You're mistaken. Look again.
- Sean L. Palmer (9/24) Nov 24 2003 Doh! I thought you meant binary as in "not unary", instead of what you
- davepermen (3/6) Nov 24 2003 hehe sorry..
- Matthew Wilson (11/152) Nov 14 2003 I don't care too much about what they're called (although I don't like t...
- Charles Sanders (16/177) Nov 14 2003 Yea but I personally would like this ASAP, i dont like the current
- Matthew Wilson (15/22) Nov 14 2003 1. Operators as instances (C++ syntax, I'm afraid):
I've accidentally implemented operator overloading in my port. It was kind of incidental to other work, so I thought "what the hell" and threw it in. But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic. I'd like Apache-style voting to be used, where the voting is either -1, -0, 0, +0, or +1 for any option, which is a good bellweather of how people think about something. First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b); 2) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b); 3) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b); 4) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b); 5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b); Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b); 2) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b); 3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b); 4) Operator overloading shouldn't be put in (My vote: -1). Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1). 2) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1". Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1) 2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1) 3) a++, a--, --a, ++a. (my vote: 0) 4) a = b. (my vote: 0) 5) a << b, a >> b, a >>> b. (my vote: +1) 6) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1) 7) new, delete. (my vote: -0) 8) a || b, a && b. (my vote: -1) 9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1) 10) a [b]. (my vote: +1) 10a) a [b] = c. (my vote: +0) 11) a [b .. c]. (my vote: +1) 12) &a, *a. (my vote: -1) 13) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b. 13a) a . b, where b can be any type. (my vote: -1) 14) a ? b : c. (my vote: -1) 15) a === b, a !== b. (my vote: 0) 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue. 17) a in b. (my vote: +1) 18) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++. 19) (a, b). (my vote: -1) And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b); 2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b); 2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b); I think that's about it.
Aug 08 2002
In general, I am leaning towards using simple names like add, mul, sub, etc. Reverse operations should be addr, mulr, subr, etc. Overloading should be restricted to arithmetic operators, and no assignment operators. "Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net...I've accidentally implemented operator overloading in my port. It was kind of incidental to other work, so I thought "what the hell" and threw it in. But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic. I'd like Apache-style voting to be used, where the voting is either -1, -0, 0, +0, or +1 for any option, which is a good bellweather of how people think about something. First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b); 2) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b); 3) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b); 4) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b); 5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b); Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b); 2) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b); 3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b); 4) Operator overloading shouldn't be put in (My vote: -1). Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1). 2) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1". Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1) 2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1) 3) a++, a--, --a, ++a. (my vote: 0) 4) a = b. (my vote: 0) 5) a << b, a >> b, a >>> b. (my vote: +1) 6) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1) 7) new, delete. (my vote: -0) 8) a || b, a && b. (my vote: -1) 9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1) 10) a [b]. (my vote: +1) 10a) a [b] = c. (my vote: +0) 11) a [b .. c]. (my vote: +1) 12) &a, *a. (my vote: -1) 13) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b. 13a) a . b, where b can be any type. (my vote: -1) 14) a ? b : c. (my vote: -1) 15) a === b, a !== b. (my vote: 0) 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue. 17) a in b. (my vote: +1) 18) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++. 19) (a, b). (my vote: -1) And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b); 2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b); 2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b); I think that's about it.
Aug 08 2002
We should ask C++ experts who write numerical libraries what kind of operator behavior they dream about at night. (Blitz++ people?) C++ operators limit what characters/strings can be used to represent an operator function. I think those choices should be mine to make: "+special+" should be valid if I want it. I also might ask whether some kind of multipass compilation in D would facilitate more flexibility with operators. It would be cool to define a function and then turn it into an operator by adding certain opeartor-ish attributes like "representative symbol string", "precedence level", and "prefix/infix/postfix". Let alone "associativity" and "commutivity." Well, sorry for giving you a headache Walter, we will like whatever you do. Mark
Aug 08 2002
In numerical work one typically prefers classes that know how to hand off pointers to array data, not classes which mandate private internal copies of the data. STL vectors mandate internal data and it stinks. Something as harmless as A = B invokes a full array copy behind your back. STL vector is thus a poor choice for serious numerical work. I hope that D offers some alternatives here. STL is quite a disappointment because it almost got there with its iterator and smart pointer concepts. Mark
Aug 08 2002
(Although the rope class may be something like what is required...reference counted and all that...M.)
Aug 09 2002
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:aiubuj$2dmc$2 digitaldaemon.com...In general, I am leaning towards using simple names like add, mul, sub,etc.Reverse operations should be addr, mulr, subr, etc. Overloading should be restricted to arithmetic operators, and no assignment operators.Months ago, in an earlier discussion, was advanced the proposal of using _identifiers_ as operators. The proposal was like: Vector mul (Vector a, Vector b) { ... } // one vector multiplication Vector vec (Vector a, Vector b) { ... } // the other ... Vector x = ...; Vector y = ...; Vector w = x :mul: y; Vector z = x :vec: y; Identifier-operators have all the same precedence and are all left-associative and non-commutative. I think this is an easy way to use infix notation for nearly everything, and should be added to D whether other operator overloading is available or not. Ciao.
Aug 09 2002
"Roberto Mariottini" <rmariottini lycosmail.com> wrote in message news:aj03sh$1lar$1 digitaldaemon.com..."Walter" <walter digitalmars.com> ha scritto nel messaggio news:aiubuj$2dmc$2 digitaldaemon.com...beIn general, I am leaning towards using simple names like add, mul, sub,etc.Reverse operations should be addr, mulr, subr, etc. Overloading shouldandrestricted to arithmetic operators, and no assignment operators.Months ago, in an earlier discussion, was advanced the proposal of using _identifiers_ as operators. The proposal was like: Vector mul (Vector a, Vector b) { ... } // one vector multiplication Vector vec (Vector a, Vector b) { ... } // the other ... Vector x = ...; Vector y = ...; Vector w = x :mul: y; Vector z = x :vec: y; Identifier-operators have all the same precedence and are all left-associative and non-commutative. I think this is an easy way to use infix notation for nearly everything,should be added to D whether other operator overloading is available or not.It's a good idea, it would be interesting to see how readable it looks in a non-trivial situation.
Aug 11 2002
On Thu, 08 Aug 2002 06:57:04 -0700 Burton Radons <loth users.sourceforge.net> wrote:First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);-12) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);-13) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b);+04) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);-0 By the way, what about putting the operator in brackets - (*) rather than "*". It just seems to look better that way (at least to me). That one would get +1.5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);0Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);-12) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);+13) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);-04) Operator overloading shouldn't be put in (My vote: -1).-1 !!!Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+12) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".-1Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+12) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+13) a++, a--, --a, ++a. (my vote: 0)+14) a = b. (my vote: 0)-05) a << b, a >> b, a >>> b. (my vote: +1)+06) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1)-07) new, delete. (my vote: -0)-18) a || b, a && b. (my vote: -1)09) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)+110) a [b]. (my vote: +1)+110a) a [b] = c. (my vote: +0)+111) a [b .. c]. (my vote: +1)+112) &a, *a. (my vote: -1)-113) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.013a) a . b, where b can be any type. (my vote: -1)-114) a ? b : c. (my vote: -1)-115) a === b, a !== b. (my vote: 0)016) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.+1 (it might differ for different argument types: for example, <> is not just !eq() for fp-numbers).17) a in b. (my vote: +1)018) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.-1 (good for "variant" types but too weird behaviour).19) (a, b). (my vote: -1)-1And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);+1 (nothing can be better than overloading operator + for ints in your friend's program! =)). Seriously speaking, sometimes you might want to override language defaults. For example, make it so that int / int produces double (rather than int).2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);-12a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);-1
Aug 08 2002
Burton Radons <loth users.sourceforge.net> wrote in news:3D5278B0.1000508 users.sourceforge.net:First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);+12) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);+13) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b);-14) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);-05) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If Ihadto put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);+0Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);+12) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);+03) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);-14) Operator overloading shouldn't be put in (My vote: -1).-0Now, reverse operator handling, where you want the right-sideexpressionto handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+12) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1).For example, "1-A" could become "-A+1".-1Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+1 What about a ~ b2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+13) a++, a--, --a, ++a. (my vote: 0)+14) a = b. (my vote: 0)-15) a << b, a >> b, a >>> b. (my vote: +1)+16) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1)+07) new, delete. (my vote: -0)+18) a || b, a && b. (my vote: -1)-19) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)I like cmp as it is10) a [b]. (my vote: +1)+110a) a [b] = c. (my vote: +0)+111) a [b .. c]. (my vote: +1)+112) &a, *a. (my vote: -1)-113) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.+113a) a . b, where b can be any type. (my vote: -1)-114) a ? b : c. (my vote: -1)-115) a === b, a !== b. (my vote: 0)-116) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.017) a in b. (my vote: +1)+118) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.-119) (a, b). (my vote: -1)-1And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);0 Perhaps on typedefs.2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);0 If it was implemented that x.func(y) could be expressed as (x func y) it might be cool. However I would set them all to be the same precedence.2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);-1I think that's about it.
Aug 08 2002
"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net...I've accidentally implemented operator overloading in my port. It was kind of incidental to other work, so I thought "what the hell" and threw it in. But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic. I'd like Apache-style voting to be used, where the voting is either -1, -0, 0, +0, or +1 for any option, which is a good bellweather of how people think about something. First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);+12) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);03) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b);04) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);+15) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b); Now, where overloaded operators are defined:+11) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);+12) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);-1 (not always)3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);-14) Operator overloading shouldn't be put in (My vote: -1). Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+12) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".-1Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+12) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+13) a++, a--, --a, ++a. (my vote: 0)+14) a = b. (my vote: 0)+15) a << b, a >> b, a >>> b. (my vote: +1)06) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1) 7) new, delete. (my vote: -0)-18) a || b, a && b. (my vote: -1)+19) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)+1 (good for sorting ect...)10) a [b]. (my vote: +1)+110a) a [b] = c. (my vote: +0)011) a [b .. c]. (my vote: +1)+112) &a, *a. (my vote: -1)-113) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.013a) a . b, where b can be any type. (my vote: -1)-114) a ? b : c. (my vote: -1)-115) a === b, a !== b. (my vote: 0)0 (hummm)16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.017) a in b. (my vote: +1)+118) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.+1 (Conversion constructor?)19) (a, b). (my vote: -1)-1And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);-12) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);-12a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);0I think that's about it.PS - This will probably be ignored, but I'd also like +,-,* type operators able to be specified as constructors. I'm not say that it should be the only way of specifying overloading because it's ineffecient. I'm just saying that it's conveniant and logical, because in many cases you normally end up creating a new object anyway. this mul (Vector a, Vector b); //I don't care about the syntax but it shouldn't be static
Aug 08 2002
[portions snipped to reduce length] - Good ideas here is my votes and some comments Burton Radons wrote:First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1)+02) "op_add", "op_mul", "op_div", etc. (my vote: +1)03) "operator +". (my vote: -1)-04) 'operator "+"'. (my vote: -0)05) 'operator (a - b)' or 'operator (this - b)'.+1 But what if you want to call it as a standard function? <added> 6) (added) 'sub operator (a-b)' or 'sub operator (this-b) static Vector sub operator (a - b) (Vector a, Vector b ); +1 </added>1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1).+02) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0).03) Overloaded operators are global functions, using both arguments (My vote: -1).-04) Operator overloading shouldn't be put in (My vote: -1).-11) A second set of potential functions (My vote: +1).+02) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1).-0 (could be useful for error reporting, but a pain to implement)1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+12) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+13) a++, a--, --a, ++a. (my vote: 0)+0 (but mode (a-- or --a) would be a pain without type 5) or *6)* style operator defines)4) a = b. (my vote: 0)-05) a << b, a >> b, a >>> b. (my vote: +1)+16) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1)-0 (could be useful - but probably better to leave seperate)7) new, delete. (my vote: -0)-1 (overloading new & delete is asking for trouble)8) a || b, a && b. (my vote: -1)+09) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)+0 (what about NaN in floats etc)10) a [b]. (my vote: +1)-010a) a [b] = c. (my vote: +0)-111) a [b .. c]. (my vote: +1)012) &a, *a. (my vote: -1)-113) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.013a) a . b, where b can be any type. (my vote: -1)-014) a ? b : c. (my vote: -1)0 (only possible for syntax types 5) & *6)*15) a === b, a !== b. (my vote: 0)-0 (reference compares should remain exactly that - only compare ptr)16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.+0 (again what about NaN in floats)17) a in b. (my vote: +1)+118) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.+0 (there is two types of cast 1. override value (use one bit patten as another type) and 2. alter value (ie convert from float to int) - although type 1 should not be overloaded type 2 should - maybe D needs different syntax for each type of cast?)19) (a, b). (my vote: -1)-1And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1)0 (could be useful - but likely to be misused especially if overloading is global - would only recommend if there were no basic types)2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1)+1 (very useful but two issues 1. precidence (how to set - see below) & 2. syntax / semantic seperation - 2. may be solved by ie prefixing new operators with a special character ie. Vector dot operator (this #dot b ) ( Vector b ); or Vector dot operator (this #dot )2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);+1 needed for defining new operators (else set new ops at fixed precidence) (word "new" is important) C 2002/8/9
Aug 09 2002
For comments additional format (should be just as easy to parse - and the function name could be optional) 6) (added) 'sub operator (a-b)' or 'sub operator (this-b) static Vector sub operator (a - b) (Vector a, Vector b ); +1 EBNF (elc) -> `` assumes function name is optional operatorOverloadFunction : [ "static" ] type [ Identifier ] "operator" "(" form ")" "(" [ arguments ] ")" ; form : operator Identifier | Identifier operator Identifier | Identifier operator ; C 2002/8/9
Aug 09 2002
I'd be just fine with this: Vector operator(Vector a - Vector b) { return a.sub(b); } Vector operator(-Vector a) { return a.negate(); } operators only permitted at module scope. I too would like to see Vector operator(Vector a dot Vector b) { return a.dot(b); } It should be easy enough to parse the declarations out separately from the operator symbols. Sean "C.R.Chafer" <blackmarlin nospam.asean-mail.com> wrote in message news:aj08qk$1qc3$1 digitaldaemon.com...For comments additional format (should be just as easy to parse - and the function name could be optional) 6) (added) 'sub operator (a-b)' or 'sub operator (this-b) static Vector sub operator (a - b) (Vector a, Vector b ); +1 EBNF (elc) -> `` assumes function name is optional operatorOverloadFunction : [ "static" ] type [ Identifier ] "operator" "(" form ")" "(" [ arguments ] ")" ; form : operator Identifier | Identifier operator Identifier | Identifier operator ; C 2002/8/9
Aug 09 2002
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message news:aj0sgr$2fqb$1 digitaldaemon.com...I'd be just fine with this: Vector operator(Vector a - Vector b) Vector operator(-Vector a)This is my favorite syntax, too. For clarity, and to ease parsing, I'd enforce parenthesis for each definition, like this: Vector operator((Vector a) - (Vector b)) Vector operator(-(Vector a)) Salutaciones, JCAB
Aug 13 2002
"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net...I've accidentally implemented operator overloading in my port. It was kind of incidental to other work, so I thought "what the hell" and threw it in. But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic. I'd like Apache-style voting to be used, where the voting is either -1, -0, 0, +0, or +1 for any option, which is a good bellweather of how people think about something. First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);-1 It's unnecessary. If you want it to call a mul function, have the operator call it. Otherwise you can put all the code into the operator.2) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);-13) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b);-1 Screw the tools. Tools can change; it's early enough in the D lifecycle.4) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);-0 (Mainly it shouldn't be a member function)5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);+1 Although the static keyword is unnecessary; they should be able to be defined at global scope. Also the (a - b) part and (Vector a, Vector b) part should be able to be combined into one, something like: Vector operator ( (Vector a) - (Vector b) ) { return a.sub(b); }Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);-1 (though they can *call* methods)2) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);+03) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);+1 (except for unary operators which have only one argument)4) Operator overloading shouldn't be put in (My vote: -1).-99 ;) (ok, really -1)Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+12) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".-0 This could break some code.Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+12) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+03) a++, a--, --a, ++a. (my vote: 0)+14) a = b. (my vote: 0)+0 (This is really useful sometimes in C++, but I can live without it)5) a << b, a >> b, a >>> b. (my vote: +1)+06) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1)+17) new, delete. (my vote: -0)+0 (I'd like some way to change allocation for a class, but not sure overriding new and delete is the best answer. Maybe flag the class as having a special allocator?)8) a || b, a && b. (my vote: -1)-09) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)+1 but it sure would be nice if you didn't have to provide them all (if you override a == b and a < b, it can generate all the other ones automatically)10) a [b]. (my vote: +1)+1 (how else will you make custom containers?)10a) a [b] = c. (my vote: +0)+0 (this needs thought out more, but overriding assignment is useful sometimes)11) a [b .. c]. (my vote: +1)+1 what the hell12) &a, *a. (my vote: -1)-013) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.+0 existing property syntax handles this. Do you mean it can pass b in as a string?13a) a . b, where b can be any type. (my vote: -1)-114) a ? b : c. (my vote: -1)-1 not needed, confusing15) a === b, a !== b. (my vote: 0)016) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.-1 I would only allow overriding == and <17) a in b. (my vote: +1)+018) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.-1 me neither19) (a, b). (my vote: -1)-1 even though I've seen this put to good use in Spirit.And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);+0 So long as it's done through modules and doesn't automatically affect the entire program. It would be useful occasionally (rarely)2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);+1 would be very nice, but hard to implement. I'd like to allow high unicode symbols.2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);+0 would be nice, but it's hard to implement.I think that's about it.Sean
Aug 09 2002
Burton Radons <loth users.sourceforge.net> wrote in news:3D5278B0.1000508 users.sourceforge.net:First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);+1 y = Vector.mul(x); // should be allowed.2) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);-0 Why not opAdd or OpMul or operatorAdd ?3) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as theabovedon't. Vector operator + (Vector b);-04) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);-1 This do not increase parser complexity. * is a token but "*" should be a token or a string. If a string, when it need to be interpreted?5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If Ihadto put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);-1 add new semantic problems: Vector operator (x - y) (Vector a, Vector b); and is similar to Vector operator + (Vector b); only with duplicated parameters.Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);+12) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);-0 Compared with (3), what this add ? Only the position of coding (within the class). But you could not make a additional operations module for another person module. But why separate? if you don't want maintaing that code but you trust in that person. if you need sync and dont wanna make modifications for that code (bug corrections).3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);-0 This could be added later if are needs. And should be consistent with overloading for non-object types.4) Operator overloading shouldn't be put in (My vote: -1).-1Now, reverse operator handling, where you want the right-sideexpressionto handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+12) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1).For example, "1-A" could become "-A+1".-1Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily.I tend to agree with you. except in:4) a = b. (my vote: 0)There are good questions here. 1) a = b + 1; // a and b are the same type is : a.replacedby(b.add(1)); or result = new resultype(); // similar with the above result.add(1); a.replacedby(result); delete result; or a.replacedby(b); a.add(1); 2) a = a + 1; is above or: a.add(1);13) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.What the diference between the properties defined by Walter where a property is a simply procedure or function ?18) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.casting should be explicited in code : int a; currency x; a + x; // error a + cast(int) x; // ok If casting and assignment don't be allowed, for what uses op overloading could be used? I know this is problematic. But could have a restricted version of both.And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);+1 For using with high performance computing like Currency, DateTime, Matematical calculations, ... This could not override built-in defined operations. Than one of operands _must_ be typedef'ed. int operator "a - b" (myType a, int b); And this follows the previous naming scheme: int add(myType a, int b);2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);-02a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);-1 If this will not be allowed now, this could be allowed later. Maybe could be a good decision stay with a little set of features allowing to be increased in future versions of language when the use could be justified by the need. -jr
Aug 09 2002
Perhaps helpful ideas: http://www.boost.org/libs/utility/operators.htm Mark
Aug 09 2002
2) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);+1 Because we are dealing with a Vector-Vector relationship this makes sense, however ...3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);+1 Here we are dealing with relationships, not things specific to any particular object. Operator overloading actually fits the object-relational paradigm better than the object-oriented paradigm. I know OOP purists consider "global" to be morally wrong. But, tell me, to which object does this relationship belong? Vector mul (Vector a, Matrix b); We have a few options. We can put this relationship in the Vector class or we can put in the Matrix class. It's really not entirely clear where it belongs. But it makes more sense to me to define it outside of any class because it doesn't fit the OOP paradigm because it is a relationship between two objects. I'm sorry to burst you OOP purist bubble. Relationships do not fit OOP. Relationships fit the object-relational paradigm. Dare I say the word "multimethods"? Just my two very educated cents. Thanks for listening. Craig
Aug 10 2002
You do have a good point. "cblack01" <cblack01 cox.net> wrote in message news:aj4glg$e61$1 digitaldaemon.com...object-relational2) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);+1 Because we are dealing with a Vector-Vector relationship this makes sense, however ...3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);+1 Here we are dealing with relationships, not things specific to any particular object. Operator overloading actually fits theparadigm better than the object-oriented paradigm. I know OOP purists consider "global" to be morally wrong. But, tell me, to which object does this relationship belong? Vector mul (Vector a, Matrix b); We have a few options. We can put this relationship in the Vector classorwe can put in the Matrix class. It's really not entirely clear where it belongs. But it makes more sense to me to define it outside of any class because it doesn't fit the OOP paradigm because it is a relationshipbetweentwo objects. I'm sorry to burst you OOP purist bubble. Relationships donotfit OOP. Relationships fit the object-relational paradigm. Dare I saytheword "multimethods"? Just my two very educated cents. Thanks for listening. Craig
Aug 11 2002
On Sat, 10 Aug 2002 22:08:32 -0400 "cblack01" <cblack01 cox.net> wrote:We have a few options. We can put this relationship in the Vector class or we can put in the Matrix class. It's really not entirely clear where it belongs. But it makes more sense to me to define it outside of any class because it doesn't fit the OOP paradigm because it is a relationship between two objects. I'm sorry to burst you OOP purist bubble. Relationships do not fit OOP. Relationships fit the object-relational paradigm. Dare I say the word "multimethods"? Just my two very educated cents.In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...
Aug 12 2002
It doesn't; it deals with the public interface of the class just like everybody else. Kinda makes me wish for friendship declarations but I'm not opposed to putting "readable" member functions that actually do the work and simple operators that just call those functions. Gotta trust the compiler to inline stuff properly though. Those folks seriously opposed to operator overloading can just use the "readable" versions directly. That does bring up a point though. How do you deal with this situation in D? class vector { private float x,y,z,w; } class matrix { private vector x,y,z,w; } vector operator (matrix a * vector b) { return vector (a.x.x * b.x + a.x.y * b.y + a.x.z * b.z + a.x.w * b.w, a.y.x * b.x + a.y.y * b.y + a.y.z * b.z + a.y.w * b.w, a.z.x * b.x + a.z.y * b.y + a.z.z * b.z + a.z.w * b.w, a.w.x * b.x + a.w.y * b.y + a.w.z * b.z + a.w.w * b.w); } Won't compile because obviously xyzw are all private in both classes. So how to fix it? class vector { private float x,y,z,w; } class matrix { private vector x,y,z,w; public vector transform(vector b) { return vector (x.x * b.x + x.y * b.y + x.z * b.z + x.w * b.w, y.x * b.x + y.y * b.y + y.z * b.z + y.w * b.w, z.x * b.x + z.y * b.y + z.z * b.z + z.w * b.w, w.x * b.x + w.y * b.y + w.z * b.z + w.w * b.w); } } vector operator (matrix a * vector b) { return a.transform(b); } That still doesn't work because matrix can't access members of vector. And it won't work if you put transform into class vector either. Have to expose some way to get at the private data, which kind of misses the point of making it private to begin with. For this kind of thing I'd probably just make the members public anyway (and use structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change. But it's not hard to imagine some other situations like this. Without "friend" in C++, how would you handle this situation without violating the privacy of the classes? Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374805064096759 news.digitalmars.com...On Sat, 10 Aug 2002 22:08:32 -0400 "cblack01" <cblack01 cox.net> wrote:orWe have a few options. We can put this relationship in the Vector classclasswe can put in the Matrix class. It's really not entirely clear where it belongs. But it makes more sense to me to define it outside of anybetweenbecause it doesn't fit the OOP paradigm because it is a relationshipnottwo objects. I'm sorry to burst you OOP purist bubble. Relationships dothefit OOP. Relationships fit the object-relational paradigm. Dare I sayword "multimethods"? Just my two very educated cents.In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...
Aug 13 2002
Probably, the simplest solution is to have user-defined opeators at global level and let them access private member of the classes which they have as arguments. e.g. class Vector { private float x, y, z, w; } class Matrix { private float x, y, z, w; } Vector operator(Vector a * Matrix b) { /* here this function is able to access private members of classes Vector and Matrix */ } I apologize if anyone has proposed this solution and it has been rejected already. ___________________________________________________It doesn't; it deals with the public interface of the class just like everybody else. Kinda makes me wish for friendship declarations but I'm not opposed to putting "readable" member functions that actually do the work and simple operators that just call those functions. Gotta trust the compiler to inline stuff properly though. Those folks seriously opposed to operator overloading can just use the "readable" versions directly. That does bring up a point though. How do you deal with this situation in D? class vector { private float x,y,z,w; } class matrix { private vector x,y,z,w; } vector operator (matrix a * vector b) { return vector (a.x.x * b.x + a.x.y * b.y + a.x.z * b.z + a.x.w * b.w, a.y.x * b.x + a.y.y * b.y + a.y.z * b.z + a.y.w*b.w, a.z.x * b.x + a.z.y * b.y + a.z.z * b.z + a.z.w*b.w, a.w.x * b.x + a.w.y * b.y + a.w.z * b.z + a.w.w*b.w); } Won't compile because obviously xyzw are all private in both classes. So how to fix it? class vector { private float x,y,z,w; } class matrix { private vector x,y,z,w; public vector transform(vector b) { return vector (x.x * b.x + x.y * b.y + x.z * b.z + x.w * b.w, y.x * b.x + y.y * b.y + y.z * b.z + y.w *b.w,z.x * b.x + z.y * b.y + z.z * b.z + z.w *b.w,w.x * b.x + w.y * b.y + w.z * b.z + w.w * b.w); } } vector operator (matrix a * vector b) { return a.transform(b); } That still doesn't work because matrix can't access members of vector.Andit won't work if you put transform into class vector either. Have toexposesome way to get at the private data, which kind of misses the point of making it private to begin with. For this kind of thing I'd probably just make the members public anyway(anduse structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change. But it's not hard to imaginesomeother situations like this. Without "friend" in C++, how would you handle this situation without violating the privacy of the classes? SeanclassWe have a few options. We can put this relationship in the Vectororitwe can put in the Matrix class. It's really not entirely clear wheredoclassbelongs. But it makes more sense to me to define it outside of anybetweenbecause it doesn't fit the OOP paradigm because it is a relationshiptwo objects. I'm sorry to burst you OOP purist bubble. Relationshipsnotsayfit OOP. Relationships fit the object-relational paradigm. Dare Itheword "multimethods"? Just my two very educated cents.In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...
Aug 13 2002
"Dario" <supdar yahoo.com> wrote in message news:ajb1or$14nq$1 digitaldaemon.com...Probably, the simplest solution is to have user-defined opeators at global level and let them access private member of the classes which they have as arguments. e.g. class Vector { private float x, y, z, w; } class Matrix { private float x, y, z, w; } Vector operator(Vector a * Matrix b) { /* here this function is able to access private members of classes Vector and Matrix */ } I apologize if anyone has proposed this solution and it has been rejected already.The major problem with that is, you open a portal for hackers and bad coding. People will missuse these operators simply for the sake of getting at private members when they should use other means. This would defeat the purpose of operators in the first place.
Aug 13 2002
globalProbably, the simplest solution is to have user-defined opeators ataslevel and let them access private member of the classes which they haverejectedarguments. e.g. class Vector { private float x, y, z, w; } class Matrix { private float x, y, z, w; } Vector operator(Vector a * Matrix b) { /* here this function is able to access private members of classes Vector and Matrix */ } I apologize if anyone has proposed this solution and it has beenalready.The major problem with that is, you open a portal for hackers and bad coding. People will missuse these operators simply for the sake of getting at private members when they should use other means. This would defeat the purpose of operators in the first place.I don't understand what you mean exactly. There are programming language which are OO but don't support class privacy (Python is an example). In these languages the interface is simply a convention which programmers aren't forced to respect. Is this agains the concept of OO programming? Moreover, since D supports pointer arithmetic you _can_ access private members that way. Ok, you will probably never want to, but "hacking" isn't totally prevented as you can see. But since D has the capability to change the member order, very few people will do such a "hack". Anyway shouldn't a programmer who want to access a private member simply make that member public modifying the class source code? (If the class is totally contained in an .obj file (as distributed classes usually are), you obviouly won't be able to write a new operator for that class, will you?)
Aug 13 2002
On Tue, 13 Aug 2002 21:10:27 +0200 "Dario" <supdar yahoo.com> wrote:Anyway shouldn't a programmer who want to access a private member simply make that member public modifying the class source code? (If the class is totally contained in an .obj file (as distributed classes usually are), you obviouly won't be able to write a new operator for that class, will you?)Why not? You have the interface for the class, so what's the problem? Besides, it could be useful to glue libraries together: for example, in C++, you might want to overload << to output matrices from math lib to streams from STL. Neither class is yours (and you might not even have the source for them!), but overloading is possible. Anyhow, I think the "security reasons" aren't strong enough... if one really really needs to get to a private member somehow, it is in fact better to have at least portable solution (operator overloading) than using pointers... Misuse? Yes. And who cares? Overloading operator just to be able to access private member is a too complex solution to be used widely, so it might be used only by a few hackers here and there, mostly in low-level libs and such.
Aug 13 2002
Pavel Minayev wrote:On Tue, 13 Aug 2002 21:10:27 +0200 "Dario" <supdar yahoo.com> wrote:Anyway shouldn't a programmer who want to access a private member simply make that member public modifying the class source code? (If the class is totally contained in an .obj file (as distributed classes usually are), you obviouly won't be able to write a new operator for that class, will you?)Why not? You have the interface for the class, so what's the problem? Besides, it could be useful to glue libraries together: for example, in C++, you might want to overload << to output matrices from math lib to streams from STL. Neither class is yours (and you might not even have the source for them!), but overloading is possible.Anyhow, I think the "security reasons" aren't strong enough... if one really really needs to get to a private member somehow, it is in fact better to have at least portable solution (operator overloading) than using pointers... Misuse? Yes. And who cares? Overloading operator just to be able to access private member is a too complex solution to be used widely, so it might be used only by a few hackers here and there, mostly in low-level libs and such.Hm. Well, since security is intended as protection for the end-user, and emphatically not like lock box security, perhaps it should be spoofable a la const: (public) a.x; Or if that's not noticeable enough: cast (public) a.x; Thus the preference will be to use properties and methods to manipulate a class's internals, but there's a recourse if the class was incorrectly written. I've always been troubled about C++'s lack of recourse; it makes bad situations a gazillion times worse. I almost always use "// private:" and "// protected:" simply because of this.
Aug 13 2002
Good idea, still kinda breaks data abstraction. However, it means strong typing ;). Perhaps something like: access(a) { a.x = ...; a.b = ...; } Parhaps there could be something known as strong privates and protected that still can't be accessed: strong private: int x; strong protected: int y; This way you could still protect you data abstraction if you really need to. I think that'll satify both groups. "Burton Radons" <loth users.sourceforge.net> wrote in message news:3D597876.9080108 users.sourceforge.net...Pavel Minayev wrote:isOn Tue, 13 Aug 2002 21:10:27 +0200 "Dario" <supdar yahoo.com> wrote:Anyway shouldn't a programmer who want to access a private member simply make that member public modifying the class source code? (If the classyoutotally contained in an .obj file (as distributed classes usually are),you?)obviouly won't be able to write a new operator for that class, willreallyWhy not? You have the interface for the class, so what's the problem? Besides, it could be useful to glue libraries together: for example, in C++, you might want to overload << to output matrices from math lib to streams from STL. Neither class is yours (and you might not even have the source for them!), but overloading is possible.Anyhow, I think the "security reasons" aren't strong enough... if onepointers...really needs to get to a private member somehow, it is in fact better to have at least portable solution (operator overloading) than usingaccessMisuse? Yes. And who cares? Overloading operator just to be able tobeprivate member is a too complex solution to be used widely, so it mightsuch.used only by a few hackers here and there, mostly in low-level libs andHm. Well, since security is intended as protection for the end-user, and emphatically not like lock box security, perhaps it should be spoofable a la const: (public) a.x; Or if that's not noticeable enough: cast (public) a.x; Thus the preference will be to use properties and methods to manipulate a class's internals, but there's a recourse if the class was incorrectly written. I've always been troubled about C++'s lack of recourse; it makes bad situations a gazillion times worse. I almost always use "// private:" and "// protected:" simply because of this.
Aug 13 2002
On Wed, 14 Aug 2002 11:04:22 +0800 "anderson" <anderson firestar.com.au> wrote:Parhaps there could be something known as strong privates and protected that still can't be accessed: strong private: int x; strong protected: int y;If there's something that is forbidden, there will be someone who needs it badly!This way you could still protect you data abstraction if you really need to. I think that'll satify both groups.I don't think one really needs to protect data abstraction to that level. A simple private declaration would be enough to tell both the compiler and the user that this member is not to be messed with. If the user, for some reason, decides to, it should be his right - and his problems. =)
Aug 14 2002
Parhaps if with statements are included: with (private) a; { .x = .. .y = .. } Just to save on that messy casting (but also alow casting of course). "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374824929020255 news.digitalmars.com...On Wed, 14 Aug 2002 11:04:22 +0800 "anderson" <anderson firestar.com.au>wrote:thatParhaps there could be something known as strong privates and protectedto.still can't be accessed: strong private: int x; strong protected: int y;If there's something that is forbidden, there will be someone who needs it badly!This way you could still protect you data abstraction if you really needI think that'll satify both groups.I don't think one really needs to protect data abstraction to that level. A simple private declaration would be enough to tell both the compiler and the user that this member is not to be messed with. If the user, for some reason, decides to, it should be his right - and his problems. =)
Aug 15 2002
On Tue, 13 Aug 2002 14:21:58 -0700 Burton Radons <loth users.sourceforge.net> wrote:Hm. Well, since security is intended as protection for the end-user, and emphatically not like lock box security, perhaps it should be spoofable a la const: (public) a.x; Or if that's not noticeable enough: cast (public) a.x;This one seems to be a neat solution to all problems! No friend declarations etc, but you're still able to play with private data as you like when it comes to that. And the syntax is rather clear. I vote +1.
Aug 14 2002
Yes, I was considering this last week. This was when I was talking about using some type of protection mechinism (permission) like lynux does rwx rwx rwx (i think...). So you could put classes into differn't groups with differn't permissions. This of course would have other added advantages. It could be applied at the package, class, method and private method. Private, protected and public would still apply. However I don't know how this would look (it should be simple and small). Java allows packages to access private members in that package. That's a simular but more basic approach to this idea. The standard method in C++ was to return each member by a get/set witch was laborious and sometimes broke a class. I think Pavel indicates that the his static version idea could have access to both (or the present???) class privates. "Sean L. Palmer" <seanpalmer earthlink.net> wrote in message news:ajac46$fg0$1 digitaldaemon.com...It doesn't; it deals with the public interface of the class just like everybody else. Kinda makes me wish for friendship declarations but I'm not opposed to putting "readable" member functions that actually do the work and simple operators that just call those functions. Gotta trust the compiler to inline stuff properly though. Those folks seriously opposed to operator overloading can just use the "readable" versions directly. That does bring up a point though. How do you deal with this situation in D? class vector { private float x,y,z,w; } class matrix { private vector x,y,z,w; } vector operator (matrix a * vector b) { return vector (a.x.x * b.x + a.x.y * b.y + a.x.z * b.z + a.x.w * b.w, a.y.x * b.x + a.y.y * b.y + a.y.z * b.z + a.y.w*b.w, a.z.x * b.x + a.z.y * b.y + a.z.z * b.z + a.z.w*b.w, a.w.x * b.x + a.w.y * b.y + a.w.z * b.z + a.w.w*b.w); } Won't compile because obviously xyzw are all private in both classes. So how to fix it? class vector { private float x,y,z,w; } class matrix { private vector x,y,z,w; public vector transform(vector b) { return vector (x.x * b.x + x.y * b.y + x.z * b.z + x.w * b.w, y.x * b.x + y.y * b.y + y.z * b.z + y.w *b.w,z.x * b.x + z.y * b.y + z.z * b.z + z.w *b.w,w.x * b.x + w.y * b.y + w.z * b.z + w.w * b.w); } } vector operator (matrix a * vector b) { return a.transform(b); } That still doesn't work because matrix can't access members of vector.Andit won't work if you put transform into class vector either. Have toexposesome way to get at the private data, which kind of misses the point of making it private to begin with. For this kind of thing I'd probably just make the members public anyway(anduse structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change. But it's not hard to imaginesomeother situations like this. Without "friend" in C++, how would you handle this situation without violating the privacy of the classes? Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374805064096759 news.digitalmars.com...classOn Sat, 10 Aug 2002 22:08:32 -0400 "cblack01" <cblack01 cox.net> wrote:We have a few options. We can put this relationship in the Vectororitwe can put in the Matrix class. It's really not entirely clear wheredoclassbelongs. But it makes more sense to me to define it outside of anybetweenbecause it doesn't fit the OOP paradigm because it is a relationshiptwo objects. I'm sorry to burst you OOP purist bubble. Relationshipsnotsayfit OOP. Relationships fit the object-relational paradigm. Dare Itheword "multimethods"? Just my two very educated cents.In general, you're right. But me personally, I don't care much about OOP purity or something like that... tell me, in your scheme, how does an overloaded operator, being a global function, accesses private members of classes? It is almost always needed...
Aug 13 2002
On Tue=2C 13 Aug 2002 21=3A53=3A49 +0800 =22anderson=22 =3Canderson=40firestar=2Ecom=2Eau=3E wrote=3A =3E Java allows packages to access private members in that package=2E That's a =3E simular but more basic approach to this idea=2E This is basically the same as C++'s friend=2C only applied automatically=2E =3E I think Pavel indicates that the his static version idea could have access =3E to both =28or the present=3F=3F=3F=29 class privates=2E Well=2C any static function can access class privates=2E But only the one it resides in=2E My first proposal was that operator can access private members of classes of operands and result=2E For example=3A =09Foo operator=28Bar a + Baz b=29=3B This one can access private members of classes Foo=2C Bar and Baz directly=2E Kinda auto-friend again=2E Unless you care much of OOP purity=2C it seems the simplest =28both to implement and to use=29 approach=2E=2E=2E
Aug 13 2002
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message news:ajac46$fg0$1 digitaldaemon.com...For this kind of thing I'd probably just make the members public anyway(anduse structs instead of classes) just because I like to get at the members easily and they rarely, if ever, change. But it's not hard to imaginesomeother situations like this. Without "friend" in C++, how would you handle this situation without violating the privacy of the classes?It's an interesting problem. I just don't like the C++ "friend" syntax and semantics. There's got to be a better way.
Aug 13 2002
"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net...Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1). 2) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".It just occurred to me (I apologize if I missed someone else posting it) that the language can make the commutative operators (+, *, |, &, etc.) commutative even with operator overloads, with the proviso that if a reverse overload was provided, that would be used instead. For example: class A { A add(int); } A a; a+1 => a.add(1) 1+a => a.add(1) But if: class A { A add(int); A add_r(int); } A a; a+1 => a.add(1) 1+a => a.add_r(1) This seems to have the advantage of both schemes, and minimizes the need for a plethora of functions being defined just for swizzling the arguments.
Aug 11 2002
Right, but what about? class A { A add(B); A add_r(B); } class B { B add(A); B add_r(A); } I suppose this may be illegal? A a; B b; a+b => a.add(b) & b.add(a) b+a => a.add_r(b) & b.add_r(a) "Walter" <walter digitalmars.com> wrote in message news:aj6gbt$2c7b$1 digitaldaemon.com..."Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net...reverseNow, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1). 2) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".It just occurred to me (I apologize if I missed someone else posting it) that the language can make the commutative operators (+, *, |, &, etc.) commutative even with operator overloads, with the proviso that if aoverload was provided, that would be used instead. For example: class A { A add(int); } A a; a+1 => a.add(1) 1+a => a.add(1) But if: class A { A add(int); A add_r(int); } A a; a+1 => a.add(1) 1+a => a.add_r(1) This seems to have the advantage of both schemes, and minimizes the needfora plethora of functions being defined just for swizzling the arguments.
Aug 11 2002
It should give an ambiguity error. "anderson" <anderson firestar.com.au> wrote in message news:aj74ij$2v6e$1 digitaldaemon.com...Right, but what about? class A { A add(B); A add_r(B); } class B { B add(A); B add_r(A); } I suppose this may be illegal? A a; B b; a+b => a.add(b) & b.add(a) b+a => a.add_r(b) & b.add_r(a)
Aug 11 2002
Here are my votesI've accidentally implemented operator overloading in my port. It was kind of incidental to other work, so I thought "what the hell" and threw it in. But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic. I'd like Apache-style voting to be used, where the voting is either -1, -0, 0, +0, or +1 for any option, which is a good bellweather of how people think about something. First off, the naming scheme: 1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);+02) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);-03) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b);-04) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);-05) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);+0 Even better the sintax someone has proposed: // global function Vector operator(Vector a - Vector b);Now, where overloaded operators are defined: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);0 This vote is because the compiler won't be able to choose between a.add(b) and b.addr(a). The compiler will emit an ambiguity error and this will be _very_ frustrating to fix.2) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);-1 Static operators are not overridable.3) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);+14) Operator overloading shouldn't be put in (My vote: -1).-0 (to be sincere I have rarely used it...)Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+12) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".-1Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+12) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+13) a++, a--, --a, ++a. (my vote: 0)-0 This should be equivalent to a = a + 1, etc.4) a = b. (my vote: 0)+05) a << b, a >> b, a >>> b. (my vote: +1)+16) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1)-1 This should always be equivalent to a = a + b, etc.7) new, delete. (my vote: -0)08) a || b, a && b. (my vote: -1)+0 Why not???9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)+0 If we let op= to be overloaded, why not these?10) a [b]. (my vote: +1)+110a) a [b] = c. (my vote: +0)+1 Maybe there is a way to use settors?11) a [b .. c]. (my vote: +1)+112) &a, *a. (my vote: -1)-113) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.-1 What is this needed for?13a) a . b, where b can be any type. (my vote: -1)-114) a ? b : c. (my vote: -1)-115) a === b, a !== b. (my vote: 0)-116) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.+017) a in b. (my vote: +1)+118) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.-119) (a, b). (my vote: -1)-1 Why a(b) not? This gets +0And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);-1 This invalidates code.2) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);02a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);-1 This is too error-prone.I think that's about it.
Aug 13 2002
The polls are closed. I'll try to pool the write-in candidates. For summing, -1, -0, 0, +0, and +1 are recorded as -2, -1, 0, +1, and +2.1) "add", "mul", "div", etc. (my vote: +1) Vector mul (Vector b); Vector div (Vector b);+0, -1, +1, +1, +0, -1, +1, +0 = 2.5/8 = +0.3125 My vote on this has changed to +0. Although I'm not sure I like the syntax, "((Vector a) * (extended b))" is definitely clearer and handles reverse and the post/pre-increment/decrement far more elegantly.2) "op_add", "op_mul", "op_div", etc. (my vote: +1) Vector op_sub (Vector b); Vector op_mod (Vector b);+0, -1, +1, 0, 0, -1, -0, -0 = -3/8 = -0.375 Juarez suggested "opAdd" or "operator Add".3) "operator +". (my vote: -1) My vote is because I find this syntax confusing in C++, particularly with its wide expressiveness, and I admire any syntax which doesn't require a change to tools, as the above don't. Vector operator + (Vector b);-1, +0, -1, 0, -0, -1, -0, -0 = -8/8 = -14) 'operator "+"'. (my vote: -0) For some reason I find this less visually disconcerting. Vector operator "*" (Vector b);-0, -0, -0, +1, 0, -0, -1, -0 = -5/8 = -0.625 Pavel suggested (*). My preference here was because it causes the syntax highlighter to mark it nicely, so it doesn't get lost in a sea of parentheses.5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);+0, 0, +0, +1, +1, -1, +0 = 5/7 = 0.7143 Pavel, you didn't +1 anything here. Do you have any syntax in mind, or are they all equally evil? C.R. suggested "static Vector sub operator (a - b) (Vector a, Vector b)". I'll merge this with "static Vector operator (Vector a - Vector b)". If I decide to use this - and it seems quite likely - then I'll get more opinions there.1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);+1, -1, +1, +1, +0, -1, +1, 0 = 5/8 = 0.6252) Overloaded operators are always static methods with both left and right arguments defined (My vote: 0). static Vector add (Vector a, Vector b);0, +1, +0, -1, 0, +0, -0, +1, -1 = 1/9 = 0.1113) Overloaded operators are global functions, using both arguments (My vote: -1). Vector add (Vector a, Vector b);-1, -0, -0, -1, -0, +1, -0, +1, +1 = -2/9 = 0.2224) Operator overloading shouldn't be put in (My vote: -1).-1, -1, -0, -1, -1, -1, -0 = -12/7 = -1.714 Honesty much appreciated, Dario.Now, reverse operator handling, where you want the right-side expression to handle the evaluation, such as with the form "int * Vector": 1) A second set of potential functions (My vote: +1).+1, +1, +1, +1, +0, +1, +1, +1 = 15/8 = 1.8752) Automatic reorganization of the expression. This makes assumptions about what the operators do and can't handle "1 / Vector" (My vote: -1). For example, "1-A" could become "-A+1".-1, -1, -1, -1, -0, -0, -1, -1 = -14/8 = -1.75Now for the operations covered. Please be temperate with your votes - operations can be added later, but they can't be removed as easily. 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1)+1, +1, +1, +1, +1, +1, +1 = 14/7 = 2 Patrick reminded me about a ~ b. I'll pool that with (10).2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1)+1, +1, +1, +1, +1, +0, -1, +1 = 11/8 = 1.3753) a++, a--, --a, ++a. (my vote: 0)0, +1, +1, +1, +0, +1, -0 = 8/7 = 1.14294) a = b. (my vote: 0)-1, -0, -1, +1, -0, +0, +0 = -2/7 = -0.2857 I changed my vote.5) a << b, a >> b, a >>> b. (my vote: +1)+1, +0, +1, 0, +1, +1, +1 = 11/7 = 1.57146) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1)-1, -0, +0, -0, +1, -1 = -3/6 = -0.57) new, delete. (my vote: -0)-0, -1, +1, -1, -1, +0, 0 = -4/7 = -0.57148) a || b, a && b. (my vote: -1)-1, 0, -1, +1, +0, -0, +0 = -1/7 = -0.1429 The argument against this one is that like the trinary operator, it's impossible to duplicate the current semantics. The builtin and the overloaded operator are not the same in any way, so it seems wrong to give them the same name. Being able to test for nonzero is helpful, though.9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1)-1, +1, -1, +1, +0, +1, +0 = 4/7 = 0.5714 This confused some people. You can already overload cmp, which already gives enough information to do these operators. I don't see how one could require more than that without breaking the basic meaning of the operators - and I definitely don't see any reason to care about people who WANT to break the basic meaning of the operators.10) a [b]. (my vote: +1)+1, +1, +1, +1, -0, +1, +1 = 11/7 = 1.571410a) a [b] = c. (my vote: +0)+0, +1, +1, 0, -1, +0, +1 = 6/7 = 0.857111) a [b .. c]. (my vote: +1)+1, +1, +1, +1, 0, +1, +1 = 12/7 = 1.714312) &a, *a. (my vote: -1)-1, -1, -1, -1, -1, -0, -1 = 13/7 = -1.857113) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note that this won't allow just anything in b.+1, 0, +1, 0, 0, +0, -1 = 3/7 = 0.4286 Another one that confused people. A sample: struct PyObject { PyObject operator getattr (char [] name) { PyObject string, result; string = new PyStringObject (name); result = type.getAttr (string); string.decref (); return incref (result); } } py.foo; /* Calls getattr if the field doesn't exist otherwise */13a) a . b, where b can be any type. (my vote: -1)-1, -1, -1, -1, -0, -1, -1 = -13/7 = -1.857114) a ? b : c. (my vote: -1)-1, -1, -1, -1, 0, -1, -1 = -12/7 = -1.714315) a === b, a !== b. (my vote: 0)0, 0, -1, 0, -0, 0, -1 = -5/8 = -0.62516) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.0, +1, 0, 0, +0, -1, +0 = 2/7 = 0.2857 The same argument as >=, >, <, <= above. This is simply implemented as a combination of eq and cmp, which expresses everything we need to do these properly. Explicitly allowing them is confusing.17) a in b. (my vote: +1)+1, 0, +1, +1, +1, +0, +1 = 11/7 = 1.571418) cast (b) a. (my vote: -0) I haven't had any good experiences with cast overloading in C++.-1, -0, -1, +1, +0, -1, -1 = -6/7 = -0.857119) (a, b). (my vote: -1)-1, -1, -1, -1, -1, -1, -1 = -14/7 = -2 Dario reminded me of a(b). Forgot about that one. I can't pool that into any other operator, so is anyone opposed to it?And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);-1, +1, 0, -1, 0, +0, +1, -12) Definition of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) Vector operator (this dot b) (Vector b);-1, -1, 0, -1, +1, +1, -0, 0 = -3/8 = -0.375 Patrick suggested allowing "a.func (b)" to be written as "a func b". IMO they mean the exact same thing, I just can't figure out what precedence the second is given. Most of the time you'd write "(a func b)" to be clear, at which point you're saving no characters at all, so why not express it normally?2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. (my vote: -1) operator (a dot b) above (a >= b) below (a * b);-1, -1, -1, 0, +1, +0, +0, -1, -1 = -6/9 = -0.6667
Aug 16 2002
Burton Radons wrote:Oops. This sums to zero.And miscellaneous: 1) Operator overloading should be allowed on basic types as global functions. (my vote: -1) int operator "a - b" (int a, int b);-1, +1, 0, -1, 0, +0, +1, -1
Aug 16 2002
On Fri, 16 Aug 2002 19:49:01 -0700 Burton Radons <loth users.sourceforge.net> wrote:Pavel, you didn't +1 anything here. Do you have any syntax in mind, or are they all equally evil?Citing myself: =)This is NOT just a simple combination of eq() and cmp() - how would you express D floating-point comparisons (RTFM!) this way?16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.The same argument as >=, >, <, <= above. This is simply implemented as a combination of eq and cmp, which expresses everything we need to do these properly. Explicitly allowing them is confusing.
Aug 17 2002
Pavel Minayev wrote:On Fri, 16 Aug 2002 19:49:01 -0700 Burton Radons<loth users.sourceforge.net>wrote:Through a simple combination of eq and cmp (with bugs, indubitably): == is eq != is !eqPavel, you didn't +1 anything here. Do you have any syntax in mind, or are they all equally evil?Citing myself: =)This is NOT just a simple combination of eq() and cmp() - how would you express D floating-point comparisons (RTFM!) this way?16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) IMO this is an eq/cmp combination issue.The same argument as >=, >, <, <= above. This is simply implemented as a combination of eq and cmp, which expresses everything we need to do these properly. Explicitly allowing them is confusing.is cmp > 0 = is cmp >= 0 or eq< is cmp < 0 <= is cmp <= 0 or eq !<>= is !cmp and !eq <> is cmp <>= is cmp or eq !<= is cmp <= 0 or !eq !< is cmp < 0 or !eq !>= is cmp >= 0 or !eq !> is cmp > 0 or !eq !<> is cmp or !eq For the operations which can throw exceptions, we could leave them alone if only cmp or eq are overloaded, and throw if they're incompatible - for example, with <=, if cmp returns zero but eq returns false, it's unordered, hence one is NaN and an exception can be thrown. Walter, could you back one of us up here, please?
Aug 17 2002
"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5F0476.1060203 users.sourceforge.net...Walter, could you back one of us up here, please?I think it will work right if: a op b is rewritten as: a.cmp(b) op 0 For the nan cases, the cmp function can return nan's.
Aug 18 2002
On Sun, 18 Aug 2002 16:47:56 -0700 "Walter" <walter digitalmars.com> wrote:I think it will work right if: a op b is rewritten as: a.cmp(b) op 0 For the nan cases, the cmp function can return nan's.Then cmp() needs to be defined as "float cmp(a, b)".
Aug 18 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374873976712963 news.digitalmars.com...On Sun, 18 Aug 2002 16:47:56 -0700 "Walter" <walter digitalmars.com>wrote:Yes - you can define it to return anything you want <g>.I think it will work right if: a op b is rewritten as: a.cmp(b) op 0 For the nan cases, the cmp function can return nan's.Then cmp() needs to be defined as "float cmp(a, b)".
Aug 19 2002
On Mon, 19 Aug 2002 17:52:08 -0700 "Walter" <walter digitalmars.com> wrote:Doesn't Object define it as int cmp() already?Then cmp() needs to be defined as "float cmp(a, b)".Yes - you can define it to return anything you want <g>.
Aug 20 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374884975017593 news.digitalmars.com...Doesn't Object define it as int cmp() already?Correct. But if you overload it, you can change the return type - but be aware that will create more than one entry for cmp in the vtbl[].
Aug 20 2002
Correct. But if you overload it, you can change the return type - but be aware that will create more than one entry for cmp in the vtbl[].Um, I think overload is too strong a word for this. "Fudge" might be more accurate <g>. It might be good if you could overload based on just the return type--but you can't in the current implementation. For example, this bogus code won't compile: class A { int neg() { return -1; } char[] neg() { return "-1"; } void neg() { assert(false); } } void foo() { A a; -a; int i = -a; char[] s = -a; } Though, FWIW, it should be noted that if you fudge the return type of neg to void and don't provide the other overloads, you can keep the operator from being used to create an rvalue.
Aug 20 2002
"Joe Battelle" <Joe_member pathlink.com> wrote in message news:aju8ag$1s8n$1 digitaldaemon.com...returnCorrect. But if you overload it, you can change the return type - but be aware that will create more than one entry for cmp in the vtbl[].Um, I think overload is too strong a word for this. "Fudge" might be more accurate <g>. It might be good if you could overload based on just thetype--but you can't in the current implementation.What you'd have to do for cmp is provide two functions: class MyFloat { int cmp(Object o); float cmp(MyFloat f); }
Aug 21 2002
On Tue=2C 20 Aug 2002 11=3A33=3A34 -0700 =22Walter=22 =3Cwalter=40digitalmars=2Ecom=3E wrote=3A =3E Correct=2E But if you overload it=2C you can change the return type - but be =3E aware that will create more than one entry for cmp in the vtbl=5B=5D=2E Then=2C take a look at this=3A =09class Foo =09{ =09=09float cmp=28=29 { =2E=2E=2E } =09} =09void process=28Object a=2C Object b=29 =09{ =09=09if =28a =3C b=29 =09=09=09=2E=2E=2E =09=09else =09=09=09=2E=2E=2E =09} =09int main=28=29 =09{ =09=09process=28new Foo=2C new Foo=29=3B =09} Now=2C which version of cmp=28=29 will be used in process=28=29=3F
Aug 20 2002
The int Foo.cmp(Object o); version will be used. Since process() doesn't know about NaN's anyway, you'll need to overload int cmp(Object o); to perhaps throw an exception on a NaN, and then write a float cmp(MyFloat o) to handle NaN's. "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374890162473958 news.digitalmars.com... On Tue, 20 Aug 2002 11:33:34 -0700 "Walter" <walter digitalmars.com> wrote:Correct. But if you overload it, you can change the return type - but be aware that will create more than one entry for cmp in the vtbl[].Then, take a look at this: class Foo { float cmp() { ... } } void process(Object a, Object b) { if (a < b) ... else ... } int main() { process(new Foo, new Foo); } Now, which version of cmp() will be used in process()?
Aug 21 2002
On Wed, 21 Aug 2002 01:21:43 -0700 "Walter" <walter digitalmars.com> wrote:The int Foo.cmp(Object o); version will be used. Since process() doesn't know about NaN's anyway, you'll need to overload int cmp(Object o); to perhaps throw an exception on a NaN, and then write a float cmp(MyFloat o) to handle NaN's.process() doesn't need to know anything of NaNs - but it relies on the fact that correct comparison is performed regardless of actual types of objects. Maybe it would really be better to make cmp() always return float? I don't think it would add any significant slowdown, but the feature would then be consistent...
Aug 21 2002
Hi, "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374899500592593 news.digitalmars.com...Maybe it would really be better to make cmp() always return float? I don't think it would add any significant slowdown, but the feature would then be consistent...If floating point isn't supported by hardware, it would cause a major performance hit. Regards, Martin M. Pedersen
Aug 21 2002
On Wed=2C 21 Aug 2002 22=3A11=3A45 +0100 =22Martin M=2E Pedersen=22 =3Cmmp=40www=2Emoeller-pedersen=2Edk=3E wrote=3A =3E If floating point isn't supported by hardware=2C it would cause a major =3E performance hit=2E Then=2C let's define a standard =22fp-comparison=22 interface in object=2Ed=3A =09interface CompareFP =09{ =09=09float cmp=28=29=3B =09} Now process=28=29 would be=3A =09process=28CompareFP a=2C CompareFP b=29 =09{ =09=09=2E=2E=2E =09} And all problems are gone=2E
Aug 21 2002
Have cmp() return an enum: enum CmpResult { LessThan = -1, EqualTo = 0, GreaterThan = 1, Undefined = 1<<31, } So this will work: float a = sqrt(-1); // generate NaN float b = 1; if (a.cmp(b) != 0) printf("they're different\n"); Using the old cmpresult < 0 and cmpresult > 0 checks will mistakenly think that NaN comparisons are less than, but that shouldn't be a big problem. And we can leave cmp() defined to return int. Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374900566370602 news.digitalmars.com... On Wed, 21 Aug 2002 22:11:45 +0100 "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote:If floating point isn't supported by hardware, it would cause a major performance hit.Then, let's define a standard "fp-comparison" interface in object.d: interface CompareFP { float cmp(); } Now process() would be: process(CompareFP a, CompareFP b) { ... } And all problems are gone.
Aug 22 2002
On Thu, 22 Aug 2002 10:26:54 -0700 "Sean L. Palmer" <seanpalmer earthlink.net> wrote:Have cmp() return an enum: enum CmpResult { LessThan = -1, EqualTo = 0, GreaterThan = 1, Undefined = 1<<31, }A nice idea.
Aug 22 2002
Hi, "Pavel Minayev" <evilone omen.ru> wrote in message news:CFN374909708268634 news.digitalmars.com...I agree. Regards, Martin M. Pedersenenum CmpResultA nice idea.
Aug 22 2002
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message news:ak36cs$23d7$1 digitaldaemon.com...Have cmp() return an enum: enum CmpResult { LessThan = -1, EqualTo = 0, GreaterThan = 1, Undefined = 1<<31, } So this will work: float a = sqrt(-1); // generate NaN float b = 1; if (a.cmp(b) != 0) printf("they're different\n"); Using the old cmpresult < 0 and cmpresult > 0 checks will mistakenly think that NaN comparisons are less than, but that shouldn't be a big problem. And we can leave cmp() defined to return int.The behavior of < and > is defined for NaNs, so there would have two be two comparisons for every cmp. The CPU handles this by setting the P flag for NaN comparisons, but that isn't accessible to functions.
Aug 23 2002
Walter wrote:"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5F0476.1060203 users.sourceforge.net...I don't have a problem with making this change, but I think it should be consistent or it'll cause more confusion than enlightenment. Always returning float from cmp is actually helpful, since it can then be used if eq isn't provided, which it almost universally won't be, and it handles "long - long" properly. Better yet would be to remove eq and see how many complaints there are.Walter, could you back one of us up here, please?I think it will work right if: a op b is rewritten as: a.cmp(b) op 0 For the nan cases, the cmp function can return nan's.
Aug 21 2002
"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D63BB45.3040706 users.sourceforge.net...I don't have a problem with making this change, but I think it should be consistent or it'll cause more confusion than enlightenment. Always returning float from cmp is actually helpful, since it can then be used if eq isn't provided, which it almost universally won't be, and it handles "long - long" properly. Better yet would be to remove eq and see how many complaints there are.Always returning float has a problem for embedded systems which may want to use an integer-only subset of D, and also it would be a problem in general for machines which have arbitrarilly slow floating point. The reason for a separate eq from cmp is that for many objects there is no concept of "less than", although there is a concept for "equals".
Aug 21 2002
Walter wrote:"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D63BB45.3040706 users.sourceforge.net...Uh, okay, but if float is supported in comparison then float will be used practically everywhere, and the embedded problem is not eased at all. Besides which, this is poppycock. Comparison against zero is a trivial operation whether you have hardware support or not. Zero: v == 0 Negative: v & 0x80000000 NaN: (v & 0x7FFF0000) == 0x7FFF0000 && (v & 0xFFFF) Positive: none of the above I'm sure that bit twiddlers could bring that down to fewer operations, but it's clearly not of any consequence.I don't have a problem with making this change, but I think it should be consistent or it'll cause more confusion than enlightenment. Always returning float from cmp is actually helpful, since it can then be used if eq isn't provided, which it almost universally won't be, and it handles "long - long" properly. Better yet would be to remove eq and see how many complaints there are.Always returning float has a problem for embedded systems which may want to use an integer-only subset of D, and also it would be a problem in general for machines which have arbitrarilly slow floating point.The reason for a separate eq from cmp is that for many objects there is no concept of "less than", although there is a concept for "equals".In which case they'll only return 0 or float.nan.
Aug 21 2002
"Burton Radons" <loth users.sourceforge.net> wrote in message news:3D640B7D.5000603 users.sourceforge.net...toAlways returning float has a problem for embedded systems which may wantgeneraluse an integer-only subset of D, and also it would be a problem inFloat is only necessary for supporting NaN comparisons. Other comparisons most likely will stick to simple int returns of <0, 0, or >0.for machines which have arbitrarilly slow floating point.Uh, okay, but if float is supported in comparison then float will be used practically everywhere, and the embedded problem is not eased at all.Besides which, this is poppycock. Comparison against zero is a trivial operation whether you have hardware support or not. Zero: v == 0 Negative: v & 0x80000000 NaN: (v & 0x7FFF0000) == 0x7FFF0000 && (v & 0xFFFF) Positive: none of the above I'm sure that bit twiddlers could bring that down to fewer operations, but it's clearly not of any consequence.I disagree, in loops especially it can be extremely sensitive to comparison time.
Aug 23 2002
This scored most:And this did:5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had to put in any new syntax I would prefer it to be this one. static Vector operator (a - b) (Vector a, Vector b);Now, the question is, what is "static" doing in the syntax? =)1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs (My vote: +1). Vector add (Vector b);
Aug 17 2002
One thing I dissagree with is the way you conducted this survay. Next time keep your opinions in a separate email please. Explain what you mean as much as you want, but don't optionate it. Otherwise you may effect the results of your replies. I'm not trying to flame you, I'm just pointing this out for next time.
Aug 17 2002
Whoops "anderson" <anderson firestar.com.au> wrote in message news:ajkvgl$h0k$1 digitaldaemon.com...One thing I dissagree with, is the way you conducted this survay. Nexttimekeep your opinions in a separate email please. Explain what you mean asmuchas you want, but don't put opinions in it. Otherwise you may effect theresultsof your replies. I'm not trying to flame you, I'm just pointing this out for next time.
Aug 17 2002
On Thu, 08 Aug 2002 06:57:04 -0700, Burton Radons <loth users.sourceforge.net> wrote:I've accidentally implemented operator overloading in my port. It was kind of incidental to other work, so I thought "what the hell" and threw it in. But this brings up the whole issue of syntax, and I think that should be voted on to specify the syntax on my side and to influence Walter when he decides to do this topic.I'm scared of voting... it's too much like a committee...
Aug 21 2002
"Toyotomi" <io219 attbi.com> wrote in message news:oll7mu4nat45gi1gjfvslh7mriv0b3jer7 4ax.com...I'm scared of voting... it's too much like a committee...I think democratically designed languages tend to be failures <g>. Nevertheless, ignoring feedback from users is equally perilous. These kinds of discussions help me to understand what things are important and what are not.
Aug 21 2002
On Wed, 21 Aug 2002 14:27:33 -0700, "Walter" <walter digitalmars.com> wrote:"Toyotomi" <io219 attbi.com> wrote in message news:oll7mu4nat45gi1gjfvslh7mriv0b3jer7 4ax.com...Glad you see the first bit that way. Ignoring is a bit _less_ perilous in my opinion though. ;-p I think I can see I don't have too much to fear. Thanks.I'm scared of voting... it's too much like a committee...I think democratically designed languages tend to be failures <g>. Nevertheless, ignoring feedback from users is equally perilous. These kinds of discussions help me to understand what things are important and what are not.
Aug 21 2002
Should we vote this again? I mean, there're some complaining about how overloaded operators should work... "Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net... | I've accidentally implemented operator overloading in my port. It was | kind of incidental to other work, so I thought "what the hell" and threw | it in. But this brings up the whole issue of syntax, and I think that | should be voted on to specify the syntax on my side and to influence | Walter when he decides to do this topic. | | I'd like Apache-style voting to be used, where the voting is either -1, | -0, 0, +0, or +1 for any option, which is a good bellweather of how | people think about something. | | First off, the naming scheme: | | 1) "add", "mul", "div", etc. (my vote: +1) | | Vector mul (Vector b); | Vector div (Vector b); | | 2) "op_add", "op_mul", "op_div", etc. (my vote: +1) | | Vector op_sub (Vector b); | Vector op_mod (Vector b); | | 3) "operator +". (my vote: -1) My vote is because I find this syntax | confusing in C++, particularly with its wide expressiveness, and I | admire any syntax which doesn't require a change to tools, as the above | don't. | | Vector operator + (Vector b); | | 4) 'operator "+"'. (my vote: -0) For some reason I find this less | visually disconcerting. | | Vector operator "*" (Vector b); | | 5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had | to put in any new syntax I would prefer it to be this one. | | static Vector operator (a - b) (Vector a, Vector b); | | Now, where overloaded operators are defined: | | 1) Operators are normal, possibly virtual methods in classes, normal | nonvirtual methods in structs (My vote: +1). | | Vector add (Vector b); | | 2) Overloaded operators are always static methods with both left and | right arguments defined (My vote: 0). | | static Vector add (Vector a, Vector b); | | 3) Overloaded operators are global functions, using both arguments (My | vote: -1). | | Vector add (Vector a, Vector b); | | 4) Operator overloading shouldn't be put in (My vote: -1). | | Now, reverse operator handling, where you want the right-side expression | to handle the evaluation, such as with the form "int * Vector": | | 1) A second set of potential functions (My vote: +1). | | 2) Automatic reorganization of the expression. This makes assumptions | about what the operators do and can't handle "1 / Vector" (My vote: -1). | For example, "1-A" could become "-A+1". | | Now for the operations covered. Please be temperate with your votes - | operations can be added later, but they can't be removed as easily. | | 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1) | | 2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1) | | 3) a++, a--, --a, ++a. (my vote: 0) | | 4) a = b. (my vote: 0) | | 5) a << b, a >> b, a >>> b. (my vote: +1) | | 6) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1) | | 7) new, delete. (my vote: -0) | | 8) a || b, a && b. (my vote: -1) | | 9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1) | | 10) a [b]. (my vote: +1) | | 10a) a [b] = c. (my vote: +0) | | 11) a [b .. c]. (my vote: +1) | | 12) &a, *a. (my vote: -1) | | 13) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note | that this won't allow just anything in b. | | 13a) a . b, where b can be any type. (my vote: -1) | | 14) a ? b : c. (my vote: -1) | | 15) a === b, a !== b. (my vote: 0) | | 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) | IMO this is an eq/cmp combination issue. | | 17) a in b. (my vote: +1) | | 18) cast (b) a. (my vote: -0) I haven't had any good experiences with | cast overloading in C++. | | 19) (a, b). (my vote: -1) | | And miscellaneous: | | 1) Operator overloading should be allowed on basic types as global | functions. (my vote: -1) | | int operator "a - b" (int a, int b); | | 2) Definition of new operators is allowed. I'll ignore this one if it | goes positive. (my vote: -1) | | Vector operator (this dot b) (Vector b); | | 2a) Setting precedence of new operators is allowed. I'll ignore this | one if it goes positive. (my vote: -1) | | operator (a dot b) above (a >= b) below (a * b); | | I think that's about it. | --- Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.538 / Virus Database: 333 - Release Date: 2003-11-10
Nov 13 2003
1) "add", "mul", "div", etc. -1 it can be used for own functions very nice, wich should NOT be operators then. 2) "op_add", "op_mul", "op_div", etc. (my vote: +1) -0 less chance to get used as normal func wich should NOT be operator.. but opAdd would be the D way then. doesn't mather.. i don't like it 3) "operator +". +1 definitely best. its an unambiguous name, not to use for anything else.. except possibly +(a,b) or operator+(a,b).. but the issues of 1) and 2) are not there. 4) 'operator "+"'. -1 its not an operator on a string token 5) 'operator (a - b)' or 'operator (this - b)'. 0 never seen it before.. and directly the suggested way, -1, but the idea is something we could think about.. Vector operator(Vector a - Vector b) { return sub(a,b); } _could_ be a nice way.. next: 1) Operators are normal, possibly virtual methods in classes, normal nonvirtual methods in structs +1 they _can_ be 2) Overloaded operators are always static methods with both left and right arguments defined -1 not always. 3) Overloaded operators are global functions, using both arguments +1 definitely way to go. if you know oo, if you know encapsulation, you have to allow that. if not, read more on www.cuj.com (thats the link?). its the only way to make operators extendable, just "adding another layer". the whole very dynamic stream concept of c++ would have never worked without that. and there's more.. (end of text) 4) Operator overloading shouldn't be put in -2 it definitely has to be in. next 1) A second set of potential functions +0 acceptable, the way c++ did it, too 2) Automatic reorganization of the expression. -1 this defeats the way to define them with new behaviour. and a new one: 3) specify by some token.. like Vector operator+ (Vector a,Vector b) reversible { return add(a,b); } (reversible isn't the mathematical term.. but i'm too tierd currently to use my brain for remembering that term..) oh, and.. +1 it saves the additional typing. why not? next 1) a + b, a - b, a * b, a / b, a % b, -a, +a. +1 2) a & b, a | b, a ^ b, ~a, !a. !a doesn't fit in this list as the rest are binary ops.. for binary ops: +1 for ! 0 3) a++, a--, --a, ++a. for --a and ++a, yes. a++,a-- should be autoimplemented.. its just a changing of the order.. but they can be useful for iterator thingies.. +0 4) a = b. (my vote: 0) +0 i think yes. but as a binary operator, not the way c++ does with possibility of a constructor, or an operator AType() void operator = (TypeA a,TypeB b) { a.set(b); } 5) a << b, a >> b, a >>> b. (my vote: +1) +1 6) a += b, a -= b, a *= b, a %= b, etc. if we have them, we don't need 1) actually.. +0 7) new, delete. +1 if the way they are done now.. they can be useful. 8) a || b, a && b. -1 9) explicit a >= b, a > b, a <= b, a < b 0 i don't need them. but i've seen people who'd like to have them, and for reasons.. 10) a[b]. +1 10a) a[b] = c. uhm? 11) a[b..c] +1 12) &a, *a. -1 13) a.b, a.b = c. -1 we have properties for such things 14) a ? b : c. (my vote: -1) -1 15) a === b, a !== b. -1 this is defined to be the comparison if its the identical object. not overloadable. 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) hm? -0 17) a in b. +1 18) cast (b) a. hm.. hm... 0 19) (a, b). hm.. -1 next 1) Operator overloading should be allowed on basic types as global functions. -1 2) Definition of new operators is allowed. I'll ignore this one if it goes positive. -1 2a) Setting precedence of new operators is allowed. I'll ignore this one if it goes positive. +0 actually this could get interesting for the standard operators, too.. but not that syntax, and it can be dangerous.. but the idea still makes a lot of sence.. (so, final statement:D) binary operators should be functions, not member functions or anything (but could be, and should be possible to be). reasoning: Vector operator*(Vector a,Quaternion q); that belongs to who? to class Vector? or class Quaternion?. to NONE. its a mathermatical function on BOTH. it is linking them together with some operation. but it does not belong to any of those. thus, it should not be member of any. this helps encapsulation. operator* in this case doesn't have direct access to Vector and Quaternion. (they both would be structs with public members in THIS case, but anyways). this means implementation can change, operator doesn't bother about it. else, it would say belong to Vector. it would not have the possibility to access Quaternion. but it could access Vector. this is an unfair situation, and doesn't make sence. unary operators should be members. but of course, they don't have to.. reasoning is, they only belong to one variable of one type, so that fits well.. class Vector { Vector operator-() { return negated(this); } } the great thing about having them as global functions is the ability to ADD them afterwards. you get a library, say like a D3DX library. they have nice functions like D3DXMatrixMultiply(D3DXVector* out,D3DXMatrix* m,D3DXVector* in); or similar. all you need to do then is write.. D3DXVector operator*(D3DXMatrix m,D3DXVector v) { D3DXVector ret; D3DXMatrixMultiply(&ret,&m,&v); return ret; } and you added the functionality. without touching the D3DX library at all. same for say streams.. Stream operator<<(Stream s,Type obj) { return s<<obj.foo<<obj.bla<<obj.bar; } this adds a lot of functionality. a lot of freedom. and a lot of savety. it eases our tasks as well by much.. oh, and you forgot operator() :D
Nov 14 2003
"davepermen" <davepermen_member pathlink.com> wrote in message news:bp2hml$1dlq$1 digitaldaemon.com...3) specify by some token.. like Vector operator+ (Vector a,Vector b) reversible { return add(a,b); } (reversible isn't the mathematical term.. but i'm too tierd currently touse mybrain for remembering that term..)It's called commutativity1) a + b, a - b, a * b, a / b, a % b, -a, +a. +1 2) a & b, a | b, a ^ b, ~a, !a. !a doesn't fit in this list as the rest are binary ops.. for binary ops: +1 for ! 0You're mistaken. Look again.3) a++, a--, --a, ++a. for --a and ++a, yes. a++,a-- should be autoimplemented.. its just achanging ofthe order.. but they can be useful for iterator thingies.. +0 4) a = b. (my vote: 0) +0 i think yes. but as a binary operator, not the way c++ does with possibility of a constructor, or an operator AType() void operator = (TypeA a,TypeB b) { a.set(b); }You are right, construction and destruction do not make sense most of the time, it is conversion or production that gives us 99% of our values. Let's focus on that. Assignment is pretty fundamental to procedural languages. Assigning one value to a variable of another type is an implicit conversion, and those are really good to be able to define simply, OUTSIDE of the class declaration, because otherwise you get into the C++ mess of user-defined conversions which are exactly the same thing as constructors, if you really think about it. The copy constructor could likewise be eliminated, and becomes a special case of assigning a value to an lvalue of its own type, in other words same as the basic assignment operator.5) a << b, a >> b, a >>> b. (my vote: +1) +1 6) a += b, a -= b, a *= b, a %= b, etc. if we have them, we don't need 1) actually.. +0 7) new, delete. +1 if the way they are done now.. they can be useful.I've never really liked new and delete. I would love to get rid of them and just use factory / demolition functions (assignments to/from void work for this purpose).10) a[b]. +1 10a) a[b] = c. uhm?array store (array used as lvalue)12) &a, *a. -1The C++ purpose for these being overloadable is to provide and dereference pointer types. &a is pretty much the equivalent of saying a.begin(), null is almost equivalent to a.end(). If you use them, you give up the ability to take the address of a variable, you "wrap" that type's pointer capability.1) Operator overloading should be allowed on basic types as globalfunctions.-1Why not? ++float float >> 1 These are good examples of why I think it *should* be allowed. The language designers "forgot" those operations, creating little pitfalls and minefields in template authoring.2) Definition of new operators is allowed. I'll ignore this one if itgoespositive. -1I hate you all!! There are not nearly enough operators to go around. Sean
Nov 21 2003
quoting {2) a & b, a | b, a ^ b, ~a, !a. !a doesn't fit in this list as the rest are binary ops.. for binary ops: +1 for ! 0You're mistaken. Look again. } first: i made a typo. but my statement is correct. !a is no binary op. its an unary op:D (read up yourself). what i ment is, ! is not a bitwise op. the others are. a&b ands all bits. a|b ors all bits, a^b xors all bits, ~a inverts all bits, but !a returns a boolean, and only checks if all bits are zero, or not, to return that boolean. ! belongs to &&,||, a possible ^^ (hehe:D), etc.. it is a logical op. not a bitwise op. i just checked the docu's, and it still is. as in c++.
Nov 22 2003
Doh! I thought you meant binary as in "not unary", instead of what you really meant, which was "not logical". ;) Sean "davepermen" <davepermen_member pathlink.com> wrote in message news:bpnsck$2r4l$1 digitaldaemon.com...quoting {an2) a & b, a | b, a ^ b, ~a, !a. !a doesn't fit in this list as the rest are binary ops.. for binary ops: +1 for ! 0You're mistaken. Look again. } first: i made a typo. but my statement is correct. !a is no binary op. itsunary op:D (read up yourself). what i ment is, ! is not a bitwise op. the others are. a&b ands all bits.a|bors all bits, a^b xors all bits, ~a inverts all bits, but !a returns aboolean,and only checks if all bits are zero, or not, to return that boolean. ! belongs to &&,||, a possible ^^ (hehe:D), etc.. it is a logical op. notabitwise op. i just checked the docu's, and it still is. as in c++.
Nov 24 2003
hehe sorry.. :D In article <bpsljg$hlc$1 digitaldaemon.com>, Sean L. Palmer says...Doh! I thought you meant binary as in "not unary", instead of what you really meant, which was "not logical". ;) Sean
Nov 24 2003
I don't care too much about what they're called (although I don't like the current naming conventions much). What's really important is that operators be not always bound to instances, i.e. we can (and should) declare binary operators as free functions, and we should have the right to do so with unary operators. I'm not sure it's necessary to vote on this, because I think this will be change that will be forced on D (i.e. on Walter) at some point, as the problems associated with the current approach become too great to ignore. IMO, if that change does not happen, D will founder "Carlos Santander B." <carlos8294 msn.com> wrote in message news:bp1fs0$2oat$1 digitaldaemon.com...Should we vote this again? I mean, there're some complaining about how overloaded operators should work... "Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net... | I've accidentally implemented operator overloading in my port. It was | kind of incidental to other work, so I thought "what the hell" and threw | it in. But this brings up the whole issue of syntax, and I think that | should be voted on to specify the syntax on my side and to influence | Walter when he decides to do this topic. | | I'd like Apache-style voting to be used, where the voting is either -1, | -0, 0, +0, or +1 for any option, which is a good bellweather of how | people think about something. | | First off, the naming scheme: | | 1) "add", "mul", "div", etc. (my vote: +1) | | Vector mul (Vector b); | Vector div (Vector b); | | 2) "op_add", "op_mul", "op_div", etc. (my vote: +1) | | Vector op_sub (Vector b); | Vector op_mod (Vector b); | | 3) "operator +". (my vote: -1) My vote is because I find this syntax | confusing in C++, particularly with its wide expressiveness, and I | admire any syntax which doesn't require a change to tools, as the above | don't. | | Vector operator + (Vector b); | | 4) 'operator "+"'. (my vote: -0) For some reason I find this less | visually disconcerting. | | Vector operator "*" (Vector b); | | 5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If I had | to put in any new syntax I would prefer it to be this one. | | static Vector operator (a - b) (Vector a, Vector b); | | Now, where overloaded operators are defined: | | 1) Operators are normal, possibly virtual methods in classes, normal | nonvirtual methods in structs (My vote: +1). | | Vector add (Vector b); | | 2) Overloaded operators are always static methods with both left and | right arguments defined (My vote: 0). | | static Vector add (Vector a, Vector b); | | 3) Overloaded operators are global functions, using both arguments (My | vote: -1). | | Vector add (Vector a, Vector b); | | 4) Operator overloading shouldn't be put in (My vote: -1). | | Now, reverse operator handling, where you want the right-side expression | to handle the evaluation, such as with the form "int * Vector": | | 1) A second set of potential functions (My vote: +1). | | 2) Automatic reorganization of the expression. This makes assumptions | about what the operators do and can't handle "1 / Vector" (My vote: -1). | For example, "1-A" could become "-A+1". | | Now for the operations covered. Please be temperate with your votes - | operations can be added later, but they can't be removed as easily. | | 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1) | | 2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1) | | 3) a++, a--, --a, ++a. (my vote: 0) | | 4) a = b. (my vote: 0) | | 5) a << b, a >> b, a >>> b. (my vote: +1) | | 6) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1) | | 7) new, delete. (my vote: -0) | | 8) a || b, a && b. (my vote: -1) | | 9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1) | | 10) a [b]. (my vote: +1) | | 10a) a [b] = c. (my vote: +0) | | 11) a [b .. c]. (my vote: +1) | | 12) &a, *a. (my vote: -1) | | 13) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note | that this won't allow just anything in b. | | 13a) a . b, where b can be any type. (my vote: -1) | | 14) a ? b : c. (my vote: -1) | | 15) a === b, a !== b. (my vote: 0) | | 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) | IMO this is an eq/cmp combination issue. | | 17) a in b. (my vote: +1) | | 18) cast (b) a. (my vote: -0) I haven't had any good experiences with | cast overloading in C++. | | 19) (a, b). (my vote: -1) | | And miscellaneous: | | 1) Operator overloading should be allowed on basic types as global | functions. (my vote: -1) | | int operator "a - b" (int a, int b); | | 2) Definition of new operators is allowed. I'll ignore this one if it | goes positive. (my vote: -1) | | Vector operator (this dot b) (Vector b); | | 2a) Setting precedence of new operators is allowed. I'll ignore this | one if it goes positive. (my vote: -1) | | operator (a dot b) above (a >= b) below (a * b); | | I think that's about it. | --- Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.538 / Virus Database: 333 - Release Date: 2003-11-10
Nov 14 2003
What's really important is that operators be not always bound toinstances, Could you tell me what you mean here, with an example ?I'm not sure it's necessary to vote on this, because I think this will be change that will be forced on DYea but I personally would like this ASAP, i dont like the current inconsistent convention and am hoping each release will fix it. C "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message news:bp3dfi$2qs9$1 digitaldaemon.com...I don't care too much about what they're called (although I don't like the current naming conventions much). What's really important is that operators be not always bound toinstances,i.e. we can (and should) declare binary operators as free functions, andweshould have the right to do so with unary operators. I'm not sure it's necessary to vote on this, because I think this will be change that will be forced on D (i.e. on Walter) at some point, as the problems associated with the current approach become too great to ignore. IMO, if that change does not happen, D will founder "Carlos Santander B." <carlos8294 msn.com> wrote in message news:bp1fs0$2oat$1 digitaldaemon.com...threwShould we vote this again? I mean, there're some complaining about how overloaded operators should work... "Burton Radons" <loth users.sourceforge.net> wrote in message news:3D5278B0.1000508 users.sourceforge.net... | I've accidentally implemented operator overloading in my port. It was | kind of incidental to other work, so I thought "what the hell" andeither -1,| it in. But this brings up the whole issue of syntax, and I think that | should be voted on to specify the syntax on my side and to influence | Walter when he decides to do this topic. | | I'd like Apache-style voting to be used, where the voting isabove| -0, 0, +0, or +1 for any option, which is a good bellweather of how | people think about something. | | First off, the naming scheme: | | 1) "add", "mul", "div", etc. (my vote: +1) | | Vector mul (Vector b); | Vector div (Vector b); | | 2) "op_add", "op_mul", "op_div", etc. (my vote: +1) | | Vector op_sub (Vector b); | Vector op_mod (Vector b); | | 3) "operator +". (my vote: -1) My vote is because I find this syntax | confusing in C++, particularly with its wide expressiveness, and I | admire any syntax which doesn't require a change to tools, as thehad| don't. | | Vector operator + (Vector b); | | 4) 'operator "+"'. (my vote: -0) For some reason I find this less | visually disconcerting. | | Vector operator "*" (Vector b); | | 5) 'operator (a - b)' or 'operator (this - b)'. (my vote: +0) If Iexpression| to put in any new syntax I would prefer it to be this one. | | static Vector operator (a - b) (Vector a, Vector b); | | Now, where overloaded operators are defined: | | 1) Operators are normal, possibly virtual methods in classes, normal | nonvirtual methods in structs (My vote: +1). | | Vector add (Vector b); | | 2) Overloaded operators are always static methods with both left and | right arguments defined (My vote: 0). | | static Vector add (Vector a, Vector b); | | 3) Overloaded operators are global functions, using both arguments (My | vote: -1). | | Vector add (Vector a, Vector b); | | 4) Operator overloading shouldn't be put in (My vote: -1). | | Now, reverse operator handling, where you want the right-sidevote: -1).| to handle the evaluation, such as with the form "int * Vector": | | 1) A second set of potential functions (My vote: +1). | | 2) Automatic reorganization of the expression. This makes assumptions | about what the operators do and can't handle "1 / Vector" (Mywith| For example, "1-A" could become "-A+1". | | Now for the operations covered. Please be temperate with your votes - | operations can be added later, but they can't be removed as easily. | | 1) a + b, a - b, a * b, a / b, a % b, -a, +a. (my vote: +1) | | 2) a & b, a | b, a ^ b, ~a, !a. (my vote: +1) | | 3) a++, a--, --a, ++a. (my vote: 0) | | 4) a = b. (my vote: 0) | | 5) a << b, a >> b, a >>> b. (my vote: +1) | | 6) a += b, a -= b, a *= b, a %= b, etc. (my vote: -1) | | 7) new, delete. (my vote: -0) | | 8) a || b, a && b. (my vote: -1) | | 9) explicit a >= b, a > b, a <= b, a < b. (my vote: -1) | | 10) a [b]. (my vote: +1) | | 10a) a [b] = c. (my vote: +0) | | 11) a [b .. c]. (my vote: +1) | | 12) &a, *a. (my vote: -1) | | 13) a.b, a.b = c. Retrieve and assign property. (my vote: +1) Note | that this won't allow just anything in b. | | 13a) a . b, where b can be any type. (my vote: -1) | | 14) a ? b : c. (my vote: -1) | | 15) a === b, a !== b. (my vote: 0) | | 16) a !<> b, a <> b, a !> b, a !< b, a !<= b, a !>= b. (my vote: 0) | IMO this is an eq/cmp combination issue. | | 17) a in b. (my vote: +1) | | 18) cast (b) a. (my vote: -0) I haven't had any good experiences| cast overloading in C++. | | 19) (a, b). (my vote: -1) | | And miscellaneous: | | 1) Operator overloading should be allowed on basic types as global | functions. (my vote: -1) | | int operator "a - b" (int a, int b); | | 2) Definition of new operators is allowed. I'll ignore this one if it | goes positive. (my vote: -1) | | Vector operator (this dot b) (Vector b); | | 2a) Setting precedence of new operators is allowed. I'll ignore this | one if it goes positive. (my vote: -1) | | operator (a dot b) above (a >= b) below (a * b); | | I think that's about it. | --- Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.538 / Virus Database: 333 - Release Date: 2003-11-10
Nov 14 2003
"Charles Sanders" <sanders-consulting comcast.net> wrote in message news:bp40ik$plv$1 digitaldaemon.com...1. Operators as instances (C++ syntax, I'm afraid): class X { X operator +(X const &rhs); // "this" is the lhs }; 2. Free functions: class X {} X operator +(X const &lhs, X const &rhs);What's really important is that operators be not always bound toinstances, Could you tell me what you mean here, with an example ?beI'm not sure it's necessary to vote on this, because I think this willMe too, but there seems much resistance on Walter's part. I can see that it's probably a big job. It will happen eventually, though, I have no doubtchange that will be forced on DYea but I personally would like this ASAP, i dont like the current inconsistent convention and am hoping each release will fix it.
Nov 14 2003