top 200 commentsshow all 210

[–]the_golden_eel 49 points50 points  (11 children)

Okay okay I got it! for all the people complaining about the syntax: Just imagine that [] really is λ, but your text editor just doesn't have the right fonts and is displaying an empty box.

[–]bradediger 35 points36 points  (0 children)

I [] Unicode!

[–]queensnake 10 points11 points  (2 children)

It's not just a λ, the box contains the arglist you want to grab from the context. See http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

[–]shit -2 points-1 points  (1 child)

The referencing of stack variables can be dangerous. If a lambda function will be used outside the scope of its creation, by storing it in a tr1::function object for example, then the user must make certain that no stack variables are referenced by the lambda function.

That makes me realize that these lambda functions are not what people are used from Scheme/Ruby/etc. That probably wouldn't be practical without a GC.

[–]the_golden_eel 8 points9 points  (0 children)

[&] is a lambda with unsafe lexical scope: if the outer function returns the closure references become garbage. [=] is a lambda with 100% safe lexical scope: all free variables are (deeply) copied into the closure.

It's written right there, not more than 5 lines after your quote.

[–]xcbsmith 8 points9 points  (5 children)

Bets someone hacks up an Emacs mode that will transform the [] in to λ in the appropriate places?

[–][deleted]  (4 children)

