• Zygo (unregistered) in reply to bramzy
    bramzy:
    Btw, what exactly does adding a vector to a matrix do?

    Fail to compile, apparently. I think I meant to write "multiply" but the type-checking in my web browser's text edit box sucks. ;-)

    With a different library the code could have the Matrix try to convert itself into a Vector, then hit a runtime exception if that wasn't possible.

    Which reminds me of double dispatch, another thing that would be nice to have in C++...

  • Captcha: Tastey (unregistered) in reply to TopTension

    The real WTF here is that he didn't overload the ++ operator.

    Bonus points if pre and post increment do something different.

  • JBange (unregistered) in reply to Beowulff
    Beowulff:
    Too bad this thread erupted into a language war.

    Why? Once the customary "goggles do nothing" and "frist!" posts have been made, what else is there to talk about besides whether the problem is that the programmer was a fool, or that operator overloading is itself evil? The story was the equivalent of walking into a [scottish|irish] pub and saying "Scottish, Irish--- what's the difference?"

  • (cs) in reply to Zygo
    Zygo:
    Compare C++ with LISP, which has only a half-dozen or so operators (and that's really stretching the meaning of the word "operator"), no operator overloadin

    If we measure the worth of a language by how much it can do divided by the amount of basic operations it provides to do so, brainfuck is the king of all languages.

    and a lot more expressive power than C++. In LISP, you can redefine the meaning of an entire expression, not just the operators used within it.

    I'm not sure what you mean by redefining an entire expression, but I suspect that it's the same thing as expression templates in C++. Basically, it's a way (using operator overloading and templates) to turn specific expression patterns into specific pieces of code.

    There is more power in operator overloading than just implementing new types in a way that makes them actually work like a type (unlike in java where it's yet one more thing that is forbidden to do For The Greater Good because java's creators apparently think that most java programmers are too retarded to do anything right if they are given useful tools)

    Also, the WTF presented there does not mean that C++ sucks - it means that the guy who wrote that piece of code sucks. If you need a container, use STL. If you really need to implement a custom container, implement iterators for it (and yes, as iterators expose a pointer-like behavior, you need to define operators for them). That's how things are supposed to be done in C++.

    The language try not to limit and constrain you, so of course you can do things differently, but then don't complain that your code sucks.

  • AJS (unregistered) in reply to masklinn
    masklinn:
    Congratulation, you fail. Static or dynamic typing has no relation with the issue at hand, the problem with the auto-coercion between numeric and string types which javascript retardedly tries to perform (PHP is also very guilty of that one).

    ..... stuff deleted ..... Python has a perfectly sane behavior.

    The problem is not with using "+" for both number addition and string concatenation, the problem is with performing automatic coercion between strings and numbers when using the + operator.

    But automatic coercion is not, in and of itself, a bad thing. Having to call a function just to change a string to a number, or vice versa, is a bad thing: it clutters up a program for little real benefit. The computer should be smart enough to work out what someone meant, for crying out loud!

    In Perl and PHP, the code

    print "Do stuff" + 3 + 5;
    prints 8, because the string "Do stuff" returns 0 when evaluated in a numeric context. Only numbers can be added, so + coerces things to be numeric; and only strings can be concatenated, so . coerces things to be strings. This is sane behaviour: using different operators to perform different functions. (Notice that the . is also used to delimit a fraction, so it is sort of being overloaded here. If for some reason you wish to form a string literal by concatenating a series of numeric literals, you do need to surround the concatenation dots with spaces lest they be mistaken for decimal points.)

    The way Python barfs like a statically-typed language over attempting to add "3" + 1 is certainly more sane than trying to guess (the way JavaScript does) whether you were looking for 4 or 31; but if the creators of the language had only thought to use a separate operator for concatenation, it could have coerced the "3" into 3 and added one -- or coerced the 1 into "1" and concatenated it onto the "3", if that was what you indicated -- without breaking step.

    Also, why is it more sane to expect [1,2,3] + [4,5,6] to return [1,2,3,4,5,6] than to expect it to return [5,7,9] ?

  • wien (unregistered) in reply to Zygo
    Zygo:
    What I am saying is that C++ still lacks support for important problem domains (with a few examples of such domains from the LISP world, but there are others from languages I know less well than LISP which I can't talk about with as much depth).
    But in many cases adding support for these problem domains will hurt a lot of the things C++ does well now. Performance (or at the very least memory usage) for instance will most certainly suffer if you start adding all those useful(?) LISP features you have mentioned. All for absolutely no gain to the entire existing C++ codebase.

    It all boils down to the simple fact that no language can be the be all and end all of languages. All of them will have tradeoffs making them more suited to particular problems. If I don't need to iterate over the member functions of an object at run-time, why should the language implement this feature, possibly slowing down the entire object model in the process?

  • AdT (unregistered) in reply to Zygo
    Zygo:
    I did do a mostly-working C preprocessor parser (supporting // and /* */ comments, #define, #include, #if, #ifdef, #ifndef, #else, __FILE__, __LINE__, macros with and without arguments, recursive expansion, # and ##, respecting string and character literals and backslash) years ago in under 5 hours in bare Perl code (in other words, starting from the standard language runtime and an empty text file, and a two-page description of the grammar).

    Now if you make the Perl version half as fast as the C++ version in another 11 hours, we can call it quits. Well, if most of the time is spent in Perl's regex library (which is implemented in C), you might stand a chance.

    But usually people prefer to ignore that when they say that they can solve the problem in less time than in languages other than C(++), they rarely get a solution that is equally efficient.

    Zygo:
    Choosing the right language for solving your problem is as important as choosing the libraries your program depends on and the operating system it runs on--it can affect developer productivity by orders of magnitude. This is something that is difficult to get across to people who have learned only one or two programming languages, especially very similar languages like C, C++, Java, and C#--they simply don't believe that it can take 10 times longer to implement a solution to a particular problem in their favorite language than in one they have never used, although for some reason they accept the reverse without question.

    Well, programming languages that I have used include C, C++, Java and C#, but also Haskell, PROLOG, LISP*, x86 Assembler and Perl. I certainly don't use C++ where a Perl one-liner would do, but I wouldn't even use LISP to configure my text editor. Mostly because I tried that and it nearly drove me mad.

    *) I was forced to, in University, and by Emacs. I'm no longer a student, and I have found ViM, which is insane, but significantly less so than Emacs.

  • AdT (unregistered)

    By the way I use Perl extensively at work, mostly for scripting and for web service programming. Currently I use it to implement a log message aggregation service. I could probably have done this in less time using C++ (not because Perl is so hard to use but because I have much more C++ than Perl experience), but I'm still doing it in Perl because I want the program to be able to dynamically load aggregation and priorization rules, and Perl's eval function is very useful in this context.

  • Jeff (unregistered) in reply to fist-poster
    fist-poster:
    There were a few really large problems and a lot of small ones that accumulated. One was that the linked-list type provided operator[], and someone used it to iterate over a linked list using an integer index in a for loop from 0 to count(). The punch line: both operator[] and count() were O(N) operations, executing N times in a loop.

    Ouch... OK, [] makes no sense for a linked list, but is it really that much overhead to make count() a O(1) operation for all containers by keeping the size at all times?

    But then it wouldn't be a count function!

  • (cs) in reply to AdT

    [quote user="AdT"]Well, programming languages that I have used include C, C++, Java and C#, but also Haskell, PROLOG, LISP*, x86 Assembler and Perl. I certainly don't use C++ where a Perl one-liner would do, but I wouldn't even use LISP to configure my text editor. Mostly because I tried that and it nearly drove me mad.[/quote]

    [quote user="Zygo"]Just for laughs one day, I read the Pentium 4 optimization manual (not all of it, just the summaries in the first few chapters and one or two detailed areas for reference).

    On really small microcontrollers things tend to drift a bit from the ISO C standards. One microcontroller I used had 256 bytes of memory that was 60% faster than the other 63.75K of memory--it could be accessed with 8-bit addresses and a special set of instruction opcodes.[/quote]

    Wow, you guys must be a right laugh down the pub!

    [quote=user="AdT"]Now if you make the Perl version half as fast as the C++ version in another 11 hours, we can call it quits. Well, if most of the time is spent in Perl's regex library (which is implemented in C), you might stand a chance.

    But usually people prefer to ignore that when they say that they can solve the problem in less time than in languages other than C(++), they rarely get a solution that is equally efficient.[/quote]

    Personally, I'll try to use the right tool for job. Is there a performance constraint in place? Cause if there isn't I'll quite happily pop for the Perl version and spend the rest of my day working on something else.

  • (cs) in reply to AdT
    AdT:
    By the way I use Perl extensively at work, mostly for scripting and for web service programming. Currently I use it to implement a log message aggregation service. I could probably have done this in less time using C++ (not because Perl is so hard to use but because I have much more C++ than Perl experience), but I'm still doing it in Perl because I want the program to be able to dynamically load aggregation and priorization rules, and Perl's eval function is very useful in this context.
    Well, I'd warn you off eval in any language, much as I'd warn you off self-modifying assembler.

    I'd also, respectfully, suggest that you revisit emacs at some stage. You don't necessarily have to write elisp to make it work. You could just use it as (in Stroustrup's words, almost) "a better vim."

  • (cs) in reply to Zygo
    Zygo:
    Richard:
    You want the world to run on interpreted languages? Go back to Smalltalk or Lisp you hippy!

    Lisp and Smalltalk are not necessarily interpreted. Compilers do exist for both. The trick is that they keep around the parsed expression trees after generating the machine code (something most C++ compilers don't do). When you have LISP code examining itself, you are actually iterating over the data structure that was compiled into binary machine code. If you generate a new expression tree structure then you can get it compiled by the runtime library and execute it. People used to write whole operating systems in LISP and Smalltalk this way.

    This technique is still used today in a number of big production systems, especially where search queries are user-generated and fairly complicated (much more complicated than most SQL implementations), and the data set fits into a high performance server's RAM. Compiled LISP machine code translates the query into LISP data, then calls a function to turn the LISP data structure into a binary blob of machine code, then executes the binary blob, then frees the memory for the blob.

    Well, I guess it's too late to reply to this (and you) in any meaningful sense, but irrespective of language flame wars -- which I believe I deprecated above, and if not, then I now do -- I absolutely agree with you that a huge weakness in all C++ implementations (that I know of) is that they don't retain the AST, together with tools to make use of that AST.

    What those tools might be, or what they might be used for, is largely irrelevant.

    I'm just not very keen on throwing data away. Particularly when it potentially helps me solve a problem. (Doesn't mean I've got the chops to solve the problem right now: I'd just like to have the resources to learn how to do so. And if that takes another language, then so be it.)

  • (cs) in reply to Zygo
    Zygo:
    real_aardvark:
    Perhaps you'd like to give us a parameterized version of what "useful" might be?

    I meant to summarize the entire flamewar in a single sentence.

    Obviously operator overloading is a powerful tool (if nothing else, it generates vigorous flamewars ;-). If OO didn't have some useful purpose that couldn't be implemented as effectively in another way, it would have never have survived review by the ISO committees. Arguments have been presented across the spectrum ranging from 100% for to 100% against OO. So far, nobody has disputed that OO is a C++ feature. ;-) So at the end of the (second) day, the usefulness of a powerful C++ feature is clearly in dispute.

    Hard to argue against operator overloading as a C++ feature. You, yourself, have quoted exact references to the ANSI spec.

    I suspect that, in all cases other than stream operations (which are implicitly a side effect in general usage), operator overloading has absolutely no use whatsoever, "effective" or otherwise. It's very hard to argue that it's anything else but syntactic sugar. Which, btw, I did argue.

    However, sugar is good, as long as it doesn't rot the teeth.

    Zygo:
    I'm not really trying to say LISP is better than C++ (which seems to be how many people are characterizing my position). <semi-random, but thought-out, snip> It doesn't help that few people who work in these domains can actually understand C++ (never mind they might spend their days designing the hardware C++ runs on).

    <more snip for brevity, but it's available above>

    I would certainly agree that most people who program in C++ don't have a clue what they're doing. I've never met myself, but I'd include myself in the group of people I've met who have never seriously consulted the ANSI standard. (I looked it up once, but it was a Wednesday afternoon, and it was raining.)

    This might, however, be the first ad hominem attack on a programming language that I've ever seen. Perhaps we're all too sophisticated these days. The fact that a bunch of ignoramuses abuse the features of a language (any language) does not mean that the language itself is not useful in a bog-standard problem domain.

    And that's what I meant by "useful." I'm not disagreeing with your other comments. I'm just suggesting that it might be helpful to define where C++ is not "useful."

  • wien (unregistered) in reply to real_aardvark
    real_aardvark:
    I absolutely agree with you that a huge weakness in all C++ implementations (that I know of) is that they don't retain the AST, together with tools to make use of that AST.
    What should happen in cases where entire class hierarchies and huge sequences of function calls have been optimized away then? The AST you end up with after most C++ compilers have done their thing, bares little resemblance to the actual code. Having access to the AST just wouldn't be useful. Alternatively it would cripple C++ optimizers, killing performance.
  • Earl Purple (unregistered)

    Correct thing to do here is to create a wrapper class for the node pointer and overload the operators on that.

    As the wrapper would be a bi-directional iterator but not random-access, operator+(int) would make no sense but operator++ would. Normally you should of course call the prefix operator++.

  • Padmaja (unregistered) in reply to real_aardvark

    Hi, I'm beginner in Perl. I need to concatenate three values in the date format like,

    $fullDate = $ARGV[3] . "/" . $ARGV[4] . "/" . $ARGV[5];

    But while concatenating, it is performing division on values. I have tried '.',':','-' . But its not working. I have to use some separator between the date, month and year.

    Pls suggest me how to proceed.

    Thanks a ton, Padmaja T N.

  • enjoyaol (unregistered)

    i saw this 'rhs' variable stuff in the operators blahblah that comes from a book whose author is Scott Meyers.

  • wayne (unregistered)

    Anyone that uses overloaded operators should have their scrotum used as a pin cushion. Too many programmers want to prove how clever they are vs writing code that is maintainable.

    If you get the desire to write overloaded operators or even overloaded functions please shoot yourself first and save those of us with common sense the desire to do so.

  • Who Me? (unregistered) in reply to ciaranm
    Ah yes, ban all features that can be abused.

    Ah yes... simply ban the POWER SWITCH...all will be good.

  • GenRincewind (unregistered) in reply to Zygo

    Dude, I know I'm necroing this a bit, but I read:"Real programming languages can generate, inspect, or modify existing code at runtime" and you know, that is a horrible idea. I can't even imagine how fucking abusable that feature would be.

Leave a comment on “Yet Another Operator Overloading Abuse”

Log In or post as a guest

Replying to comment #:

« Return to Article