D - Missing boolean exclusive-or operator, operator overloading and real bool type advocacy
- Christophe Bouchon (62/64) Jan 20 2002 These are my 2 cents opinions:
- Sean L. Palmer (24/88) Jan 21 2002 C (and C++ and Java and D) already *have* a boolean exclusive-or operato...
- Mike Wynn (53/144) Jan 21 2002 Real boolean type YES.
- Sean L. Palmer (34/194) Jan 21 2002 It's funny how all the folks who "have rarely used it" are the most voic...
- Mike Wynn (33/55) Jan 21 2002 voiceful
- Sean L. Palmer (42/96) Jan 22 2002 is
- Mike Wynn (69/94) Jan 22 2002 that
- reiter nomadics.com (Mac Reiter) (75/100) Jan 22 2002 Depends on if operator= is written correctly. "Correctly" means that
- Mike Wynn (8/17) Jan 22 2002 they don't carry guns where I live, maybe that's why I'm not a fan of
- Roberto Mariottini (82/107) Jan 23 2002 what
- Juan Carlos Arevalo Baeza (30/49) Jan 22 2002 that
- Russell Borogove (4/7) Jan 22 2002 Heh, I hadn't noticed your email address prior to this. Tell the
- Walter (11/14) Jan 25 2002 Actually, it isn't very hard. Then again, I'm used to writing them. C++ ...
- D (8/11) Feb 04 2002 Not all. Virtually all. And not all CPU's support floats. So by your
- D (24/32) Feb 04 2002 I have never used operator overloading, but I have had the "need" for it...
- Sean L. Palmer (21/56) Feb 04 2002 You're right, I'd rather have ROL/ROR built in, and emulated on those (r...
- D (45/113) Feb 04 2002 Rotations through the carry would be nice, but no high level language gi...
- OddesE (29/41) Feb 04 2002 on
- Rajiv Bhagwat (16/80) Jan 22 2002 Thank you for pointing out 'sprit'! It is certainly impressive and prope...
- D (7/15) Feb 04 2002 An exclusive or operator is needed for both logical and boolean types.
- Pavel Minayev (3/5) Feb 04 2002 ^ and ^^, then.
- Sean L. Palmer (11/16) Feb 04 2002 That'd be great, but the point you guys KEEP MISSING is that there's alr...
- Mike Wynn (13/31) Feb 04 2002 I think people are missing the point of && and ||
- Juan Carlos Arevalo Baeza (8/10) Feb 04 2002 already
- D (5/7) Feb 04 2002 That operator is not equal, not logical xor. Programming via side effec...
These are my 2 cents opinions: 1) Like most programming languages, D is missing a boolean exclusive-or operator. I can't count the number of times I had to write something like: if ((cond1 && !cond2) || (!cond1 && cond2)) // bad if cond1 and/or cond2 have side effect or if ((cond1 != 0) ^ (cond2 != 0)) the "!= 0" above are required if cond1 or cond2 can be such that (cond1 & cond2) == 0 but (cond1 | cond2) != 0, like cond1==2 and cond2==4. I don't use this kind of condition as often as simple || and && but often enough to be realy anoyed. Pppllllease, add a ^^ boolean exclusive-or operator ! 2) I think that mostly, a real intrisic bool type (and requiring bool arguments to if, while, &&, ||, ^^, !...) is a good thing and protect against lots of hard to catch errors. After all, D documentation says:Who D is For Programmers who routinely use lint or similar code analysis tools toeliminate bugs before the code is even compiled. And declaring a variable as bool instead of int is better for code documentation. Perhaps a compiler option to allow/prevent automatic convertion to bool in conditionals should be the best option to satisfy everybody. 3) I also add my support for operator overloading. I agree that it can be abused (you can find abuses of any programming language feature) but in some cases, it can be used in a very nice and readable way. If you think it's just good for complex numbers, look at http://spirit.sourceforge.net/ for an example of a clean, usefull and nice operator overloading usage with templates: you get lex+yacc capabilities directly within C++ source, an EBNF-like notation (with overloaded C++ operators) constructing a parser during object construction, the constructed variables becoming the automaton of the parser. Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >> +digit)[&doInt] ]; rule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]); The >> is a sequence, !, * and + (with a single argument on the right) are the 0-or-1, 0-or-more and 1-or-more repetitions, the actions are in the [] (functions with pointers to the first and last elements parsed by the rule) and | is an alternative. Execution of a rule returns the number of elements matched. The ch_p('+') is there because '+' | '-' can't use the overloaded |. digit is a predifined single digit parser, doInt, doAdd... are some simple action functions not included here. Then you just do something like: parse(expr, "1 + ((6 * 200) - 20) / 6"); 4) Perhaps also add non-vitual member functions to struct to be able to handle light/simple objects on the stack or embeded inside other struct/class (for allocation speed). This is what's done in the .NET framework and I think it's also a proposed extension for Java. It can help to prevent too much heap fragmentation with lot of tiny memory blocks. Other than that, D seems like a great and well designed language with mostly reasonable compromises. It removes most of the things I hated in C++ like pre-processor, completely useless . -> and :: separation, forward declarations, #include (parse these headers again and again and again... or struggle with restricted precompiled headers), ambiguous syntax depending on the nature of a symbol like (type)-1 instead or (var)-1 and last but not least, added missing language supported safe garbage collection (=>full RTTI) and class properties (exist only as non-portable extensions in Borland C++ Builder and MSVC).
Jan 20 2002
"Christophe Bouchon" <cbouchon hotmail.com> wrote in message news:a2ensl$2uac$1 digitaldaemon.com...These are my 2 cents opinions: 1) Like most programming languages, D is missing a boolean exclusive-or operator. I can't count the number of times I had to write something like: if ((cond1 && !cond2) || (!cond1 && cond2)) // bad if cond1 and/or cond2 have side effect or if ((cond1 != 0) ^ (cond2 != 0)) the "!= 0" above are required if cond1 or cond2 can be such that (cond1 & cond2) == 0 but (cond1 | cond2) != 0, like cond1==2 and cond2==4. I don't use this kind of condition as often as simple || and && but often enough to be realy anoyed. Pppllllease, add a ^^ boolean exclusive-or operator !C (and C++ and Java and D) already *have* a boolean exclusive-or operator... it's " != " !!! :) if ((cond1 != 0) != (cond2 != 0))2) I think that mostly, a real intrisic bool type (and requiring bool arguments to if, while, &&, ||, ^^, !...) is a good thing and protect against lots of hard to catch errors. After all, D documentation says:I sit on the fence on this issue. I don't really have a preference.Who D is For Programmers who routinely use lint or similar code analysis tools toeliminate bugs before the code is even compiled. And declaring a variable as bool instead of int is better for code documentation. Perhaps a compiler option to allow/prevent automatic convertion to bool in conditionals should be the best option to satisfy everybody.3) I also add my support for operator overloading. I agree that it can be abused (you can find abuses of any programming language feature) but in some cases, it can be used in a very nice and readable way. If you think it's just good for complex numbers, look at http://spirit.sourceforge.net/ for an example of a clean, usefull and nice operator overloading usagewithtemplates: you get lex+yacc capabilities directly within C++ source, an EBNF-like notation (with overloaded C++ operators) constructing a parser during object construction, the constructed variables becoming theautomatonof the parser. Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >> +digit)[&doInt] ]; rule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]); The >> is a sequence, !, * and + (with a single argument on the right) are the 0-or-1, 0-or-more and 1-or-more repetitions, the actions are in the [] (functions with pointers to the first and last elements parsed by therule)and | is an alternative. Execution of a rule returns the number ofelementsmatched. The ch_p('+') is there because '+' | '-' can't use the overloaded |. digit is a predifined single digit parser, doInt, doAdd... are some simple action functions not included here. Then you just do something like: parse(expr, "1 + ((6 * 200) - 20) / 6");Sounds very cool. I love operator overloading... many many cases functional notation just makes the code uglier. Sure operator overloading can be abused, but as you show above it can also be a powerful tool.4) Perhaps also add non-vitual member functions to struct to be able to handle light/simple objects on the stack or embeded inside other struct/class (for allocation speed). This is what's done in the .NET framework and I think it's also a proposed extension for Java. It can help to prevent too much heap fragmentation with lot of tiny memory blocks.I'm for that.Other than that, D seems like a great and well designed language withmostlyreasonable compromises. It removes most of the things I hated in C++ like pre-processor, completely useless . -> and :: separation, forward declarations, #include (parse these headers again and again and again...orstruggle with restricted precompiled headers), ambiguous syntax dependingonthe nature of a symbol like (type)-1 instead or (var)-1 and last but not least, added missing language supported safe garbage collection (=>full RTTI) and class properties (exist only as non-portable extensions inBorlandC++ Builder and MSVC).Yup. Now if it just had operator overloading and generics and DFront I'd be all set to switch over. ;) Actually that's not true... until I can write extremely lightweight classes (like a replacement for int, or a 3d math library) or at least get builtin 3D math stuff, I won't be able to switch for performance reasons. Sean
Jan 21 2002
Real boolean type YES. Operator Overloading NO! rotate operators please. although a boolean xor does not exists; you can do if ((x<8) ^ (y>9) ) or use != I like Java's approach to booleans. && and || are boolean, and can be short cut by the comiler in the same way C does & | ^ can be boolean but both sides will be evaluated (xor has to eval both sides) and if and while should be if (boolean-expression) {..} true this means that if ( a = b ) has to become if ( (a=b) != 0 ) but a 5 extra chars for a lot of time saved finding bugs. for the same reason I also like perls aproach to blocks instead of if ( expr ) stmt [else stmt] if ( bool-expr ) block [elseif (bool-expr) block ][else block] but that can wait for another day... as for operator overloading, your example is to me the prime reason for NOT having operator overloading, on the surface it looks like one thing but is infact something else if I want to write a parser, I'll use Lex/Yacc/ANTLR I do not deny that operator overloading is powerfull, but it is not realy required and I believe leads to more problem than it solves. in my experiance I have rarely used it ( apart from << and >> on streams) but do not consider that reason enough for it to be included in a language. far more important would be rotate operators all the CPU's I've every used have shift left and right (signed and unsigned) and rotate left and right. why do no languages have rotate operators. instead you have to unsigned shift left but N and shift right by integer-bitlength-N. and it can't be that only the minimum set of bitwise operator require are available because then you would have rotate right (or left) and nand (or nor) ! I have required rotate operations far more than operator overloading Mike. "Sean L. Palmer" <spalmer iname.com> wrote in message news:a2gikm$131g$1 digitaldaemon.com..."Christophe Bouchon" <cbouchon hotmail.com> wrote in message news:a2ensl$2uac$1 digitaldaemon.com...&These are my 2 cents opinions: 1) Like most programming languages, D is missing a boolean exclusive-or operator. I can't count the number of times I had to write something like: if ((cond1 && !cond2) || (!cond1 && cond2)) // bad if cond1 and/or cond2 have side effect or if ((cond1 != 0) ^ (cond2 != 0)) the "!= 0" above are required if cond1 or cond2 can be such that (cond1oftencond2) == 0 but (cond1 | cond2) != 0, like cond1==2 and cond2==4. I don't use this kind of condition as often as simple || and && butoperator...enough to be realy anoyed. Pppllllease, add a ^^ boolean exclusive-or operator !C (and C++ and Java and D) already *have* a boolean exclusive-orit's " != " !!! :) if ((cond1 != 0) != (cond2 != 0))in2) I think that mostly, a real intrisic bool type (and requiring bool arguments to if, while, &&, ||, ^^, !...) is a good thing and protect against lots of hard to catch errors. After all, D documentation says:Who D is For Programmers who routinely use lint or similar code analysis tools toeliminate bugs before the code is even compiled. And declaring a variable as bool instead of int is better for code documentation. Perhaps a compiler option to allow/prevent automatic convertion to boolbeconditionals should be the best option to satisfy everybody.I sit on the fence on this issue. I don't really have a preference.3) I also add my support for operator overloading. I agree that it canhttp://spirit.sourceforge.net/abused (you can find abuses of any programming language feature) but in some cases, it can be used in a very nice and readable way. If you think it's just good for complex numbers, look atarefor an example of a clean, usefull and nice operator overloading usagewithtemplates: you get lex+yacc capabilities directly within C++ source, an EBNF-like notation (with overloaded C++ operators) constructing a parser during object construction, the constructed variables becoming theautomatonof the parser. Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >> +digit)[&doInt] ]; rule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]); The >> is a sequence, !, * and + (with a single argument on the right)[]the 0-or-1, 0-or-more and 1-or-more repetitions, the actions are in theoverloaded(functions with pointers to the first and last elements parsed by therule)and | is an alternative. Execution of a rule returns the number ofelementsmatched. The ch_p('+') is there because '+' | '-' can't use thefunctional|. digit is a predifined single digit parser, doInt, doAdd... are some simple action functions not included here. Then you just do something like: parse(expr, "1 + ((6 * 200) - 20) / 6");Sounds very cool. I love operator overloading... many many casesnotation just makes the code uglier. Sure operator overloading can be abused, but as you show above it can also be a powerful tool.help4) Perhaps also add non-vitual member functions to struct to be able to handle light/simple objects on the stack or embeded inside other struct/class (for allocation speed). This is what's done in the .NET framework and I think it's also a proposed extension for Java. It canliketo prevent too much heap fragmentation with lot of tiny memory blocks.I'm for that.Other than that, D seems like a great and well designed language withmostlyreasonable compromises. It removes most of the things I hated in C++dependingpre-processor, completely useless . -> and :: separation, forward declarations, #include (parse these headers again and again and again...orstruggle with restricted precompiled headers), ambiguous syntaxonbethe nature of a symbol like (type)-1 instead or (var)-1 and last but not least, added missing language supported safe garbage collection (=>full RTTI) and class properties (exist only as non-portable extensions inBorlandC++ Builder and MSVC).Yup. Now if it just had operator overloading and generics and DFront I'dall set to switch over. ;) Actually that's not true... until I can write extremely lightweightclasses(like a replacement for int, or a 3d math library) or at least get builtin 3D math stuff, I won't be able to switch for performance reasons. Sean
Jan 21 2002
It's funny how all the folks who "have rarely used it" are the most voiceful critics of operator overloading. Probably the same goes for templates. If you guys actually used this stuff for anything you'd realize that it is *very* nice to have. Since you don't personally use it you think that nobody else does either. If you had operator overloading (especially the kind where you could make up new operators, not just overload existing ones) you could make your own damn rotate operator. ;) Think about that for a while. You can't go asking the language designer to add every little thing you want to the language spec. That's why operator overloading and templates are nice, you can kinda "extend" the language to suit your needs. Sean "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message news:a2h3ii$1e0p$1 digitaldaemon.com...Real boolean type YES. Operator Overloading NO! rotate operators please. although a boolean xor does not exists; you can do if ((x<8) ^ (y>9) ) or use != I like Java's approach to booleans. && and || are boolean, and can be short cut by the comiler in the same wayCdoes & | ^ can be boolean but both sides will be evaluated (xor has to evalbothsides) and if and while should be if (boolean-expression) {..} true this means that if ( a = b ) has to become if ( (a=b) != 0 ) but a 5 extra chars for a lot of time saved finding bugs. for the same reason I also like perls aproach to blocks instead of if ( expr ) stmt [else stmt] if ( bool-expr ) block [elseif (bool-expr) block ][else block] but that can wait for another day... as for operator overloading, your example is to me the prime reason forNOThaving operator overloading, on the surface it looks like one thing but is infact something else if I want to write a parser, I'll use Lex/Yacc/ANTLR I do not deny that operator overloading is powerfull, but it is not realy required and I believe leads to more problem than it solves. in my experiance I have rarely used it ( apart from << and >> on streams) but do not consider that reason enough for it to be included in a language. far more important would be rotate operators all the CPU's I've every used have shift left and right (signed and unsigned) and rotate left and right. why do no languages have rotate operators. instead you have to unsigned shift left but N and shift rightbyinteger-bitlength-N. and it can't be that only the minimum set of bitwise operator require are available because then you would have rotate right (or left) and nand (or nor) ! I have required rotate operations far more than operator overloading Mike. "Sean L. Palmer" <spalmer iname.com> wrote in message news:a2gikm$131g$1 digitaldaemon.com...exclusive-or"Christophe Bouchon" <cbouchon hotmail.com> wrote in message news:a2ensl$2uac$1 digitaldaemon.com...These are my 2 cents opinions: 1) Like most programming languages, D is missing a booleancond2operator. I can't count the number of times I had to write something like: if ((cond1 && !cond2) || (!cond1 && cond2)) // bad if cond1 and/or(cond1have side effect or if ((cond1 != 0) ^ (cond2 != 0)) the "!= 0" above are required if cond1 or cond2 can be such that&booloftencond2) == 0 but (cond1 | cond2) != 0, like cond1==2 and cond2==4. I don't use this kind of condition as often as simple || and && butoperator...enough to be realy anoyed. Pppllllease, add a ^^ boolean exclusive-or operator !C (and C++ and Java and D) already *have* a boolean exclusive-orit's " != " !!! :) if ((cond1 != 0) != (cond2 != 0))2) I think that mostly, a real intrisic bool type (and requiring bool arguments to if, while, &&, ||, ^^, !...) is a good thing and protect against lots of hard to catch errors. After all, D documentation says:Who D is For Programmers who routinely use lint or similar code analysis tools toeliminate bugs before the code is even compiled. And declaring a variable as bool instead of int is better for code documentation. Perhaps a compiler option to allow/prevent automatic convertion toininbeconditionals should be the best option to satisfy everybody.I sit on the fence on this issue. I don't really have a preference.3) I also add my support for operator overloading. I agree that it canabused (you can find abuses of any programming language feature) butthinksome cases, it can be used in a very nice and readable way. If youanhttp://spirit.sourceforge.net/it's just good for complex numbers, look atfor an example of a clean, usefull and nice operator overloading usagewithtemplates: you get lex+yacc capabilities directly within C++ source,parserEBNF-like notation (with overloaded C++ operators) constructing a+digit)[&doInt] ];during object construction, the constructed variables becoming theautomatonof the parser. Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >>thearerule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]); The >> is a sequence, !, * and + (with a single argument on the right)the 0-or-1, 0-or-more and 1-or-more repetitions, the actions are in[]tooverloaded(functions with pointers to the first and last elements parsed by therule)and | is an alternative. Execution of a rule returns the number ofelementsmatched. The ch_p('+') is there because '+' | '-' can't use thefunctional|. digit is a predifined single digit parser, doInt, doAdd... are some simple action functions not included here. Then you just do something like: parse(expr, "1 + ((6 * 200) - 20) / 6");Sounds very cool. I love operator overloading... many many casesnotation just makes the code uglier. Sure operator overloading can be abused, but as you show above it can also be a powerful tool.4) Perhaps also add non-vitual member functions to struct to be ableagain...helphandle light/simple objects on the stack or embeded inside other struct/class (for allocation speed). This is what's done in the .NET framework and I think it's also a proposed extension for Java. It canliketo prevent too much heap fragmentation with lot of tiny memory blocks.I'm for that.Other than that, D seems like a great and well designed language withmostlyreasonable compromises. It removes most of the things I hated in C++pre-processor, completely useless . -> and :: separation, forward declarations, #include (parse these headers again and again andnotordependingstruggle with restricted precompiled headers), ambiguous syntaxonthe nature of a symbol like (type)-1 instead or (var)-1 and last but(=>fullleast, added missing language supported safe garbage collectionI'dRTTI) and class properties (exist only as non-portable extensions inBorlandC++ Builder and MSVC).Yup. Now if it just had operator overloading and generics and DFrontbebuiltinall set to switch over. ;) Actually that's not true... until I can write extremely lightweightclasses(like a replacement for int, or a 3d math library) or at least get3D math stuff, I won't be able to switch for performance reasons. Sean
Jan 21 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a2hn3d$1rkp$1 digitaldaemon.com...It's funny how all the folks who "have rarely used it" are the mostvoicefulcritics of operator overloading. Probably the same goes for templates.Of course, If you do not like it, you do not used it!If you guys actually used this stuff for anything you'd realize that it is *very* nice to have. Since you don't personally use it you think that nobody else does either.No, I know people who do, but I do not agree that it helps the program in any way it may help one programmer, but it you are working on a project with several people and as is often the case programs that where written by people who no longer work for the company, code has to be readable to all so I don't use it because as you say it enhances the language, but in ways that are not always inline with the rest of the language. I have worked for people who would have sacked me If I produced code like your example. I would read Walters explanation for not including operator overloading.If you had operator overloading (especially the kind where you could makeupnew operators, not just overload existing ones) you could make your owndamnrotate operator. ;) Think about that for a while.my point against overloading is that initial observation of the code make make someone else believe that you code does things that it is not.. and I want a rotate operator not a function masked behind syntax. if I overload operator an to do a rotate I still have to use shift left and right to perform the operation, just as I do with a rotate function it is just syntatic sugar. or use assembler and then it only works on one CPU.You can't go asking the language designer to add every little thing youwantto the language spec. That's why operator overloading and templates are nice, you can kinda "extend" the language to suit your needs.Templates I like, but again D supports Dynamic arrays and Hashtables, they could be implemented as template classes, but apart from collections, I have not seen templates used in commersial apps. and I still stand by my initial observation that this example is exactly why operator overloading should not be included. for us meer mortals, that have spent 2 years working on a project that ends up with a couple of megs of source, it's damn hard to remember what you wrote. So any features that help the confusion are avoided. Mike.+digit)[&doInt] ];Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >>rule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]);
Jan 21 2002
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message news:a2hsk0$1v0r$1 digitaldaemon.com..."Sean L. Palmer" <spalmer iname.com> wrote in message news:a2hn3d$1rkp$1 digitaldaemon.com...isIt's funny how all the folks who "have rarely used it" are the mostvoicefulcritics of operator overloading. Probably the same goes for templates.Of course, If you do not like it, you do not used it!If you guys actually used this stuff for anything you'd realize that iteither.*very* nice to have. Since you don't personally use it you think that nobody else doesNo, I know people who do, but I do not agree that it helps the program in any way it may help one programmer, but it you are working on a project withseveralpeople and as is often the case programs that where written by people whonolonger work for the company, code has to be readable to all so I don't use it because as you say it enhances the language, but in ways that are not always inline with the rest of the language.People who cannot understand a section of code shouldn't be working on that section of code. If they know enough to be able to justifiably critique such code, they are perfectly capable of replacing such code with something they can read easier. Sometimes some readability has to be sacrificed for the sake of writability. Tools like this make code easier to write.I have worked for people who would have sacked me If I produced code like your example.Wasn't my example, but personally I think the Spirit parser generator is a wonderful example of the kinds of brilliant things people will figure out how to do given a set of powerful tools (templates + operator overloading). Sure, they're "abusing" the normal syntax of C++, but they get a working user-defined parser generated for them from nice easy EBNF-like notation by their humble C++ compiler. ;) Try doing anything close to that without using either templates or operator overloading, I'd love to see it. Ask Walter what a recursive-descent parser written in straight C (or D) looks like, and how easy it is to maintain that kind of monster. I think it's a very good trade-off, one I'd be willing to make. If you think about it, even functions are merely a tool to help the programmer hide code that they aren't concerned with at the time. You really don't *want* to see every little thing that's going on in your program, your brain would explode. If you want that, you should program assembly. Even assemblers use macros. With operator overloading, at least you can step into the operator functions in the debugger if you so desire. Or take a few seconds to hit "browse" on one of the variables to see where it's defined... that's a good idea anyway. Never assume types of variables without seeing their declarations.makeIf you had operator overloading (especially the kind where you couldupandnew operators, not just overload existing ones) you could make your owndamnrotate operator. ;) Think about that for a while.my point against overloading is that initial observation of the code make make someone else believe that you code does things that it is not.. and I want a rotate operator not a function masked behind syntax. if I overload operator an to do a rotate I still have to use shift leftright to perform the operation, just as I do with a rotate function it is just syntatic sugar. or use assembler and then it only works on one CPU.Not all CPUs even have a rotate instruction. After that you'll be wanting a rotate with carry operator. ;) It's not often in a high level language you find yourself needing a rotate operator anyway.wantYou can't go asking the language designer to add every little thing youhaveto the language spec. That's why operator overloading and templates are nice, you can kinda "extend" the language to suit your needs.Templates I like, but again D supports Dynamic arrays and Hashtables, they could be implemented as template classes, but apart from collections, Inot seen templates used in commersial apps.You haven't worked much, have you?and I still stand by my initial observation that this example is exactlywhyoperator overloading should not be included. for us meer mortals, that have spent 2 years working on a project thatendsup with a couple of megs of source, it's damn hard to remember what you wrote. So any features that help the confusion are avoided.I feel your pain. SeanMike.+digit)[&doInt] ];Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >>rule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]);
Jan 22 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a2je9c$2v8i$1 digitaldaemon.com...People who cannot understand a section of code shouldn't be working onthatsection of code. If they know enough to be able to justifiably critique such code, they are perfectly capable of replacing such code withsomethingthey can read easier. Sometimes some readability has to be sacrificed for the sake of writability. Tools like this make code easier to write.No one understands fully a section of code someone else wrote the first time they see it. and I've not worked for a company that would allow such replacement without good justification, and have work for one company where every line of code written always had to be reviewed by someone else before you could submit it into the source tree. painfull at times, but did mean that more than one person could modify any section.Wasn't my example, but personally I think the Spirit parser generator is a wonderful example of the kinds of brilliant things people will figure out how to do given a set of powerful tools (templates + operatoroverloading).Sure, they're "abusing" the normal syntax of C++, but they get a working user-defined parser generated for them from nice easy EBNF-like notationbytheir humble C++ compiler. ;) Try doing anything close to that without using either templates or operator overloading, I'd love to see it. Ask Walter what a recursive-descent parser written in straight C (or D) looks like, and how easy it is to maintain that kind of monster. I think it's a very good trade-off, one I'd be willing to make.you yourself say 'they're "abusing" the normal syntax of C++' exactly my reason for not liking operator overloading. as I said, if you want to write a parser use Lex/Yacc and I've written recursive-descent parsers in C, Delphi and Java by hand the generated abstract syntax trees for interpreters but I prefered JavaCC and Lex/Yacc (a lot more maintainable).If you think about it, even functions are merely a tool to help the programmer hide code that they aren't concerned with at the time. You really don't *want* to see every little thing that's going on in your program, your brain would explode. If you want that, you should program assembly. Even assemblers use macros.I've did some DOS real mode assembler mixed with C about 8 years ago, Segmented memory near,far and huge pointers what fun, and little MIPS and a bit or ARM/Thumb and some x86 Protected mode.With operator overloading, at least you can step into the operatorfunctionsin the debugger if you so desire. Or take a few seconds to hit "browse"onone of the variables to see where it's defined... that's a good ideaanyway.Never assume types of variables without seeing their declarations.you use VC++ then, give gdb a go (without ddd). you should not have to run the debugger to know what a program is doing.You haven't worked much, have you?anout 6 major projects in the last 8 years, all involving at least 2 languages in C++, C or Java with bits of Perl and one with some PHP. on several platforms and architectures. I used mysql++ on one project, along side Perl/DBI and PHP, I was tempted to use Perl/TK instead as I did not find it actually improved anything, infact it just obscured what was going on. I wanted to create SQL statements and get data back, the only reason for not using the C Api is C's lask of dynamic strings and automatic resouce management. and I think my adversion to operator overloading stems from the set of languages that I have used at the same time, if you have to write a Java program and read someone else Perl source to check you doing the right thing, or MFC programs with Perl and PHP it's nice if they look familiar. and having written two large applications in Java going back to C++ felt realy odd, infact I started to perfer C, if was going to have more control over what was going on I wanted full control. As Walter said in the D overview, Apart from SmartPointers and Strings what do you use operator overloading for ? I prefer to see myStream.ouput( MyObject ); to myStream << MyObject; Java StringBuffer class returns ref to itself so you can do myBuffer.append( 'a' ).append('b'); much like myBuffer << 'a' << 'b'; I know the behaviour without having to look it up if you overload operator = do you get a right associative operator I can't find an answer to this in my C++ book. and I consider "operator ++(int i){}" a bodge. and MyBuffer >> a >> b; can easily be misread but MyBuffer.read( a ).read(b); can not. give me an example where operator overloading in D would improve the language not just save a few chars or be a "cool" way of doing something but improve the readablility, debugability, maintainability and reduce the learning curve for new employees. things that are important to a company. who are, from my experiance, anyways selling products where the ink is still wet on the designs. Mike.
Jan 22 2002
As Walter said in the D overview, Apart from SmartPointers and Strings what do you use operator overloading for ? I prefer to see myStream.ouput( MyObject ); to myStream << MyObject; Java StringBuffer class returns ref to itself so you can do myBuffer.append( 'a' ).append('b'); much like myBuffer << 'a' << 'b'; I know the behaviour without having to look it up if you overload operator = do you get a right associative operator I can't find an answer to this in my C++ book.Depends on if operator= is written correctly. "Correctly" means that you return a reference to *this. For a detailed explanation, check Item 15 of "Effective C++, 2nd Edition". Because this is not widely known or clearly stated anywhere, the mechanism should only be used by experienced and well trained programmers. But just because guns are dangerous for children doesn't mean police officers shouldn't have them either (and no, I DON'T want to get into a gun rights argument here. It was just the first analogy that came to mind. If you prefer axes and woodcutters (or firemen, depending on the type of axe), that's fine too.) See comments below about automated code review tools and company policies about reviewing usage of dangerous but useful and powerful language features.and I consider "operator ++(int i){}" a bodge.Agreed. But just because the C++ standard committe had a syntax brain fart and signed it into law doesn't mean the whole idea is bad. operator++() and ++operator() could have been used. operator ++pre() and operator ++post() could have been used. operator ++x() and operator x++() could have been used.and MyBuffer >> a >> b; can easily be misread but MyBuffer.read( a ).read(b); can not. give me an example where operator overloading in D would improve the language not just save a few chars or be a "cool" way of doing something but improve the readablility, debugability, maintainability and reduce the learning curve for new employees. things that are important to a company. who are, from my experiance, anyways selling products where the ink is still wet on the designs. Mike.Things that work better with operator overloading: 1. Any numerical type that needs to do math and isn't built into the language. People trying to develop symbolic mathematics engines like Mathematica are going to use types that no compiler on the planet supports natively, and they're going to want to be able to say "a=b+c", not "a.assign(b.plus(c))". 2. ANY class that needs to be sortable through a generic algorithm that is probably going to use < as the decision operator. I refuse to believe that (given a and b as instances of a hypothetical class Fleem): if (Fleem::less_than(a, b)) {...} or if (a.less_than(b)) {...} is REALLY easier to read or understand than: if (a < b) {...} Operator overloading can be misused. It frequently is. Fire the people who repeatedly misuse it. The ability to interface directly to C APIs is dangerous and fraught with potential errors -- do you really want to be without it in a real language? D has pointers, and pointers are some of the most dangerous constructs you can ever give to a programmer. They are present because they are also one of the most powerful tools you can ever give a programmer. The danger of pointers was handled by providing other mechanisms and then basically saying "don't use pointers unless you REALLY have to". Why not do the same with operator overloading? ANY tool can be misused. That does not mean that ALL tools should be outlawed. Make code review tools that find uses of operator overloading in projects. Require code reviews by three or more people before allowing such code. Do not accept "abuses" of syntax. If nothing else, the sheer hassle of this process will remove the desire to casually toss operator overloading into a project. You will end up with operator overloading ONLY in the places that really need it, because that is the only place where programmers are willing to get grilled about their use of it. Apply the code review tools to any incoming library. Alternatively, occasionally apply it to entire projects. Maybe you only need these capabilities 10% of the time. But when you hit that 10% of the time, you're going to find out you REALLY need them. I did a lot of Visual Basic programming at one point in my life. If was really nice of Microsoft to store all the guns away so that I couldn't shoot myself in the foot. Then I found out that I couldn't shoot anything else, either, and now I end up doing all of my programming in C++. When you hit the wall of missing functionality, you can't do anything about it, and you have to switch to another language. While operator overloading is never REQUIRED, there are cases where the alternatives are too painful to consider. I've programmed in COBOL, and I know what hell it is to read code that essentially looks like "add transaction to total giving newtotal", which may be more readable to an accountant, but take me a lot longer to parse than "newtotal = transation + total". (For the sake of argument, let us assume a Currency class that is not supported natively in the language. Such variables exist in many languages designed primarily for financial calculations, because many financial calculations are rounded to the nearest penny, and roundoff errors are discarded -- as insane as that sounds, it is nevertheless true...) Mac Reiter Software Engineer
Jan 22 2002
Because this is not widely known or clearly stated anywhere, the mechanism should only be used by experienced and well trained programmers. But just because guns are dangerous for children doesn't mean police officers shouldn't have them either (and no, I DON'T want to get into a gun rights argument here. It was just the first analogy that came to mind. If you prefer axes and woodcutters (or firemen, depending on the type of axe), that's fine too.) See comments below about automated code review tools and company policies about reviewing usage of dangerous but useful and powerful language features.they don't carry guns where I live, maybe that's why I'm not a fan of operator overloading :) I totally agree, the question is, and every one has a personal postion on this Is operator overloading a big enough gun to justify the extra complexity required within the compiler. There is an interesting thread on IOperator just starting up. Mike.
Jan 22 2002
"Mike Wynn" <mike.wynn l8night.co.uk> ha scritto nel messaggio news:a2jsjb$6ui$1 digitaldaemon.com...[...] As Walter said in the D overview, Apart from SmartPointers and Stringswhatdo you use operator overloading for ? I prefer to see myStream.ouput( MyObject ); to myStream << MyObject;Maybe that's because you know what 'output' means. What about: myStream.dajjeggiu(myObject) ? And what about: myInteger.increment(); where: class Integer { ... void increment() { value *= 3.14; } private: int value; } You think that operator overloading is not clear because you're not used to it. Doing operator overloading the right way is not confusing more than using functions. Writing functions the wrong way is confusing too.Java StringBuffer class returns ref to itself so you can do myBuffer.append( 'a' ).append('b'); much like myBuffer << 'a' << 'b'; I know the behaviour without having to look it upI also know the behaviour of operator << without having to look it up, but maybe someone don't know what 'append' means.if you overload operator = do you get a right associative operator I can't find an answer to this in my C++ book.Operator precedence and associativity is one and only one. The parser decided this at an earlier stage. So operator = is right-associative. This is written somewhere in your book. Something that is not specified is order of evaluation in function parameters: int i = 43; int j = function1(++i, i++); You'll get different results for different _compilers_. (BTW, How this is handled in D?)and I consider "operator ++(int i){}" a bodge.A trick. I would otherwise remove the post-increment operator (it's useless).and MyBuffer >> a >> b; can easily be misread but MyBuffer.read( a ).read(b); can not.Why?give me an example where operator overloading in D would improve the language not just save a few chars or be a "cool" way of doing something but improve the readablility, debugability, maintainability and reduce the learning curve for new employees. things that are important to a company. who are, from my experiance, anyways selling products where the ink isstillwet on the designs.Sure, operator overloading doesn't add much to the language. But this way there is no need for identifiers: double sub 2000 (double, double) ... double = 0.33; double = 0.44; What identifiers add to the language? They add a lot for an human reader, if he/she knows what they mean. Look: double ffff(double ab, double cd) { return ab + cd - (ab * cd); } ... double hh = 0.33; double ii = 0.44; double gg = ffff(hh, ii); printf("%g", gg); This doesn't add much. But: double compound_probability(double p1, double p2) { return p1 + p2 - (p1 * p2); } ... double p_A = 0.33; double p_B = 0.44; double p_AorB = compound_probability(p_A, p_B); printf("%g", p_AorB); Or: Probability operator | (Probability a, Probablility b) { ... } ... Probability p_A(0.33); Probability p_B(0.44); Probability p_AorB = p_A | p_B; cout << p_AorB; Ciao
Jan 23 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a2je9c$2v8i$1 digitaldaemon.com...People who cannot understand a section of code shouldn't be working onthatsection of code. If they know enough to be able to justifiably critique such code, they are perfectly capable of replacing such code withsomethingthey can read easier. Sometimes some readability has to be sacrificed for the sake of writability. Tools like this make code easier to write.And much easier to read, I'd say, once you learn the syntax of that user-defined sub-language, or DSL (Domain Specific Language).likeI have worked for people who would have sacked me If I produced codeoverloading). He has a point, though. Code like that, developed in-house, requires a guru-head programmer in order to maintain it. That can definitely become a problem. For example, at Ronin, where I work, I'm the only guru-head like that, and I've done my share of template craziness. If I leave the company, there could be a serious problem because of that. Things like Spirit, though, which are externally-developed libraries are less of an issue. And they show that C++ templates, even flawed as they might be, are tremendously powerful.your example.Wasn't my example, but personally I think the Spirit parser generator is a wonderful example of the kinds of brilliant things people will figure out how to do given a set of powerful tools (templates + operatorSure, they're "abusing" the normal syntax of C++, but they get a working user-defined parser generated for them from nice easy EBNF-like notationbytheir humble C++ compiler. ;) Try doing anything close to that without using either templates or operator overloading, I'd love to see it.Try reading about "monadic parser combinators" for the Haskell language. It doesn't have operator overloading (well, it has, kind of, but in a very different way). And it sure doesn't have templates. But it can do even better at creating powerful BNF-like parsers.If you think about it, even functions are merely a tool to help the programmer hide code that they aren't concerned with at the time. You really don't *want* to see every little thing that's going on in your program, your brain would explode. If you want that, you should program assembly. Even assemblers use macros.Exactly. This is a concept that is hard to really understand for many programmers. Just by creating a function or a typedef in a library, you're actually modifying the language used to write your programs. Operator overloading is no different from function overloading, really. And libraries like Spirit just go one step further, creating a complete sub-language. You already have some sort of operator overloading by allowing "+" to be used for integers, floats and complex numbers, for example. Salutaciones, JCAB
Jan 22 2002
Juan Carlos Arevalo Baeza wrote:For example, at Ronin, where I work, I'm the only guru-head like that, and I've done my share of template craziness. If I leave the company, there could be a serious problem because of that.Heh, I hadn't noticed your email address prior to this. Tell the Blue Planet guys that Russell B says hi. -RB
Jan 22 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a2je9c$2v8i$1 digitaldaemon.com...Ask Walter what a recursive-descent parser written in straight C (or D) looks like, and how easy it is to maintain that kind of monster.Actually, it isn't very hard. Then again, I'm used to writing them. C++ is hard because the grammar doesn't make any sense - then again, a yacc isn't going to help much with that, either. A colleague of mine is working on a vbscript implementation. She's using bison. She told me that it was so much trouble that, if she was doing it over, she'd use a custom recursive descent parser. With D, the lexer/parser is the easy part. Of course, that's by design <g>. I know I'm in the minority dissing parser generators, most people find them useful, but hey, you asked!
Jan 25 2002
Not all. Virtually all. And not all CPU's support floats. So by your argument should floats be dropped also? Those CPU's that do not have a ROL opcode will be obligated to preform extra work to supply one. Tough! Sean L. Palmer <spalmer iname.com> wrote in message news:a2je9c$2v8i$1 digitaldaemon.com...Not all CPUs even have a rotate instruction. After that you'll be wantingarotate with carry operator. ;) It's not often in a high level languageyoufind yourself needing a rotate operator anyway.
Feb 04 2002
I have never used operator overloading, but I have had the "need" for it on several occasions. I understand it's utility, and I understand that programmers can't be trusted to use it properly. Face the truth. If programmers could be trusted modern languages that inforce structured programming and object oriented programming wouldn't be needed. Structure must be imposed on programmers, because programmers are for the most part don't have a clue. Programmers do wonderful things like inputting strings into buffers without checking for overflow conditions. Programmers do things like write languages that don't support nested comments. Programmers do brilliant things like redefining the multiply symbol to mean <Add a record to the database>. Providing the ability to create new operators on the other hand is a blessing. And yes you would be able to create your own Roll operators. Why? ROL is a standard part of most every CPU's native vocabulary. You issue a single opcode to implement it. Creating ROL out of a string of high level functions and pretending that the C compiler will properly optimize it to it's single opcode equivalent is the height of foolishness. Build in two new shift functions... Call them ROL and ROR. Sean L. Palmer <spalmer iname.com> wrote in messageIt's funny how all the folks who "have rarely used it" are the mostvoicefulcritics of operator overloading. Probably the same goes for templates. If you guys actually used this stuff for anything you'd realize that it is *very* nice to have. Since you don't personally use it you think that nobody else does either. If you had operator overloading (especially the kind where you could makeupnew operators, not just overload existing ones) you could make your owndamnrotate operator. ;) Think about that for a while.
Feb 04 2002
You're right, I'd rather have ROL/ROR built in, and emulated on those (rare) cpu's that don't support it in hardware. But then what about RCR/RCL? Those are useful too. I'm sure we could find many asm instructions for one machine or another that would occasionally be nice to have as operators in our nice high level language. Gotta draw the line somewhere though. You've got to trust the programmers at least a little bit. If they really suck that bad you should fire them or send them back to programming school. Imposed structure that limits utility is no good, it just forces the good programmers to jump through hoops to get what they need. Imposing structure that doesn't keep you from doing anything (just keeps you from doing it wrongly) is a Good Thing however. Sean "D" <s_nudds hotmail.com> wrote in message news:a3lk03$s9l$1 digitaldaemon.com...I have never used operator overloading, but I have had the "need" for itonseveral occasions. I understand it's utility, and I understand that programmers can't be trusted to use it properly. Face the truth. If programmers could be trusted modern languages that inforce structured programming and object oriented programming wouldn't be needed. Structure must be imposed on programmers, because programmers are for the most part don't have a clue. Programmers do wonderful things likeinputtingstrings into buffers without checking for overflow conditions.Programmersdo things like write languages that don't support nested comments. Programmers do brilliant things like redefining the multiply symbol tomean<Add a record to the database>. Providing the ability to create new operators on the other hand is a blessing. And yes you would be able to create your own Roll operators. Why? ROL is a standard part of most every CPU's native vocabulary. You issue a single opcode to implement it. Creating ROL out of a string of high level functions and pretending that the C compiler will properly optimize it to it's single opcode equivalent is the height of foolishness. Build in two new shift functions... Call them ROL and ROR. Sean L. Palmer <spalmer iname.com> wrote in messageisIt's funny how all the folks who "have rarely used it" are the mostvoicefulcritics of operator overloading. Probably the same goes for templates. If you guys actually used this stuff for anything you'd realize that iteither.*very* nice to have. Since you don't personally use it you think that nobody else doesmakeIf you had operator overloading (especially the kind where you couldupnew operators, not just overload existing ones) you could make your owndamnrotate operator. ;) Think about that for a while.
Feb 04 2002
Rotations through the carry would be nice, but no high level language gives you access to the condition code register. In fact many modern RISC CPU's don't have condition code registers at all, hence there is no carry to rotate through. Sad... Rather these CPU's store the result of comparisons in another register which is then specified in a conditional jump that typically follows. I don't particularly like the concept but it does offer some nice advantages with regard to pipelining instructions and parallel processing. I would prefer a setup where a destination condition code register could be specified for each operation. This is perferable to me because the various operating flags that can be generated in parallel with performing your typical CPU operation can be immediately used in a conditional to follow. Without having a at least one dedicated condition code register, you lose the ability to do that. . Whatever... The fact is, you don't have access to the condition code register, and I don't see how you could reasonably give access to it in a HLL. Operator overloading provides <no> additional functionality. It simply adds the potential of improved code clarity and simplifies code writing and correctness. However the way overloading is implemented in C/C++ where the existing operators can be overloaded, code clarity is typically reduced, because most of the situations where overloading is useful don't lend themselves to the common meanings of the existing operators. In some instances you can stretch the meanings, like using "+" for adding a record or appending strings, or "-" for deleting a record. But there simply aren't sufficient operators so you end up doing things like record = record * record, and nonsense like that. Much better to allow the creation of new operators and impose a syntax where the new operators are easily distinguished from variables. Sean L. Palmer <spalmer iname.com> wrote in message news:a3lom3$uj1$1 digitaldaemon.com...You're right, I'd rather have ROL/ROR built in, and emulated on those(rare)cpu's that don't support it in hardware. But then what about RCR/RCL? Those are useful too. I'm sure we could find many asm instructions foronemachine or another that would occasionally be nice to have as operators in our nice high level language. Gotta draw the line somewhere though. You've got to trust the programmers at least a little bit. If they really suck that bad you should fire them or send them back to programmingschool.Imposed structure that limits utility is no good, it just forces the good programmers to jump through hoops to get what they need. Imposingstructurethat doesn't keep you from doing anything (just keeps you from doing it wrongly) is a Good Thing however. Sean "D" <s_nudds hotmail.com> wrote in message news:a3lk03$s9l$1 digitaldaemon.com...beI have never used operator overloading, but I have had the "need" for itonseveral occasions. I understand it's utility, and I understand that programmers can't be trusted to use it properly. Face the truth. If programmers could be trusted modern languages that inforce structured programming and object oriented programming wouldn'ttheneeded. Structure must be imposed on programmers, because programmers are foramost part don't have a clue. Programmers do wonderful things likeinputtingstrings into buffers without checking for overflow conditions.Programmersdo things like write languages that don't support nested comments. Programmers do brilliant things like redefining the multiply symbol tomean<Add a record to the database>. Providing the ability to create new operators on the other hand is a blessing. And yes you would be able to create your own Roll operators. Why? ROL is a standard part of most every CPU's native vocabulary. You issuelevelsingle opcode to implement it. Creating ROL out of a string of hightofunctions and pretending that the C compiler will properly optimize ittemplates.it's single opcode equivalent is the height of foolishness. Build in two new shift functions... Call them ROL and ROR. Sean L. Palmer <spalmer iname.com> wrote in messageIt's funny how all the folks who "have rarely used it" are the mostvoicefulcritics of operator overloading. Probably the same goes foritIf you guys actually used this stuff for anything you'd realize thatisowneither.*very* nice to have. Since you don't personally use it you think that nobody else doesmakeIf you had operator overloading (especially the kind where you couldupnew operators, not just overload existing ones) you could make yourdamnrotate operator. ;) Think about that for a while.
Feb 04 2002
"D" <s_nudds hotmail.com> wrote in message news:a3lk03$s9l$1 digitaldaemon.com...I have never used operator overloading, but I have had the "need" for itonseveral occasions. I understand it's utility, and I understand that programmers can't be trusted to use it properly. Face the truth. If programmers could be trusted modern languages that inforce structured programming and object oriented programming wouldn't be needed. Structure must be imposed on programmers, because programmers are for the most part don't have a clue. Programmers do wonderful things likeinputtingstrings into buffers without checking for overflow conditions.Programmersdo things like write languages that don't support nested comments. Programmers do brilliant things like redefining the multiply symbol tomean<Add a record to the database>.Give me a language that (cough) "enforces" structure and I'll show you ways to abuse it to the point that you cry when you have to maintain that code for a living. Give me a language that doesn't "allow" structured code to be written and I'll show you ways to code with it that makes you go to bed at night with a smile on your face. Bottom line, a language should offer the possibility to write structured, readable code. It should not force you to use difficult and error prone features such as pointers. There are always moments that using a pointer, or functions instead of classes are cleaner than difficult workarounds however, and a language should not shut them out just because they 'might' be abused. In C dealing with simple strings is a nightmare (strcmp, strcat, strcpy, char[], char *), maybe that is the reason "Programmers do wonderful things like inputting strings into buffers without checking for overflow conditions.", and not that they "for the most part don't have a clue". -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 04 2002
Every language can be abused. True enough. Poor programmers do such things, and poor languages provide insufficent structure to avoid the abuses. I take it then that you believe structured languages should be abandoned because spaghetti code is the way to go? OddesE <OddesE_XYZ hotmail.com> wrote in message news:a3msuv$1se0$1 digitaldaemon.com...Give me a language that (cough) "enforces" structure and I'll show you ways to abuse it to the point that you cry when you have to maintain that code for a living. Give me a language that doesn't "allow" structured code to be written and I'll show you ways to code with it that makes you go to bed at night with a smile on your face.Well, when dealing with arrays of data, you have two choices, using array references or using pointer references. Pointer references have the advantage of being significantly faster since the content of the pointer is maintained between array references while with array references the pointer must be computed from the specified index for each reference. Some optimizations are possible at times, but typically none are performed by compilers from what I have seen. Buffer processing in C/C++ programs is often done without error checking because of the programming philosophy built into the language. That philosophy is to provide half baked, half working solutions to problems that usually work, but fail if the user steps outside the box. "Who is going to enter a 5K string into my password checker? No one is going to sit there and type for 5 minutes to fill the buffer. So if I set the buffer to 5K then no one is ever going to cause a problem, and 5K isn't too much memory to waste, and it makes my programming task so much easier." That is the mindset of your typical C/C++ programmer. As a result, 80% of security exploits are the result of failure to check for buffer overflows that clobber the stack. If you don't believe this sad ideology is built into the language, I draw your attention to GETS in the standard library.Bottom line, a language should offer the possibility to write structured, readable code. It should not force you to use difficult and error prone features such as pointers. There are always moments that using a pointer, or functions instead of classes are cleaner than difficult workarounds however, and a language should not shut them out just because they 'might' be abused. In C dealing with simple strings is a nightmare (strcmp, strcat, strcpy, char[], char *), maybe that is the reason "Programmers do wonderful things like inputting strings into buffers without checking for overflow conditions.", and not that they "for the most part don't have a clue".
Feb 04 2002
"D" <s_nudds hotmail.com> wrote in message news:a3njn6$29ud$1 digitaldaemon.com...Every language can be abused. True enough. Poor programmers do such things, and poor languages provide insufficent structure to avoid the abuses. I take it then that you believe structured languages should be abandoned because spaghetti code is the way to go?Ofcourse not. I agree with you that a lot of problems can be solved with structured programming like OO. In fact, I love OO. I don't agree with you though that programmers used to write spaghetti code because they didn't want to write better code or because they just didn't care. I think that the causes for the spaghetti code of the past (and I wrote some too :) ) are the facts that programming was new and we didn't know much about structuring code and that languages provided no easy ways of writing structured code. goto was there, so people used it. classes where not there, so people didn't use them. But to turn this around and say that languages should not provide any constructs that *could* be abused, even though they might be veru usefull, is a different story altogether.OddesE <OddesE_XYZ hotmail.com> wrote in message news:a3msuv$1se0$1 digitaldaemon.com...isGive me a language that (cough) "enforces" structure and I'll show you ways to abuse it to the point that you cry when you have to maintain that code for a living. Give me a language that doesn't "allow" structured code to be written and I'll show you ways to code with it that makes you go to bed at night with a smile on your face.Well, when dealing with arrays of data, you have two choices, using array references or using pointer references. Pointer references have the advantage of being significantly faster since the content of the pointermaintained between array references while with array references thepointermust be computed from the specified index for each reference. Some optimizations are possible at times, but typically none are performed by compilers from what I have seen. Buffer processing in C/C++ programs is often done without error checking because of the programming philosophy built into the language. That philosophy is to provide half baked, half working solutions to problemsthatusually work, but fail if the user steps outside the box. "Who is going to enter a 5K string into my password checker? No one is going to sit there and type for 5 minutes to fill the buffer. So if I set the buffer to 5K then no one is ever going to cause a problem, and 5Kisn'ttoo much memory to waste, and it makes my programming task so mucheasier."That is the mindset of your typical C/C++ programmer. As a result, 80% of security exploits are the result of failure to check for buffer overflows that clobber the stack. If you don't believe this sad ideology is built into the language, I draw your attention to GETS in the standard library.Agreed. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 05 2002
"D" <s_nudds hotmail.com> wrote in message news:a3njn6$29ud$1 digitaldaemon.com...OddesE <OddesE_XYZ hotmail.com>Every language can be abused. True enough. Poor programmers do such things, and poor languages provide insufficent structure to avoid the abuses. I take it then that you believe structured languages should be abandoned because spaghetti code is the way to go?Ofcourse not. I agree with you that a lot of problems can be solved with structured programming like OO. In fact, I love OO. I don't agree with you though that programmers used to write spaghetti code because they didn't want to write better code or because they just didn't care. I think that the causes for the spaghetti code of the past (and I wrote some too :) ) are the facts that programming was new and we didn't know much about structuring code and that languages provided no easy ways of writing structured code. goto was there, so people used it. classes where not there, so people didn't use them. But to turn this around and say that languages should not provide any constructs that *could* be abused, even though they might be veru usefull, is a different story altogether.If mistakes can happen they will happen. This is the lesson of ergonomic system design. Systems that are designed to avoid errors are inherently less prone to error than systems that make no such effort. If a change can be made to avoid error, and which does not alter a system's ability to function then that change is beneficial and will improve reliability without cost. This is the case with things like including xor, and block typing. These things can be hand at essentially zero cost, and provide real benefits that will reduce errors thereby making the language that employs them superior to one that does not. It's as simple as that. .Why Things Bite Back Edward Tenner If it can go wrong, it will--thus Murphy's Law. Science journalist Edward Tenner looks more closely at this eternal verity, named after a U.S. Air Force captain who, during a test of rocket-sled deceleration, noticed that critical gauges had been improperly set and concluded, "If there's more than one way to do a job and one of those ways will end in disaster, then somebody will do it that way." Tenner concurs, and he gives us myriad case studies of how technological fixes often create bigger problems than the ones they were meant to solve in the first place. The indiscriminate use of antibiotics, by way of example, has yielded hardier strains of bacteria and viruses that do not respond to pharmaceutical treatment; the wide-scale use of air conditioning in cities has raised the outdoor temperature in some places by as much as 10 degrees, adding stress to already-taxed cooling systems; the modern reliance on medical intervention to deal with simple illnesses, to say nothing of the rapidly growing number of elective surgeries, means that even a low percentage of error (one patient in twenty-five, by a recent estimate) can affect increasingly large numbers of people. Tenner examines what he deems the "unintended consequences" of technological innovation, drawing examples from everyday objects and situations. Although he recounts disaster after painful disaster, his book makes for curiously entertaining, if sometimes scary, reading. --Gregory McNamee The Logic of Failure Dietrich Dorner, et al That's Not What We Meant to Do: Reform and Its Unintended Consequences in the Twentieth Century Steven M. Gillon Normal Accidents Charles Perrow Systemantics The Underground Text of Systems Lore John Gall, D.H. Gall (Illustrator)
Feb 06 2002
Thank you for pointing out 'sprit'! It is certainly impressive and properly illustrates how features of a 'higher level' language can simplify otherwise tedious tasks. I understand it is not for everyone, but then hey, simple tasks are simple in most of the languages! -Rajiv "Christophe Bouchon" <cbouchon hotmail.com> wrote in message news:a2ensl$2uac$1 digitaldaemon.com...These are my 2 cents opinions: 1) Like most programming languages, D is missing a boolean exclusive-or operator. I can't count the number of times I had to write something like: if ((cond1 && !cond2) || (!cond1 && cond2)) // bad if cond1 and/or cond2 have side effect or if ((cond1 != 0) ^ (cond2 != 0)) the "!= 0" above are required if cond1 or cond2 can be such that (cond1 & cond2) == 0 but (cond1 | cond2) != 0, like cond1==2 and cond2==4. I don't use this kind of condition as often as simple || and && but often enough to be realy anoyed. Pppllllease, add a ^^ boolean exclusive-or operator ! 2) I think that mostly, a real intrisic bool type (and requiring bool arguments to if, while, &&, ||, ^^, !...) is a good thing and protect against lots of hard to catch errors. After all, D documentation says:withWho D is For Programmers who routinely use lint or similar code analysis tools toeliminate bugs before the code is even compiled. And declaring a variable as bool instead of int is better for code documentation. Perhaps a compiler option to allow/prevent automatic convertion to bool in conditionals should be the best option to satisfy everybody. 3) I also add my support for operator overloading. I agree that it can be abused (you can find abuses of any programming language feature) but in some cases, it can be used in a very nice and readable way. If you think it's just good for complex numbers, look at http://spirit.sourceforge.net/ for an example of a clean, usefull and nice operator overloading usagetemplates: you get lex+yacc capabilities directly within C++ source, an EBNF-like notation (with overloaded C++ operators) constructing a parser during object construction, the constructed variables becoming theautomatonof the parser. Simple calculator example: rule<> expr; rule<> integer = lexeme[ (!(ch_p('+') | '-') >> +digit)[&doInt] ]; rule<> group = '(' >> expr >> ')'; rule<> expr1 = integer | group; rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >> expr1)[&doDiv]); expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]); The >> is a sequence, !, * and + (with a single argument on the right) are the 0-or-1, 0-or-more and 1-or-more repetitions, the actions are in the [] (functions with pointers to the first and last elements parsed by therule)and | is an alternative. Execution of a rule returns the number ofelementsmatched. The ch_p('+') is there because '+' | '-' can't use the overloaded |. digit is a predifined single digit parser, doInt, doAdd... are some simple action functions not included here. Then you just do something like: parse(expr, "1 + ((6 * 200) - 20) / 6"); 4) Perhaps also add non-vitual member functions to struct to be able to handle light/simple objects on the stack or embeded inside other struct/class (for allocation speed). This is what's done in the .NET framework and I think it's also a proposed extension for Java. It can help to prevent too much heap fragmentation with lot of tiny memory blocks. Other than that, D seems like a great and well designed language withmostlyreasonable compromises. It removes most of the things I hated in C++ like pre-processor, completely useless . -> and :: separation, forward declarations, #include (parse these headers again and again and again...orstruggle with restricted precompiled headers), ambiguous syntax dependingonthe nature of a symbol like (type)-1 instead or (var)-1 and last but not least, added missing language supported safe garbage collection (=>full RTTI) and class properties (exist only as non-portable extensions inBorlandC++ Builder and MSVC).
Jan 22 2002
An exclusive or operator is needed for both logical and boolean types. call them xor and lxor. If you understood the meaning of the above sentence then the superiority of xor/lxor has been proven. For those who did not understand, it is time to seek another profession. Christophe Bouchon <cbouchon hotmail.com> wrote in message news:a2ensl$2uac$1 digitaldaemon.com...These are my 2 cents opinions: 1) Like most programming languages, D is missing a boolean exclusive-or operator. I can't count the number of times I had to write something like: if ((cond1 && !cond2) || (!cond1 && cond2)) // bad if cond1 and/or cond2 have side effect or if ((cond1 != 0) ^ (cond2 != 0))
Feb 04 2002
"D" <s_nudds hotmail.com> wrote in message news:a3ljb5$s15$1 digitaldaemon.com...An exclusive or operator is needed for both logical and boolean types. call them xor and lxor.^ and ^^, then.
Feb 04 2002
That'd be great, but the point you guys KEEP MISSING is that there's already a boolean exclusive or operator... it's called != !!!!!!!! if ((a && b) != (c && d)) { // executed if either a and b are both true, or c and d are both true, but not if all four are true, and not if both sides of != are false either. } If you add ^^ you'll just end up with two operators that do the same thing. Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:a3lliv$t1a$1 digitaldaemon.com..."D" <s_nudds hotmail.com> wrote in message news:a3ljb5$s15$1 digitaldaemon.com...An exclusive or operator is needed for both logical and boolean types. call them xor and lxor.^ and ^^, then.
Feb 04 2002
I think people are missing the point of && and || they allow for only one side to be evaled not both xor HAS to eval both sizes ^^ serves no purpose the same as you can use & and | to perform && and || but force eval of both sides you can use != or ^ to do an xor. Mike. "Sean L. Palmer" <spalmer iname.com> wrote in message news:a3lott$urf$1 digitaldaemon.com...That'd be great, but the point you guys KEEP MISSING is that there'salreadya boolean exclusive or operator... it's called != !!!!!!!! if ((a && b) != (c && d)) { // executed if either a and b are both true, or c and d are both true,butnot if all four are true, and not if both sides of != are false either. } If you add ^^ you'll just end up with two operators that do the samething.Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:a3lliv$t1a$1 digitaldaemon.com..."D" <s_nudds hotmail.com> wrote in message news:a3ljb5$s15$1 digitaldaemon.com...An exclusive or operator is needed for both logical and boolean types. call them xor and lxor.^ and ^^, then.
Feb 04 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a3lott$urf$1 digitaldaemon.com...That'd be great, but the point you guys KEEP MISSING is that there'salreadya boolean exclusive or operator... it's called != !!!!!!!!In C++ that's not quite true. If you use != as XOR, you won't get the standard type conversions that you do with, for example, &&. This alone makes having a ^^ operator sound like a good idea. Then again, this is maybe not something that D should do: so many standard conversions, like pointer->bool and such.
Feb 04 2002
That operator is not equal, not logical xor. Programming via side effects is a bad programming practice. Include a proper keyword. Sean L. Palmer <spalmer iname.com> wrote in message news:a3lott$urf$1 digitaldaemon.com...That'd be great, but the point you guys KEEP MISSING is that there'salreadya boolean exclusive or operator... it's called != !!!!!!!!
Feb 04 2002