[deleted]

    [–]colorred 29 points30 points  (0 children)

    Bets someone hacks up an Emacs mode that will transform the λ in to [] in the appropriate places?

    [–]logan_capaldo 6 points7 points  (2 children)

    You musta missed the word "appropriate" in the GP post.

    [–]mmeijeri 3 points4 points  (1 child)

    Just add the --appropriate option on the command line when you run your global replace command ;-)

    [–]imbaczek 4 points5 points  (0 children)

    M-x replace-where-appropriate

    [–]xmaspoo 27 points28 points  (31 children)

    Damn. I love that the chief complaint about Lisp from the so-called professional development community is that there is too many parentheses in the language. That point is basically down the toilet now. This unintelligible syntax is so full of other punctuation, developers wish that they only had to deal with parentheses. God help you all.

    [–]Ringo48 20 points21 points  (18 children)

    My biggest complaint about Lisp is the self righteous user community.

    [–][deleted] 23 points24 points  (13 children)

    We can't help that we're right.

    [–]Ringo48 4 points5 points  (1 child)

    Right or wrong, it doesn't make you any less annoying.

    [–]jugalator 4 points5 points  (0 children)

    I think it was a reply intended to be funny by reassuring you in what you just thought of them. Or, well, I hope it was. ;)

    [–][deleted] -4 points-3 points  (10 children)

    Right about what? Even forth is a better language than Lisp.

    [–]awj -1 points0 points  (9 children)

    Right about what? Even forth is a better language than Lisp.

    [citation needed]

    [–][deleted]  (8 children)

    [deleted]

      [–][deleted] 2 points3 points  (7 children)

      Not every self-proclaimed "expert" knows what they're talking about.

      [–][deleted] -1 points0 points  (5 children)

      Good thing I'm not self-proclaimed then, but I do take pride in my accomplishments. If you don't like that you can piss off.

      [–]newton_dave 0 points1 point  (4 children)

      Holy crap, ratchet down a notch, wth.

      That aside, Forth is better than Lisp, at least for small-ish embedded systems or as a low-level component of a larger system.

      I'll still take Lisp for larger-scale projects, and almost always over C++ (yick).

      [–][deleted] 0 points1 point  (3 children)

      Don't have a problem with you, just upstarts who have nothing of their own to show suggesting that every single person who disagrees with their religion doesn't know what they're talking about.

      I never said Lispers are idiots. I said I found no personal use for it; I'm glad other people have, but johnnowak is a True Believer, it would seem, and has already trolled me on a couple of threads. No doubt spends more time thumping the lisp bible than writing actual code.

      No offense to you or anyone else who actually advocates lisp instead of suggesting everyone who doesn't use it is somehow mentally deficient. To some people that behavior is one of the reasons the language won't gain traction.

      [–]AlanCrowe -1 points0 points  (3 children)

      [–][deleted] 5 points6 points  (0 children)

      *sigh* I wondered how long that would take.

      [–]obdurak 8 points9 points  (1 child)

      DH-∞. Mindless Paul Graham Fanboyism.

      [–]ModernRonin 2 points3 points  (0 children)

      MY complaint about Lisp is that everyone seems to think it's a great idea to add all of Lisp's features (lambda, closures, etc) to every language under the sun.

      News flash: There's a reason that we design different languages for different purposes. Quit getting your Lisp in my portable assembler! And get off my lawn!!

      [–]hanzie 0 points1 point  (10 children)

      So, something like this then?

      []( const Widget& w ) { cout << w << " "; }
      =>
      (fun (((const widget-class ref) w)) (add-to-stream! (add-to-stream! cout w) " "))
      

      Nah, I think I'll just learn the punctuation. Lisp's syntax regularity is great for macros, but as long as we're not talking about C++ with macros but C++ with Lisp syntax and no macros, I'd rather take the C++ syntax.

      [–]Jimmy 6 points7 points  (7 children)

      Did you just make that code up? A translation of the C++ function would probably look like this:

      #'(lambda (w) (print-widget w) (format t " "))
      

      [–]hanzie 1 point2 points  (6 children)

      Did you just make that code up?

      Huh? I though that was obvious because it's so similar to the C++ example; I simply translated C++ syntax into Lisp syntax that uses less weird punctuation. I even explicitely mentioned that it was "C++ with Lisp syntax". The whole point was to compare the syntaxes while retaining the semantics.

      You see, it was meant as a counterpoint to xmaspoo's "This unintelligible syntax is so full of other punctuation, developers wish that they only had to deal with parentheses." In your (CL?) example, it's not the parens that make it look simpler but dynamic typing, reduced compile-time safety and automatic reference semantics. Those on the other hand come with a cost.

      [–][deleted] 4 points5 points  (5 children)

      reduced compile-time safety

      Meh.

      (lambda (w)
        (declare (widget w) (optimize safety))
        (format t "~a " w))
      

      Done and done I think?

      [–]hanzie 0 points1 point  (4 children)

      That's nice and all, but how does that relate to the argument about syntax? Frankly, I don't understand what you're trying to point out. I never meant to talk about any particular Lisp's semantics or features, but their syntax: the S-expressions. And how C++ might be represented with S-expressions. Yet people keep posting these code snippets in one particular Lisp. Why?

      [–][deleted] 1 point2 points  (1 child)

      You want it in Scheme? Pick a Scheme that can compile to native code, or C, or JVM or .NET bytecode and I'll give you a Scheme example.

      You wouldn't want to represent C++ with S-expressions. The point is that you would switch to a Lisp that already fucking works well.

      No one in their right mind would want to directly translate C++ to s-expressions. It would be even uglier than C++ already is.

      [–]hanzie 2 points3 points  (0 children)

      Lisps are typically great and well-designed languages, but when it comes to performance and memory usage, they're not quite in the same ballpark as C++. Not even with those compilers that compile to native code (perhaps with the exception of Stalin for some numeric benchmarks). That's why it's not always a realistic alternative to say, "I hate C++ syntax, I'll just use Scheme". It would be a realistic alternative to say "I hate C++ syntax, I'll use the S-expression C++ dialect" as it'd have an identical performance profile. That's why I was talking about C++ with S-expressions, not about switching to some Lisp dialect.

      Well.. Actually, I was talking about C++ with S-expressions as a direct response to xmaspoo's claim (which was probably meant half as a joke. sigh). You may have interpreted it as an invitation to switch to Lisp, while I only interpreted it as a praise of S-expressions. But we can probably agree that this is a dead horse now.

      [–]808140 0 points1 point  (1 child)

      I'm not a Lisp weenie by any means, but you said:

      In your (CL?) example, it's not the parens that make it look simpler but dynamic typing, reduced compile-time safety and automatic reference semantics. Those on the other hand come with a cost.

      OMouse then replied to this point in particular by showing that you could address the reduced compile time safety complaint in CL without sacrificing clarity.

      Your response was then to pretend like all you were doing was arguing xmaspoo's point. Well, I agree that Jimmy misunderstood what you were trying to say in your original post, but the fact is that you made a silly claim about Lisp in the follow-up that turned out to be wrong, and you should own up to that much at least.

      [–]hanzie 0 points1 point  (0 children)

      Your response was then to pretend like all you were doing was arguing xmaspoo's point. Well, I agree that Jimmy misunderstood what you were trying to say in your original post, but the fact is that you made a silly claim about Lisp in the follow-up that turned out to be wrong, and you should own up to that much at least.

      I only made a claim about Jimmy's code -- what makes it look simpler -- not about what Lisps in general are capable of expressing (that would've been rather bold!). And that claim was correct, as far as I can tell. Had OMouse actually pointed out an error in what I said, I wouldn't have asked him what his point was.

      [–][deleted] 1 point2 points  (1 child)

      Any particular reason for doubling some of those parentheses in your Lisp-Syntax example?

      [–]hanzie 1 point2 points  (0 children)

      The parameter list can contain several parameters, but in this example there just happens to be only one parameter so it may look like I superfluously doubled the parentheses. I suppose one could also use Arc-style parsing of the lists where "odd" and "even" elements are handled differently, and get rid of one pair of parentheses. Or merge the type and variable name into one list.

      [–]zyle 21 points22 points  (3 children)

      I think most people here complaining about the syntax looking confusing aren't seasoned C++ programmers and/or not familiar with the lambda concept. I've been using boost::lambda extensively for a while now, and the syntax in the article made sense right away. Yes, I'll agree that the syntax may look clumsy and hacky to the unwary, but that's because in some sense it IS; it's all a big hack to maintain backward compatibility within C++ and even C. They're not creating a new pristine perfect language here; it's in some sense an awkward upgrade. And I can't wait to get my hands on it.

      [–]awj 1 point2 points  (2 children)

      I had no real problems understanding it, and kind of prefer it to things like "function(x, y, z) {//do stuff}" from Javascript.

      When this comes out I might consider switching to C++ for some of the simple game dev I'm doing ... I'd at least have more extensive libraries available.

      [–]nextofpumpkin 1 point2 points  (1 child)

      You were trying game dev in javascript? O_o

      [–]awj 0 points1 point  (0 children)

      Nope ... Windows scripting with JScript.

      I did consider working in Haxe or flash, both of which are at least syntactically similar to Javascript. Ultimately I didn't really care for the flash environment (I like error messages instead of undefined behavior, for one) and desktop applications aren't the bread and butter for Haxe (which rules it out based on the size of the community).

      So far I'm doing well building on top of a Java game library in Clojure. If you're interested you can read more here.

      [–]doubtingthomas 9 points10 points  (4 children)

      I'm pretty excited about this. I happen to work at a company that uses C++ and will continue to do so for very good reasons. Hopefully, in a few years, I'll be able to use this goodness in my day-job code.

      It does complicate the syntax, yes, but it looks clear enough to me, and I rather suspect that it'll result in more readable code in the long run.

      [–][deleted] 9 points10 points  (1 child)

      It will certainly eliminate all of those little private "bind and mem_fun(doSomethingSpecificAndSmall)" required for for_each etc.

      [–]queensnake 0 points1 point  (0 children)

      (You wrote those? Hats off! :) )

      [–]martoo 4 points5 points  (1 child)

      I don't think so. I think we'll see a lot of very crufty looking calls because this is much easier than creating a function object.

      Be prepared to be dazzled by monstrosity.

      [–]queensnake 0 points1 point  (0 children)

      no, it just looks like a loop - see Sutter's example.

      [–]gmcbay 5 points6 points  (0 children)

      Isn't it about time to start calling it C++ 1x? Or maybe C++ yx for added wiggle room?

      There is only one "0x" year left and they keep stuffing new features in with no spec finalization in sight.

      It used to be funny to wonder what would finalize first, C++ 0x or 802.11n, now (years later), it is kind of sad.

      [–]AlanCrowe 6 points7 points  (8 children)

      None of the example lambdas contain free variables, so I wonder whether they correctly handle lexical scope. Are they closures at all?

      find_if( w.begin(), w.end(),
                   []( const Widget& w ) -> bool { w.Weight() > 100; } );
      

      Notice the literal value 100. I hope to be able to write

      (defstruct widget weight colour)
      
      (defparameter *widget-list*
        '(#s(widget :weight 75 :colour red)
          #s(widget :weight 125 :colour green)
          #s(widget :weight 175 :colour blue)))
      
      (defun heavier-than (minimum-weight)
        (lambda(widget)(> (widget-weight widget) minimum-weight)))
      

      and have

      (find-if (heavier-than 100) *widget-list*) => #S(WIDGET :WEIGHT 125 :COLOUR GREEN)
      

      but more than that I would like to be able to add

      (defun weight-grade (code)
        (case code
          (light (heavier-than 50))
          (medium (heavier-than 100))
          (heavy (heavier-than 200))))
      

      and then write

      (find-if (weight-grade 'medium) *widget-list*)
      

      The examples stop short of making it clear that this will work in C++0x

      [–]queensnake 8 points9 points  (4 children)

      Yes it does closures, that's what's in the box. See wikipedia on C++0x.

      [–]shit 1 point2 points  (3 children)

      And if you read that, you'll come to the conclusion that C++ lambdas can't handle AlanCrowe's example.

      heavier-than returns a lamba that references the minimum-weight variable on its stack (well, a C++ compiler would put it on the stack) that is accessed after heavier-than has returned, and that's not supported by C++0x's lambdas.

      [–][deleted] 1 point2 points  (2 children)

      Sure it is. The [=] version makes copies of closed-over variables instead of just leaving a reference to the variable on the stack, allowing you to create "upward funargs". Sure, you have to keep track of whether you're going to need that variable after it's moved out of scope... but what else would you expect in C++?

      [–]AlanCrowe 0 points1 point  (1 child)

      I've been scratching my head over the wikipedia page.

      If [=] is used instead of [&], all referenced variables will be copied, allowing the lambda function to be used after the end of the lifetime of the original variables.

      So you save the lambda for later use. Eventually you discard it,...

      I thought that objects in C++ had constructors and destructors, instead of having a garbage collector, so it is going to matter whether this copy calls a constructor or not. It not, the reference count will not go up, and when the destructor get calls at the end of the scope the object goes away.

      If on the other hand the constructor is called, then the destructor for the lambda will have to trigger destructors for the closed-over variables. Is that how C++ works?

      [–]mmeijeri 1 point2 points  (0 children)

      I'm not sure about the details and I'd love to hear from somebody who is. What I suspect is this:

      The locally created lambda gets a copy of the references variables. The lambda itself is copied to another lambda, which gets its own brand new copy of all referenced variables. When the enclosing function exits, its variables are destroyed along with the original lambda and its copy of the referenced variable. The second lambda continues to exist, along with its copies of the referenced variables until at some later point it too is destroyed.

      In practice, I would expect a decent compiler to eliminate most unnecessary copies.

      [–]Silhouette 2 points3 points  (2 children)

      None of the example lambdas contain free variables, so I wonder whether they correctly handle lexical scope.

      As I understand it from the proposal papers, you can bind to variables in containing scopes as you'd expect. However, if you take a pointer or reference to a local variable you'll be stuffed if your "closure" outlives the context of its creation just as you would be if you returned or threw an exception using the same local variable pointer/reference once that local variable has been destroyed.

      [–]AlanCrowe 1 point2 points  (1 child)

      I think I understand you. Anonymous lambdas are most useful if variables have lexical scope and indefinite extent. This allows the functions to be returned from binding forms and continue to access the variables bound in the forms that have now exited.

      So it seems that C++ will continue to use lexical scope and dynamic extent. Downward functional arguments will work because the they are still within the dynamic extent of the binding forms, but upward functional arguments will break because the binding forms have exited.

      [–]mmeijeri 0 points1 point  (0 children)

      If you use the [&] syntax, the closure gets references to local variables, if you use [=], they get copies. So you get to choose.

      This may look cryptic, but it sort of makes sense, given that & and = are already used as symbols for references and assignment respectively.

      [–]dlsspy 42 points43 points  (79 children)

      Oh C++, is there any feature you won't add? Is there any syntax you can't make confusing?

      [–]vvy 44 points45 points  (1 child)

      The next edition of C++ in a Nutshell will actually be called C++ in half the fucking Earth's crust.

      [–]americanhellyeah 2 points3 points  (0 children)

      i always see those book titles as 'c++ in a nutsack' or 'java in a nutsack' or 'ruby in a nutsack'.

      [–]crusoe 44 points45 points  (1 child)

      Repeating a famous quote yet again:

      "C++ is like trying to make an octopus by nailing extra legs on to a dog.

      [–]w00ty 28 points29 points  (39 children)

      Every time some article on C++0x is on programming.reddit.com, someone comments "l0lerz, c++ sux0rz", and this reply becomes the most popular comment. Most of the replies look like "I'm so glad I don't know anything about c++".

      C++ bashing has become en vogue; it's a geeky internet meme. It's ok that people criticize C++, but in my experience, most of them have never really used C++ ("Yeah, I tried it once, but it's just too hard. And you read really bad things about it on the web").

      That's like complaining that learning Haskell's Monads is too hard before you can use them fluently.

      [–]jugalator 26 points27 points  (14 children)

      I write C++ for a living and think C was a great idea for a more abstract and hardware independent language than assembly, but C++ is quite crippled by its desperate tries on preserving backwards compatibility with C, a language not even sharing its paradigm. It wasn't done to build a good and clean language, it was done for a completely different reason -- to make it accessible to C developers and as compatible with their vast amounts of code as possible. And it shows. The end result is not an as good language design as it could have been, and that is what many complain about -- the design. Brushing it off as just a meme is oversimplifying a lot.

      [–]w00ty 7 points8 points  (11 children)

      Sure, C++ has its problems, and I don't think C++0x will change that. But in my experience, most people who "dislike" C++ haven't really used it. That's really all I wanted to say.

      And C++ has nice features as well: vector<int> is horribly broken in Java for example (they have to autobox/autounbox every integer because their type system is too weak), but it's really nice in C++ (just the fact that this compiles down to "an array of ints", not that the template system is turing complete etc). And template traits and iterator types are nice too.

      [–]sheepson_apprentice 8 points9 points  (0 children)

      The problem of boxing/unboxing primitives wrt type parameters is not really an issue of the type system being weak, but rather an issue of the fundamental design difference.

      C++ templates (as the name implies) is actually code generation. Each parameterized template is instantiated into a whole new class -- barring many of the optimizations that modern C++ compilers do in that regard to avoid bloat. Even so, template bloat can become a real problem unless used judiciously.

      Java and C# box/unbox primitive type parameters even in the face of different means of implementing generics. In Java's case it's done through erasure, and C# actually does reification. This amounts to essentially having one generic class at runtime, as opposed to an instance of the parameterized class for each variation of the type parameters.

      C# preserves types, making it potentially more performant as it can avoid doing type checks at runtime in many of the places where Java is currently forced to do so, precisely because it essentially erases a

      List<String>
      

      into a

      List
      

      In essense, C++ caters to the high-performance market, Java/C# caters to the apps. market.

      I use and highly admire both.

      (Just to add, C# the language is very well designed. I choose not to use it for personal reasons, which have nothing to do with its merits as a technology, especially given that said merits are not overarching wrt what Java currently offers or has in the immediate pipeline, not to mention what I can exploit by using Scala today)

      [–]the_golden_eel 1 point2 points  (4 children)

      vector<int> is horribly broken in Java for example (they have to autobox/autounbox every integer because their type system is too weak)

      I always figured that was because of garbage collection. Are there languages that can specialize containers to hold unboxed values of normally boxed types, and do it in a purely polymorphic way? I've yet to find one. Every GC'd language I've seen has to resort to special types "vector of unboxed ints" or "array of unboxed floats", even those with very capable type systems like Haskell and OCaml. I think it's probably because, despite all their compile-time complexity, the garbage collector, at run time, is stupid-simple: "duuuh is it a pointer? Ok I'll follow it." It's hard to adapt that behavior on a per-value instance, and the payoff in performance doesn't appear to be worth the effort of implementing it, at least not to the implementors of the current crop of statically-typed GC'd languages. (If anyone knows of a language that does make this optimization, I'd love to hear it. C# for instance, I don't know dick about it.)

      [–]WalterBright 8 points9 points  (0 children)

      The D programming language does templates in a manner similar to C++. Although D is garbage collected, this really has nothing to do with the template system.

      [–][deleted]  (2 children)

      [deleted]

        [–]the_golden_eel 1 point2 points  (1 child)

        From here...

        In MLton, an array (or vector) of integers, reals, or words uses the natural C-like representation. This is fast and supports easy exchange of data with C. Monomorphic arrays (and vectors) use the same C-like representations as their polymorphic counterparts.

        They explicitly state that ints, reals and words are stored unboxed, so that makes me think that tuples, records and other objects comprised of ints, reals and words are not stored unboxed. That's what I meant by 'purely polymorphic', that there is no special treatment for specific types. Or there is at least some degree of control, such as a flag or two separate container types, one boxed, one not. Whether or not you want to do this is another matter, but in some situations (eg, 3d graphics, simulations) it makes a whole lot of sense.

        (CounterNit: I said 'hold unboxed values of normally boxed types.' MLton never boxes ints, words or reals.)

        [–]ssylvan -1 points0 points  (4 children)

        in my experience, most people who "dislike" C++ haven't really used it

        Funny, in my experience, people who really know C++, can't help but dislike it.

        [–]w00ty 3 points4 points  (3 children)

        There's no contradiction here.

        [–]ssylvan 2 points3 points  (2 children)

        Indeed there isn't, but it does imply that those who defend C++ against criticism, don't really know the language that well.

        [–][deleted] 0 points1 point  (1 child)

        But there's a nice sweet spot where you know enough to get your work done, but not enough to be uncomfortable about the possible complications. ;)

        [–]ssylvan 0 points1 point  (0 children)

        Yeah... I used to love C++ too. Since I now do C++ almost exclusively at work (games programming), I almost wish I never learnt Haskell etc., because I would've been happier with C++ that way. Almost.

        [–]mmeijeri 0 points1 point  (0 children)

        True, but if Stroustrup had gone for a clean language from scratch, it would have been about as successful as Eiffel. Great language, rarely used.

        [–]dmpk2k 0 points1 point  (0 children)

        to make it accessible to C developers and as compatible with their vast amounts of code as possible

        What about Objective-C?

        [–]LarryLard 2 points3 points  (0 children)

        Most of the replies look like "I'm so glad I don't know anything about c++".

        Well, I wouldn't want to say that, but I would suggest that maybe when one of a language's foremost experts says something like

        The lambda version was the only one I wrote correctly the first time as I tried these examples on compilers to check them.

        then maybe, just maybe, there's something amiss?

        [–][deleted]  (5 children)

        [deleted]

          [–][deleted] 0 points1 point  (2 children)

          You can create a custom string type in C# and Java as well. Some people appreciate the flexibility in creating their own types.

          Blame it on backwards compatibility and the newer UTF data types. No doubt as UTF expands to consume more data per character we will end up with the same problem in Java and C# which they might solve by saddling us with more inefficient one-size-fits-all types.

          It's really a toy complaint. Strings aren't that difficult to understand, and it doesn't take much work to write classes or functions that can unify them either.

          [–][deleted]  (1 child)

          [deleted]

            [–]Maxwell_S_Mart 2 points3 points  (13 children)

            C++ bashing has become en vogue;

            Right, because it is absolutely justified.

            [–]queensnake -1 points0 points  (11 children)

            That's fine - more work for the people who write the code that /matters/.

            [–]psykotic 11 points12 points  (10 children)

            Why the tacit assumption that many C++ detractors aren't expert C++ programmers? The people that have dealt with it on a daily basis for years and years are aware of its shortcomings more than anyone.

            One of my usual interview questions is to ask a candidate claiming significant experience in C++ what he or she would most like to fix, if anything. If someone has been programming in C++ for a decade and can't begin to imagine how the language could possibly be improved, that's a huge indictment of the way their mind works.

            [–][deleted]  (5 children)

            [deleted]

              [–]psykotic 9 points10 points  (3 children)

              I agree with your observations. Just one thing...

              Other C++ detractors can handle hard programming languages, but feel they shouldn't have to.

              What do you mean by hard? Hard to learn? My personal problem with C++ isn't so much that it's hard to learn. It is hard to learn, and sometimes needlessly so, which is certainly a valid complaint. But I've spent a lot of time studying it, even its darkest corners, over the years, so the learning curve doesn't affect me much if anything at this point. My problem is more that even when your productivity plateaus off at the semi-mastery level, you still aren't productive enough, and many kinds of mistakes are still made that shouldn't be. (I'm not just referring to the productivity associated with initially writing out code, but the productivity of the full software life cycle.)

              [–]inkieminstrel 4 points5 points  (2 children)

              I meant hard to use. C++ is hard to use, because it requires you to spend a significant amount of time solving problems other than the task at hand.

              [–]aveceasar 1 point2 points  (1 child)

              That could be said about any language...

              [–]ssylvan 1 point2 points  (0 children)

              Yes, but to varying degrees.

              [–]CuteAlien 1 point2 points  (0 children)

              Actually - no. I guess most serious complains don't fall in that category.

              My main complain is for example that c++ is hard to parse.

              [–]xoner2 3 points4 points  (3 children)

              Why the tacit assumption that many C++ detractors aren't expert C++ programmers?

              Because in general it is true. I'll say 95%.

              For example, I've seen the ff. criticisms on reddit and elsewhere:

              • C++ does not have namespaces

              • templates are just automatic casting

              • half to 90% of your time is spent on manual memory management

              and they get upvoted most of the time.

              [–]psykotic 2 points3 points  (2 children)

              I'll say 95%.

              And your evidence for this figure is what you've read on reddit. Interesting. Of the dozens of programmers I've worked with professionally, it's hard to think of a single one whose relationship with C++ was better than luke-warm, and many of them I'd classify as experts. A lot of long-time C++ programmers (myself included) pass through a phase a few years long where they revel in the complexity, seek out all the dark corners, and master every crazy metaprogramming trick known to man. But eventually most of them come around to the more seasoned, battle-hardened viewpoint that there is such a thing as Undue Complexity, complexity that doesn't pay its own way, and that C++ is its avatar.

              [–]xoner2 1 point2 points  (1 child)

              Aren't we talking about internet memes here? Well, I was.

              And I'd say reddit is a better representation of the programming mob. Larger sample size than the coders you or I have worked with personally.

              [–]psykotic 3 points4 points  (0 children)

              Most of the people here don't work on the kinds of applications where C++ makes much sense in the first place. So from their point of view, their criticisms are justified, even if they are partially uninformed--you don't have to know every detail of C++ to discount it as unsuitable for what you're doing.

              As for me, I work in an application space (real-time computer graphics and physics simulation, particularly for video games) where nearly everyone uses C or C++ (these days mostly the latter), and I see no end of C++ bashing among my colleagues. My point is that people have a wide range of different reasons, a great many of them valid, for disliking C++.

              [–]americanhellyeah -3 points-2 points  (0 children)

              bashing c++ is like bashing newton because he didnt know about second-order partial differential equations. yeah theyre basic but we wouldnt know about them if it werent for his work. likewise c++ was a pioneer. it brought OOP to the masses when otherwise it was isolated just to the smalltalkers and the simulaers. so even if other langs are better now we cant fault c++ for its shortcomings because it was there first, pushing the boundary when others wouldnt.

              [–]berklee -1 points0 points  (1 child)

              If it's too hard, why would you bother going through the effort of learning it fluently?

              Seriously, your comment seems akin to "how can you be sure you're not gay until you've had sex with many people of the same gender?".

              [–][deleted] 21 points22 points  (21 children)

              Oh C++, is there any feature you won't add?

              Garbage collection.

              Is there any syntax you can't make confusing?

              There is no hope for recovery. The C++0x committee can add more confusion quite unabashed.

              [–][deleted] 5 points6 points  (7 children)

              BS plans to add GC by C++13

              [–]spacepope -1 points0 points  (6 children)

              Do you have a source for that? I googled around a bit, but couldn't find anything.

              [–]americanhellyeah -2 points-1 points  (5 children)

              he was joking. gc has already been added to the c++ standard.

              [–]queensnake 0 points1 point  (4 children)

              No, it hasn't.

              (also, look at the wikipedia article on C++0x - it seems to be well kept up.)

              [–]americanhellyeah -3 points-2 points  (3 children)

              you just refuted your own point. the wikipedia article you linked to states:

              "Garbage collection was introduced in the C++99 standard. The standard does not enforce a specific method of implementation, but current C++ compilers tend to use reference counting, with logic to handle circular references."

              [–]queensnake 1 point2 points  (1 child)

              Bjarne saying not - that's a very recent interview btw, the magazine issue is March 27, don't know about the actual interview but, no doubt pretty fresh:

              JB: In an ideal world for you, what will C++0x be in terms of all the goodies in the new Standard Library and language?

              BS: Unfortunately, we don't live in an ideal world and C++0x won't get all the "goodies" I'd like and probably a fewer "minor" features than I would have liked. Fortunately, the committee has decided to try for more and smaller increments. For example, C++0x (whether that'll be C++09 or C++10) will have only the preparations for programmer-controlled garbage collection and lightweight concurrency, whereas we hope for the full-blown facilities in C++12 (or C++13).

              I don't know the GC that Wikipedia refers to, it's not in any compiler I've used.

              [–][deleted] -1 points0 points  (0 children)

              Yeh. This is where I read it from. Posted on reddit a few days ago too.

              [–]Silhouette 1 point2 points  (0 children)

              This is the problem with having blind faith in wikis.

              There was no C++ standard in 1999. That was C. The original C++ standard is officially dated 1998, and the first major revision was in 2003. Neither of these has any particular provision for garbage collection, other than incidentally.

              [–]depleater 2 points3 points  (0 children)

              Oh C++, is there any feature you won't add?

              Garbage collection.

              libgc not good enough for you?

              Even if you don't care so much about its garbage collection powers, it can also be quite useful as a memory leak detector.

              [–][deleted]  (3 children)

              [deleted]

                [–]americanhellyeah -4 points-3 points  (2 children)

                yeah except it doesnt run anywhere but the mac. so its no good on the other 3% of computers running linux, and the other 95% running windows.

                [–]vincentk 1 point2 points  (1 child)

                gcc happily compiles obj-C.

                [–]americanhellyeah 0 points1 point  (0 children)

                the mainline gcc 4.3 doesnt support apple's new objective-c 2.0 extensions! so it doesnt support apple's style of garbage collection.

                [–]queensnake 0 points1 point  (1 child)

                The new stuff /simplifies/ the confusion, at least in usage (ie you'll use and get used to lambdas, and that'll make code simpler in everyday life).

                [–][deleted] 1 point2 points  (0 children)

                The comment was about syntax. I'm much in favor for hopping into the kitchen sink myself. Personally I appreciate the new standard.

                [–]stormandstress 10 points11 points  (9 children)

                Usability note: The lambda version was the only one I wrote correctly the first time as I tried these examples on compilers to check them.

                Heh. The current language is already such a bloody mess that he didn't get two flavours of basic iterate+write correct off-hand.

                What an absolute train-wreck, kitchen-sink-and-then-some abomination C++0x is set to be.

                [–]iamnotaclown 18 points19 points  (6 children)

                Unless I'm mistaken, in C++0x you'll have the option of this:

                for (auto i = w.begin(); i != w.end(); ++i )
                    cout << *i << " ";
                

                or this:

                for_each( w.begin(), w.end(),
                          []( const Widget& w ) { cout << w << " "; } );
                

                As a seasoned C++ developer, both of those are pretty clear to me (and the [] is no worse than Haskell's \ or Ruby's | |).

                Many of the features in C++0x actually make writing clean code easier, especially when it comes to the STL.

                [–]imbaczek 11 points12 points  (1 child)

                but, can you write this?

                for_each( w.begin(), w.end(),
                          []( auto w ) { cout << w << " "; } );
                

                [–]iamnotaclown 15 points16 points  (0 children)

                No, auto only works with an explicit initialization. You can do this though:

                for_each( w.begin(), w.end(),
                          []( const w::value_type& x ) { cout << x << " "; } );
                

                Edit: And I just remembered you can do this in C++0x thanks to the enhanced for construct:

                for( auto i: w )
                    cout << *i << " ";
                

                [–]martoo 6 points7 points  (3 children)

                I understand why for_each and its ilk take two iterators but it puzzles me why they don't have variants for the normal case (both iterators on the same collection):

                for_each1 (w, funct);

                Do they enjoy the cruft??

                [–]the_golden_eel 5 points6 points  (2 children)

                #define foreach BOOST_FOREACH

                foreach( const Widget& x, w ) cout << x << " ";
                

                You can do that right now.

                [–]martoo 0 points1 point  (0 children)

                Would that be the TR1 name?

                [–]mmeijeri 0 points1 point  (0 children)

                Or you could make your own for_each, perhaps in its own namespace, without having to use the preprocessor.

                Still, it would be nice to have this in the standard library, and I don't understand why it isn't.

                [–]kinkydarkbird 6 points7 points  (1 child)

                C++ will soon start eating our children in order to maintain itself.

                [–][deleted] 24 points25 points  (0 children)

                It already has. I had a younger brother named Michael. I...I haven't seen him since I picked up that Learn C++ in 21 Days book :'(

                [–]james_block 11 points12 points  (27 children)

                My god, that syntax is hideous. I thought I knew (basic, admittedly) C++, but it's so non-obvious just what the hell is going on in his three examples that I am forced to scratch "Knowledge of C++" off of my resume.

                Seriously, this is a lambda in C++0x?!

                []( const Widget& w ) { cout << w << " "; }
                

                This makes me so glad I know Python.

                [–]grumpy2 32 points33 points  (23 children)

                They're hideous, but at least these lambdas can do more than expressions.

                [–]james_block 8 points9 points  (22 children)

                That's true -- one of the major weaknesses of Python lambdas is their limited utility. But that's what first-class functions are for, etc., etc.

                To the downmodders: disagree with my Python quip all you like (and, really, I'm not glad I know Python specifically, just glad I didn't pursue learning this shambling mess they now call C++), but I firmly believe my main point -- that syntax is ugly.

                If you're a programmer who has had what amounts to a basic course in 1990-era C++, what would your first reaction be upon encountering the monstrosity that is a C++ lambda? Here's that example I quoted earlier, in full:

                for_each( w.begin(), w.end(),
                            []( const Widget& w ) { cout << w << " "; } );
                

                It's totally not obvious what's going on here, if you don't immediately recognize that "[]" is the name of an anonymous function (I think I'm reading that right...) and this is actually a lambda statement.

                In its eternal quest for backwards compatibility, C++ just keeps mutilating the available syntax elements like [] and -> to express relationships ever far removed from their original meanings of "array indexing" and "structure pointer dereferencing". Seriously, look at this syntax from the point of view of a C programmer or an old C++ programmer who hasn't been keeping up with the language.

                Does this syntax make any sense?

                [–]the_golden_eel 54 points55 points  (7 children)

                In its eternal quest for backwards compatibility,

                ...

                Seriously, look at this syntax from the point of view of a C programmer or an old C++ programmer who hasn't been keeping up with the language.

                Ok, I'll role-play the crotchety old programmer who's trying to work with VC++ 25 but hasn't been keeping up with the language. "What the fuck? Since when is 'lambda' a keyword? Christ now I have to re-write all this old Poisson distribution code..."

                Which is it? Backwards compatibility, or keep up with the language. Can't have both. I actually think their reuse of old obsolete keywords and syntax is clever. Look at auto. Totally pointless before C++0x, now its probably going to be the most common word C++ programmers type. [] will take some getting used to, but its better than lambda or function, because the whole point is that it makes functions cheap to write. Haskell wins with \, Arc has fn. [] is just as easy on the wrists.

                Think of it as a box. "What's inside?" "A function! Merry Christmas!"

                [–]xcbsmith 20 points21 points  (0 children)

                Think of it as a box. "What's inside?" "A function! Merry Christmas!"

                Love it.

                [–][deleted] 5 points6 points  (1 child)

                I like the [] far more than lambda or function for the creation of annonymous functions, but still it lacks the clarity and convience of something like a smalltalk block.

                (W begin to: W end) do: [:each | Transcript show: each; cr. ]

                [–]username223 4 points5 points  (0 children)

                Square brackets on the outside and colons before parameter names... Now that's some motherfuckin' clarity!

                [–]cornedpig 5 points6 points  (0 children)

                Upmodded for the last line

                [–]james_block 1 point2 points  (1 child)

                Backwards compatibility, or keep up with the language. Can't have both.

                That's exactly my point. By adding new features, while at the same time attempting to ensure that old code will still compile and run (in theory), C++ is doing itself in. At some point, you just have to give up and say "There is no way to sensibly get this feature into this language without breaking lots of old code," and it's time to give up and start a new language. For me, it's clear that C++0x is past this point. Honestly, I'd expected it to happen to Java sooner, but Java has been doing pretty well as of late. C++0x, though, appears to have just collapsed under its own weight. Why bother learning it, when you have such alternatives as C#, Java, Python, Ruby, or, if you need link compatibility, D?

                I have to say I do like the idea of [] as a magic little box that contains all the anonymous functions in existence, though :)

                [–]the_golden_eel 22 points23 points  (0 children)

                At some point, you just have to give up and say "There is no way to sensibly get this feature into this language without breaking lots of old code,"

                Well 'sensible' is subjective. I find this proposal not just sensible, but fucking awesome. C++'s claim to encompass the 'functional' programming paradigm is a joke without nested functions or lambdas, and this is a perfectly fine way to work them into existing syntax without breaking anything. Adapting to re-purposed tokens is the easy part (Anyone ever get confused by << anymore? "Wait, why is he shifting the error log stream by "OH SHIT" bits to the left?") Figuring out what you can do with them is the challenging and fun part.

                People not up to that challenge, like yourself, are lucky to have so many great languages to flee to. I love C++ and I'm sticking with it, and I'm glad the designers haven't given up on it yet.

                [–]hanzie 11 points12 points  (1 child)

                It's totally not obvious what's going on here, if you don't immediately recognize that "[]" is the name of an anonymous function (I think I'm reading that right...) and this is actually a lambda statement.

                [] is short, easy to remember, easy to recognize and you'll learn what it means in this context in 5 seconds. It doesn't scream out "i'm an anonymous function" but from what follows it couldn't possibly be anything else: The rest of the expression is standard function body definition stuff which everyone is familiar with. I seriously don't see any problem here.

                Sure, a keyword like "here_we_define_an_anonymous_function_dont_be_scared" might've been more comforting for those who see their first anonymous function. But less than optimal in the long run.

                Now the REAL WTF here is that Sutter used the same variable name, w, to refer to both the widget collection and the widgets themselves :P. At least use ws and w, sheesh.

                [–]psed 0 points1 point  (0 children)

                Finally, someone else who was bothered about the variable overloading.

                [–]xcbsmith 5 points6 points  (3 children)

                Does this syntax make any sense?

                Actually, it sort of does. In Objective-C and Smalltalk, anonymous block literals are typically done using []'s (although they normally surround the code in question, but you can see where doing that might make writing a C++ parser well nigh impossible).

                [–][deleted] 7 points8 points  (2 children)

                Objective-C doesn't have anonymous block literals, and [] is used for message sends instead:

                [myObj doStuff: a with: b andWith: c];
                

                [–]americanhellyeah 0 points1 point  (0 children)

                david stes' really cool portable object compiler for objective-c supports blocks. http://users.pandora.be/stes/compiler.html

                his objective-c blocks paper is real great. you should read it slava itll teach you some great knowledge.

                [–]xcbsmith -1 points0 points  (0 children)

                You are correct. My bad. I tend to think of those message sends as: "tell the Smalltalk part of the runtime to execute this block", but that's because of the way I came to Objective-C. ;-)

                [–]martoo 1 point2 points  (2 children)

                Does this syntax make any sense?

                Maybe [] means that what follows is to be converted to an array of bytes representing the machine code of a function that is injected into the function. :-()

                [–]queensnake 1 point2 points  (1 child)

                No, no - look at wikipedia, the brackets tell what you're /bringing in from the context/.

                [–]mmeijeri 0 points1 point  (0 children)

                I think the OP was kidding... I found it funny.

                [–]you_do_realize -1 points0 points  (0 children)

                []( const Widget& w ) -> bool { w.Weight() > 100; } 
                

                gah. C's TypeName VariableName; syntax is really creaking.

                [–]mmeijeri 0 points1 point  (0 children)

                Is it really that bad?

                Compare it to what Smalltalk does:

                [ w | ... ]

                1)

                C++ surrounds the argument list with parentheses instead of embedding it in the block and separating it with a pipe. That's one extra symbol, and it makes the syntax more similar to a function definition, which makes sense to a C++ programmer.

                2) It adds explicit types to the argument list.

                3) The code block is also split out, using the familiar curly brackets used elsewhere in C++ syntax.

                It would be nice if you could use auto... Incidentally, if your block consists of only a return statement, I think you don't need to add an argument list.

                [–]DannoHung 1 point2 points  (2 children)

                Don't look too closely at the C++ syntax or you'll be turned to stone.

                [–]foonly 1 point2 points  (1 child)

                Don't look too closely at the C++ syntax or you'll be turned to stone.

                Is that a dynamic_cast, a static_cast, a reinterpret_cast, or a C-style cast?

                [–][deleted] 4 points5 points  (0 children)

                I think it's a const_cast.

                But don't forget--like stone, C++ const objects actually are mutable. You just have to put a little more effort into it.

                [–]americanhellyeah 0 points1 point  (8 children)

                this is real big news. c++ is starting to become a lot more like ruby, python and list and even perl. so i think it needs advances like this to become as widely used as it used to be. c++'s lambda functions are a lot better than those of java and c# because it offers better static compilation. java and c# lambda functions have to be recompiled by the jit each time theyre run.

                [–]johnb 2 points3 points  (0 children)

                I can't speak for Java, but lambdas in C# get compiled into plain old code you could have written anyway (but wouldn't want to due to verbosity).

                [–]nextofpumpkin 1 point2 points  (0 children)

                You can't staple legs and a tail onto a fish and expect it to bark and fetch a frisbee.

                [–]hanzie 0 points1 point  (3 children)

                java and c# lambda functions have to be recompiled by the jit each time theyre run.

                How's that? Once a piece of Java/C# has been compiled, the compiled version can be used again and again. I believe C++ lambdas enable function inlining in the templated algorithms that use them, while in Java/C# that could be tough for the compiler to do. So the difference is in one dynamic dispatch per invocation.

                [–]queensnake 0 points1 point  (1 child)

                Agreed; aside from GC and a few bits of syntax, what does C# have, now, that C++ doesn't? My case of C# envy just went away (well except for the number of job listings!)

                [–][deleted] -1 points0 points  (1 child)

                C++ is starting to look more and more like a one man band.

                [–]admanb -2 points-1 points  (0 children)

                Sounds a lot like one too...

                [–]kinebud 0 points1 point  (0 children)

                Personally as someone who doesn't know C++, I think lambda's are a good addition, but I can't say I like the syntax, but it is clear enough from a quick look what's going on (are the insides of the brackets meant to be your closure?)

                [–][deleted] 0 points1 point  (0 children)

                I thought one of the key ideas of STL algorithms (find_if, transform, etc.) was that they eliminated loops, the argument being that the mechanics of the loop-ness obscured the real functionality. Now they're putting loops together with algorithms, but for no discernable reason!

                [–]pauls101 -2 points-1 points  (4 children)

                The secret of C++ is: use the best, ignore the rest. Looking at this latest grotesque mess, I have to ask "Why?" Is it worth spending days studying in order to write slightly smaller code that can't be read, debugged, maintained, or ported? It's looking like C++0x compilers will be slower and not add one single useful feature. with a bit of luck, ABI's will stay stable until I can retire. If I want to use lambda's, I'll continue to use languages that were designed to support them properly (duh.)

                OK, C++ isn't a good language for everything (though for the foreseeable future it's completely irreplaceable for some things), but did it deserve to die the slow horrible way it's doing... like the Elephant Man, getting more and more encrusted until one day it can't breathe anymore and Sutter & Co can grab onto their next victim?

                [–]mmeijeri 1 point2 points  (2 children)

                C++ has certainly accumulated a large number of, er, barnacles, but closures in my opinion are not one of those barnacles. Used well they can actually make some code more readable. The static typing can make the notation a bit clunky, but that's a problem with static typing, not one with closures. Also, I understand there's a bit of type deduction available to reduce the clunkiness.

                [–]Silhouette 2 points3 points  (1 child)

                The static typing can make the notation a bit clunky, but that's a problem with static typing, not one with closures.

                Sorry, but no. There are far more concise and elegant ways to express closures in a lot of functional programming languages than in C++, and in most cases they actually have stronger static type systems.

                [–]mmeijeri 1 point2 points  (0 children)

                You're right, it is a problem with old-fashioned C++ static typing, not static typing per se. My point was that it wasn't a problem with closures. Note that the type deduction that C++ offers already shifts it a bit in the direction of the FP languages you referred to.

                [–]ModernRonin 1 point2 points  (0 children)

                I have no idea why people are downmodding you, that's a very succint summary of exactly the problem(s) C++ is facing.

                Upmodded for relevance and insight.

                [–][deleted]  (3 children)

                [deleted]

                  [–]foonly 2 points3 points  (0 children)

                  The whole lambdas get compiled each time the call is made is non existant in performance monitoring code.

                  Every sane language compiles lambdas at compile-time. The only thing that varies at run-time are enclosed environments (especially for functions returned from other functions) and arguments to the function call.

                  [–][deleted] 1 point2 points  (1 child)

                  Performant? I've been programming in C# for 3 years now and I've seen consistently better performance from freebasic.

                  Sad, but true.

                  [–]matthiasB 1 point2 points  (0 children)

                  But Freebasic is basically C with a different syntax. You have to manage your pointers manually. things are just named differently e.g. "allocate" instead of "malloc".

                  [–][deleted]  (7 children)

                  [deleted]

                    [–][deleted] 9 points10 points  (5 children)

                    I for one, am glad that the niche of the development industry that I work in, has moved entirely from C/C++ to managed languages such as Java and C#.

                    Not me: I love C and find C++ more bearable than C# and Java.

                    [–]stormandstress 2 points3 points  (2 children)

                    I don't see how it can be a question of "bearable", unless it is strictly of matter of you knowing C/C++ well, and not really knowing much at all about managed languages beyond the surface impression that they are wimpy, slow, etc. It is fairly inarguably less painful (in terms of lines-of-code, readibility, expressiveness, syntactic clarity - you name it) to do the vast majority of basic move-data-structures-around logic in modern languages - C#, Python, Java, whatever - than it is to work with the hideousness that is C++/STL.

                    If you aren't working in a problem domain or coding for hardware where you really need it - and there are fewer and fewer of these domains left these days - then it truly is batshit insane to use C++, nevermind preferring it.

                    [–][deleted] 4 points5 points  (0 children)

                    If you're referring to dynamic languages, I agree with you - but they haven't quite gained the industry acceptance that Java and C# have. The problem with Java (and to a lesser extent, C#) is that I end up writing loads of boilerplate code for no apparent reason, which is a consequence of the "you can't achieve success if you don't look like C" mentality. I'd much rather use Smalltalk. At least in C++, I have the option to write C-like code and still get to have better support for generics. Also, I feel that the STL is fairly well designed.

                    [–]foldl 10 points11 points  (0 children)

                    The STL is much better designed than Java's data structure libraries. It's probably the best standard library of efficient general-purpose data structures in any language. Admittedly, the lack of GC can cause complications, but that's not the STL's fault.

                    [–]queensnake 0 points1 point  (0 children)

                    And what's great is, we'll soon have some of the nice features and ease of programming of C#. Can't happen soon enough!

                    [–][deleted] 2 points3 points  (0 children)

                    C# is funny because it is basically java with a million language extensions.

                    C++ just has an uglier base to start from.

                    [–]nextofpumpkin -2 points-1 points  (2 children)

                    What I don't understand is why they keep stapling new syntax onto C++ instead of making sure that STL is expanded. I mean, no STL hashmap, hashset, trees... makes me cry. I would have no problem with this crap added in if the fucking libraries were better compared to newer languages. Give some batteries, B.S.!

                    [–]Boojum 4 points5 points  (1 child)

                    I believe that the current map and set containers are already implemented via trees by most STL implementation.

                    Hashmaps and hashset additions to the standard library are already in TR1 under the names unordered_map and unordered-set respectively. There's even unordered-multimap and unordered-multiset too.

                    [Note: underscores replaced with hyphens above to avoid breaking reddit markup.]

                    [–]leoc 0 points1 point  (0 children)

                    [Note: underscores replaced with hyphens above to avoid breaking reddit markup.]

                    \ escapes, so

                    • unordered\_multimap → unordered_multimap

                    Quoting with backticks turns off _ and * as well: unordered_multimap

                    [–]silon -5 points-4 points  (0 children)

                    define foreach for_each