www.digitalmars.com         C & C++   DMDScript  

D - Missing boolean exclusive-or operator, operator overloading and real bool type advocacy

reply "Christophe Bouchon" <cbouchon hotmail.com> writes:
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 to
eliminate 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
next sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
"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:
Who D is For
Programmers who routinely use lint or similar code analysis tools to
eliminate 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.
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 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");
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 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).
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
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
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 (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:
Who D is For
Programmers who routinely use lint or similar code analysis tools to
eliminate 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.
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 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");
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 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).
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
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
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 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
(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:
Who D is For
Programmers who routinely use lint or similar code analysis tools to
eliminate 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.
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 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");
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 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).
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
next sibling parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"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 most
voiceful
 critics 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 make
up
 new operators, not just overload existing ones) you could make your own
damn
 rotate 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 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.
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.
 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]);
Jan 21 2002
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
"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...
 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.
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.
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.
 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.
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.
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.
 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.
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.
You haven't worked much, have you?
 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.
I feel your pain. Sean
 Mike.

 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]);
Jan 22 2002
next sibling parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"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 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.
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 + 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.
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 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.
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
next sibling parent reply reiter nomadics.com (Mac Reiter) writes:
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
parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 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
prev sibling parent "Roberto Mariottini" <rmariottini lycosmail.com> writes:
"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 Strings
what
 do 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 up
I 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 is
still
 wet 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
prev sibling next sibling parent reply "Juan Carlos Arevalo Baeza" <jcab roningames.com> writes:
"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 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.
And much easier to read, I'd say, once you learn the syntax of that user-defined sub-language, or DSL (Domain Specific Language).
 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). 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.
 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.
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
parent Russell Borogove <kaleja estarcion.com> writes:
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
prev sibling next sibling parent "Walter" <walter digitalmars.com> writes:
"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
prev sibling parent "D" <s_nudds hotmail.com> writes:
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 wanting
a
 rotate with carry operator.  ;)  It's not often in a high level language
you
 find yourself needing a rotate operator anyway.
Feb 04 2002
prev sibling parent reply "D" <s_nudds hotmail.com> writes:
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 message
 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.
Feb 04 2002
next sibling parent reply "Sean L. Palmer" <spalmer iname.com> writes:
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 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 message
 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.
Feb 04 2002
parent "D" <s_nudds hotmail.com> writes:
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 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 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 message
 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.
Feb 04 2002
prev sibling parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"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 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>.
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
parent reply "D" <s_nudds hotmail.com> writes:
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
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"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...

 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.
Agreed. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net __________________________________________ Remove _XYZ from my address when replying by mail
Feb 05 2002
parent "D" <s_nudds hotmail.com> writes:
 "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?
OddesE <OddesE_XYZ hotmail.com>
 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
prev sibling next sibling parent "Rajiv Bhagwat" <dataflow vsnl.com> writes:
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:
Who D is For
Programmers who routinely use lint or similar code analysis tools to
eliminate 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 22 2002
prev sibling parent reply "D" <s_nudds hotmail.com> writes:
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
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"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
parent reply "Sean L. Palmer" <spalmer iname.com> writes:
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
next sibling parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
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'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
prev sibling next sibling parent "Juan Carlos Arevalo Baeza" <jcab roningames.com> writes:
"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's
already
 a 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
prev sibling parent "D" <s_nudds hotmail.com> writes:
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's
already
 a boolean exclusive or operator... it's called !=  !!!!!!!!
Feb 04 2002