15 ms·
Edward C++Hands
- fleitz 13y agoFucking backwards compatibility, let shitty code keep using shitty compilers while the rest of us move forward. There comes a time when no one uses a feature anymore so it might as well be dropped. How many of you still have floppies on your computer?
- simgidacav 13y agoThe fact is that there's a very huge amount of legacy code which provides irreplaceable functionality. What would you do if you had a complex data crunching library in C to be integrated into your program? Rewriting stuff from scratch is sometimes good, but usually you prefer to have some well-tested routines, and be sure they will not fuck up. Edit: you may also argue that projects like LLVM make it possible to compile stuff in IR, and still keep the old code... but there may be situations in which choosing a different compiler is not an option.
- CCs 13y agoBoth CLang and GCC have "C++11 compatibility" switch, so it's a matter of a compiler parameter if they accept or not the new standard. I would introduce a "backward compatibility" switch that has to be turned ON per source file to accept old constructs. All the new code from now own would be nice and shiny. There's an (easy) way to still keep around old code. Would that work?
- BruceIV 13y agoOnly if you like writing all your libraries yourself. To answer a little less flippantly, you'd need to add some sort of "unsafe" construct to the language, because most of the nice, high level abstractions have nasty low-level stuff buried in them, and because of the way C++ templates are compiled, that's all code that will be included in any program you write. In short, all "new" code is built on top of an awful lot of "old" code, and if you were going to make a huge breaking change like this, you may as well write a new language and libraries ground up (like Go or Rust).
- pcwalton 13y agoFurthermore, even if you restrict yourself to the new stuff, C++ is not memory-safe. C++ would need some sort of Rust/Cyclone-like lifetime/region semantics to become safe.
- CCs 13y agoIt's not that black and white. Scala has the same debate - there are a couple constructs only library writers use (normally). So they compile the library with "enable all". Everybody else gets a warning and they refactor the code or turn on the switch to allow.
- BruceIV 13y agoThe difference is that you can separately compile your Scala libraries from the code that calls them - if you do that in C++, you give up templates. All those #includes at the top of your C++ code are basically just dumping code into your source files, and if you're using templated code, it macro-expands with parts you're putting in from your own code. There are some separately compiled C++ libraries, but most of the standard library and Boost code you use is recompiled every time you compile your program. You could probably define a new pragma that would tell the compiler that all the code from a given file, class, or function is unsafe, but it would take source-level modifications to every library you use to properly implement the flag you suggest.
- CCs 13y agoYes, the point was "from now on", as a clean break from the past without giving up legacy code.
- BruceIV 13y agoAnd my point was that, due to the way C++ is designed (specifically, not having a proper module system and having this massively powerful macro-replacement templating engine), there is no way for the compiler to distinguish between "legacy" code and "new" code. Consider the following case study: you have a library including a template class that uses raw pointers as an iterator type. You accidentally write `iter + 9` instead of `*iter + 9` when you've included it (this will likely compile, though there should be a warning). Now, even assuming there's some language extension added to mark that library as "legacy" (maybe #include-legacy <mylibrary>), can you tell me whether the "new" code you just wrote using raw pointers counts as "legacy" or not? I think this is basically Bartosz' point as well - that C++'s legacy design features are too baked in to make positive changes easily, or even tractably (even small changes like your --no-legacy compiler flag).
- kzrdude 13y agoTaking a C library and compiling it as C++ will negate the well-tested bit, since a totally different compiler is now interpreting the code.
- gtani 13y agoYeah, amongst all the "MS has lost its way" chatter recently, I don't think anybody noted how it's treating C++ devs. Annual full releases of VS? Really? http://cpprocks.com/c11-compiler-support-shootout-visual-studio-gcc-clang-intel/ http://cpprocks.com/c11-compiler-support-shootout-visual-stu... http://www.reddit.com/r/cpp/comments/1h9uq7/c1114_stl_features_fixes_and_breaking_changes_in/ http://www.reddit.com/r/cpp/comments/1h9uq7/c1114_stl_featur...
- eliasmacpherson 13y agoThat STL link is the only thing that I learned anything from in this whole thread.
- gtani 13y agoI think the "use D or Go or rust" or "there is no alternatives" debate has run its course until people actually do big projects in rust. I do feel sorry (to the extent you can feel sorry for somebody who probably makes $150k+) for the guy in reddit who's started to talk about features he desperately wants in the C++17 spec.
- frozenport 13y agoI don't see any features that are completely unused. We had one called `auto` and its now gone. So what do you want to cut?
- hvs 13y agoEvery time I look to use C++ for something, I come away with the knowledge that I will never know the right way to do it in C++. At least with C I know where I stand.
- simgidacav 13y agoI think this is why, for instance, the Linux kernel is written in C and not in C++. And this leads to discussions on the Internet which are definitely funny! :D http://stackoverflow.com/questions/520068/why-is-the-linux-kernel-not-implemented-in-c http://stackoverflow.com/questions/520068/why-is-the-linux-k...
- sp332 13y agoThat URL looks even funnier!
- zvrba 13y ago> I will never know the right way to do it in C++ IME, looking for a "right way" of doing anything requiring some kind of knowledge or technique is a tell-tale sign of inexperience. Pursuing the search, analyzing possibilities, weighing their trade-offs in the light of envisioned use-cases makes you better and more experienced. Abandoning the search.. well, you'll certainly never get better. This extends also to things like designing a LAN, database tables and relations, even to martial arts and sports.
- zurn 13y agoWell put. It's like Perl but in self-denial - for each way to do it there's a bunch of people claiming it's the only right way to do it. And it changes every year.
- CCs 13y agoNot an easy read for C++ fans like me, especially since it is coming from Bartosz Milewski. I did try out several other languages and I keep coming back to C++11 for anything that requires scalability and raw performance, like APIs. The same basic server that gets 400 req/sec when implemented in C# ASP.NET achieves 7900 req/sec using C++. So far I could not find a programming language that does not have similar (or worse) scissors. It's more like "pick your poison" type of choice. After I learned Scala, my C++ code started to look like functional programming. According to Bartosz that's a good thing, and I did not have to dive into Haskell (yet). :)
- wheaties 13y agoI went C++ -> Python -> Scala. Still do Python. Don't do C++ anymore for the same exact reasons he mentions. The guy is a C++ hero and to hear him say those things means a lot. I encourage you to keep playing around with Scala. Have fund with the Actor model. Enjoy GC.
- chetanahuja 13y ago"Enjoy GC." Can't tell whether joking or serious. I guess my bitter laugh covers both cases.
- AsymetricCom 13y ago"Enjoy GC" "Enjoy living on a boat" "Enjoy waking up at 2AM" and other ways being not free is freeing.
- jerf 13y agoIt's easier to start from a GC'ed language, and use escape hatches when you need them, then to start without GC and then realize that your program has become a mess because you don't have it. Many GC'ed languages have such escape hatches. Those that don't, well, don't start writing performance-critical code in them would be my recommendation. And also, do not miss his point about reference counting just being a form of GC. "Manual memory management" isn't really a thing that exists, there's a whole suite of memory management techniques and alternatives, and it's easy with something like "C++ with ref counting" to actually be experiencing the worst of all worlds (all the work of "manual" memory management with all the disadvantages of GC) if you don't deeply understand what's really going on with your memory.
- chetanahuja 13y agoEvery time I read a "scathing" attack on C/C++ for being the worst language the author ever heard of, I hear Jack Sparrow's reply in my head "Ahh... but you have heard of me". Somehow despite the litany of crippling deficiencies, C/C++ have managed to be the foundation of every piece of technology a consumer or a computer professional will ever touch in their daily life. But yeah, other than that, we should all be using.. oh, I don't know, scala or haskell or something like that.
- cbp 13y agoWhy do you group C with C++?
- chetanahuja 13y agoFrom the above-mentioned litany of deficiencies: "You might think of the C subset of C++ as bona fide assembly language which you shouldn’t use it in day-to-day programming, except that it’s right there on the surface. If you reach blindly into your C++ toolbox, you’re likely to come up with naked pointers, for loops, and all this ugly stuff." It's all rolled into one as far as the author is concerned.
- banachtarski 13y agoNo the article is clearly about C++.
- chetanahuja 13y agoSorry but I have to call bullshit on this. Even in addition to the passage I quoted which explicitly calls out compatibility with C as the biggest problem with C++, the bulk of the rest of that article is directed towards resource management, starting with dismissing malloc as the worst possible API for memory allocation and going on to bitterly complain about various problems with pointers, global memory, side effects, for loops and any and everything that C++ inherits from C. The overwhelming thrust of the article is that C++ needs to stop looking like C and has to start looking like Haskell or whatever other functional cool-aid is being drunk these days. If you are interpreting this blog post to be a call to programmers to go back to C, you're not reading the same words that I am.
- detrino 13y agoHis entire rant about resource management is misplaced. It's not that new/delete/pointers are "bad" or retained only for backwards compatibility, they are primitives from which other abstractions are built. I don't think its too much to ask professionals understand simple concepts such as RAII, which renders his entire example trivial.
- phren0logy 13y agoThere was a time when I put more emphasis on what people should be able to do vs what they actually do. That time in my life has passed.
- BartoszMilewski 13y agoI wouldn't have mentioned resource management at all if it weren't for Bjarne's keynote: http://channel9.msdn.com/Events/GoingNative/2013/Opening-Keynote-Bjarne-Stroustrup http://channel9.msdn.com/Events/GoingNative/2013/Opening-Key... . Apparently this is still not common knowledge.
- detrino 13y agoThis is the first thing that he says during his keynote: "So, in the next couple of days you're going to hear a lot about the latest and greatest in C++, You're going to hear a lot about advanced techniques and new features. And I decided that in the keynote I couldn't go too much into that, so I'm going to do the opposite. I'm going to try and focus on what is the essence of C++. What is it that has been constant over the decades and what it is that that keeps C++ alive and kicking." It was clearly framed as a history lesson about C++'s strengths, so I think it is a bit disingenuous to claim he was teaching resource management to a crowd of advanced C++ programmers.
- CCs 13y agoBartosz, Haskell was created 23 years ago, before Java. What is the reason it did not catch on yet? Will that change? I'm not aware of any even mildly successful system that uses pure functional languages. Most of the implementations I know about is either C/C++/ObjC or JVM. Some Python (Youtube, Dropbox), one .NET (StackOverflow) and pretty much that's it. What do I miss? [Edit] I'm looking for production code, not "in-house" or "internal tools". I did read trough http://www.haskell.org/haskellwiki/Haskell_in_industry http://www.haskell.org/haskellwiki/Haskell_in_industry
- AsymetricCom 13y agoI'd rather Edward than Samuel Boxingglovehands
- rob05c 13y agoYou would, but the person shaking Edward's hand would not. To stretch the analogy, scissors are dangerous, but they're also very useful. I prefer a language that lets me put away the scissors when I don't need them, so I don't cut someone's hand off. For example, Python with C bindings. The problem with C++, IMO, is that it doesn't let you put the scissors away.
- AsymetricCom 13y agoYes, much better to punch your users into submission so they don't even think of using their hands.
- rob05c 13y agoC++: an octopus made by nailing extra legs onto a dog. — Steve Taylor http://harmful.cat-v.org/software/c++/ http://harmful.cat-v.org/software/c++/
- detrino 13y agoDo you think anything in that link is relevant to this article or did you just want to get in on the C++ bashing and had nothing to contribute of your own?
- sanskritabelt 13y agoWhenever I see people comparing C to assembly I automatically assume they don't know anything about (a) C or (b) any kind of assembly.
- nkurz 13y agoI think your 'or' might be misleading, with the (a) incidental and (b) required. I deal with a number of smart C (and even C++) programmers who view it as assembly with macros. But I've yet to meet any assembly programmers who view C as just a more succinct way to write assembly. Maybe it can be phrased as "Anyone who conflates C and assembly has probably never compared the output of their compiler with the code they think they wrote".
- wwweston 13y ago"Ask any C++ guru and they will tell you: avoid mutation, avoid side effects, don’t use loops, avoid class hierarchies and inheritance. But you will need strict discipline and total control over your collaborators to pull that off because C++ is so permissive. "Haskell is not permissive, it won’t let you — or your coworkers — write unsafe code. Yes, initially you’ll be scratching your head trying to implement something in Haskell that you could hack in C++ in 10 minutes. If you’re lucky, and you work for Sean Parent or other exceptional programmer, he will code review your hacks and show you how not to program in C++." For those who aren't familiar with Parent, watch this talk: https://www.youtube.com/watch?v=4moyKUHApq4 https://www.youtube.com/watch?v=4moyKUHApq4 which introduced me to Stepanov's "Elements of Programming" and the idea that I could be working with better/more reliable/provable abstractions in C++. That said... after a few weeks of shallowly digesting the material, I started thinking pretty much like Milewski says above: it's great if I can learn to write better C++, but if what I really want is to escape from its specific dangers and general common programming pitfalls, something like Haskell seems like a better bet.
- deleted 13y ago[deleted]
- njharman 13y agoI looked at the banner and could think of nothing but "Hello. My name is Inigo Montoya. You killed my father. Prepare to die." I'm sorry and deserve to be downvoted.
- fetbaffe 13y agoMe too!
- dsego 13y agoC++, the language programmers love to hate :) If you'd like to read some more C++ bashing: http://yosefk.com/c++fqa/ http://yosefk.com/c++fqa/
- detrino 13y agoDo you think anything in that link is relevant to this article or did you just want to get in on the C++ bashing and had nothing to contribute of your own?
- seanalltogether 13y agoJohn Carmack wrote a very interesting post about this same topic. http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/ http://www.altdevblogaday.com/2012/04/26/functional-programm... To sum it up, he's still writing code in C++, but it has become less and less like C++. His code has become less OOP and more functional.
- outside1234 13y agoI think Linus sums up C++ pretty well: http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918 http://thread.gmane.org/gmane.comp.version-control.git/57643...
- detrino 13y agoDo you think anything in that link is relevant to this article or did you just want to get in on the C++ bashing and had nothing to contribute of your own?
- outside1234 13y agoI think its relevant, honestly. C++ is a pile of hacks, layer upon layer, that only a small highly talented set of programmers can manage to master and the rest shoot themselves in the foot with. Linus says that in his own way, but that's the truth of the situation: C++ is a mess. My takeaway from experience from all of that is to use C (as Linus argues).
- austinz 13y agoRegarding his assertion about reference counting: Apple's implementation of ARC for Objective-C doesn't handle cycles (it requires the engineer to reason about weak and strong references in order to prevent memory leaks), but it is certainly a "serious" implementation. The fact that it doesn't have facilities for detecting and releasing cyclic references makes it definitely not the "other side" of the GC coin. That being said, ARC-style reference counting is more limited in terms of what developers can do with their code, and it may not be a general enough solution for a language like C++ (which strives to be all things to all people). Weak pointers in Objective-C also require runtime support, which could probably not be appropriate for high-performance applications in many cases.
- lelandbatey 13y agoBig side note, but C++ for me is just... too much. I come to C++ from Python, and they are just so far from each other it hurts. One of the fundamental things about Python that I loved was: "There should be one-- and preferably only one --obvious way to do it." Meanwhile, the sage wisdom I heard learning C++ is: "C++ is wonderful because there are so many ways to do anything." These two methods of thought fly right in the face of each other, and it's very hard to reconcile. With Python, I felt like I truly was learning a language, a language of action where doing any one thing was consistently defined. With C++ I feel like I'm in an ocean of choice and ambiguity, having to carry around this huge load of tribal knowledge to get anything done. Not saying it's a bad language, just sharing my feelings on it.
- 16s 13y agoReversing a string in Python is not obvious nor consistent: str[::-1] While it is in C++: std::reverse(str.begin(), str.end()); And Ruby is even more obvious and consistent: str.reverse() Most people who rag on C++ have never seriously used it. It's not that bad. Really, it isn't.
- rictic 13y agoThat's one point against python, and half a point for C++ [1]. By my accounting that leaves the score still hugely in python's favor when it comes to obviousness and consistency. Python vs Ruby is another subject entirely. Largely I feel like it's mostly a narcissism of small differences situation, and have only been doing more Python than Ruby lately because more people around me are Pythonistas than Rubyists at the moment. 1] ideally you wouldn't have to tell the reverse function the starting and ending points for the string unless you only wanted the reverse of a substring
- nly 13y agobegin() and end() return iterators. Python has iterators too, so this concept shouldn't be alien to Python programmers. reverse() is a generic algorithm that operates on any pair of bidirectional iterators. Actually, in C++, you ideally wouldn't reverse the string at all... you'd just call str.rbegin() and str.rend() to grab the reverse iterators, and pass them straight to your next algorithm. The two approaches are just as consistent as one another, Python just uses a terser syntax (which, in my opinion, isn't as obvious). In C++14, if all things go according to plan with Concepts Lite, you'll be able to write a short 3-5 line, reusable, version of reverse() that takes your string (or container) as one argument, deduces at compile time, during overload resolution, that begin() and end() return bidirectional iterators, and then does the right thing. Failing that, C++14 may introduce Ranges. So C++ is only getting terser.
- codex 13y agoThe author now works for a Haskell company; perhaps this helps explain his changing attitudes towards C++. Or it could be a result of them.
- limmeau 13y agoDo you mean Corensic? Their homepage is now "under construction", according to Network Solutions.
- BartoszMilewski 13y agoI did work for Corensic, which was bought by F5. It was a company that made a very ingenious data race detector. I learned a lot about data races and how they prevent companies from adopting concurrent programming. I also used to work for a Haskell company, FP Complete, but I quit, so I'm no longer representing them. I learned a lot about building actual applications using Haskell at FP Complete.
- millstone 13y ago> The power of multicore processors, vector units, and GPUs is being squandered by the industry because of an obsolete programming paradigm. It’s worth addressing these in turn. In reverse order: I dispute that the C paradigm squanders GPUs. OpenCL and CUDA are the two most prominent languages written with GPUs in mind, and both have a lot more in common with C than with Haskell. In particular they eschew functional mainstays like recursion, linked lists, and garbage collection. So for GPUs, it seems like the ideal paradigm is closer to C than Haskell. For vector units, there’s some recent excitement about auto-vectorization in Haskell. But I’m skeptical about the potential of auto-vectorization in general, since it only seems to apply to simple loops, and can’t take advantage of all instructions. Most effectively vectorized code uses either compiler intrinsics or outright assembly, and I don’t see that changing any time soon (I’d love to be proven wrong on this though). Lastly, multicore processors. C++11 more or less standardized the creaky POSIX threading model, with some additions like thread locals - hardly state of the art. I wonder if the author is familiar with other approaches, like libdispatch, which provide a much improved model. One last observation. Parallelism is not a goal! Improved performance is the goal, and parallelism is one mechanism to improved performance. If your Haskell program runs at half the speed of a C++ program, but scales to twice as many cores so as to make the overall time equal, that’s not a wash: it’s a significant win for C++, which did the same thing with half the resources (think battery drain, heat, other processes, etc.) Horse in front of cart.
- lmm 13y ago>I dispute that the C paradigm squanders GPUs. OpenCL and CUDA are the two most prominent languages written with GPUs in mind, and both have a lot more in common with C than with Haskell. In particular they eschew functional mainstays like recursion, linked lists, and garbage collection. So for GPUs, it seems like the ideal paradigm is closer to C than Haskell. I think the more obvious explanation is that it's much easier to write a compiler for C than for Haskell. Thus the first tooling available for any new system is almost always C. It doesn't mean C's the best tool. >For vector units, there’s some recent excitement about auto-vectorization in Haskell. But I’m skeptical about the potential of auto-vectorization in general, since it only seems to apply to simple loops, and can’t take advantage of all instructions. Most effectively vectorized code uses either compiler intrinsics or outright assembly, and I don’t see that changing any time soon (I’d love to be proven wrong on this though). We'll have to wait and see on this. >Lastly, multicore processors. C++11 more or less standardized the creaky POSIX threading model, with some additions like thread locals - hardly state of the art. I wonder if the author is familiar with other approaches, like libdispatch, which provide a much improved model. My experience is that alternative approaches to something as fundamental as parallelism never take off, because they can't gather an ecosystem around them (I'm looking in particular at the chaos of approaches available in perl and especially python). I think a modern language needs to have a single, obvious, preferred way of achieving parallelism/concurrency that libraries can build on top of (and that's why javascript has been so successful - while it's a terrible language in many ways, there is one and only one way you handle parallel-type problems, and it's (slightly) better than the standard way in other languages)
- eonil 13y ago"It’s a common but false belief that reference counting (using shared pointers in particular) is better than garbage collection. There is actual research showing that the two approaches are just two sides of the same coin." Yeah. But RC is at least deterministic and controllable side. Also, RC is just one of options of C++, while you can implement GC yourself in C++ without any overhead unlike any memory management method on GC.
- pcwalton 13y agoWithout compiler support for precise stack maps and barriers (and I don't know if it's actually possible to implement them, given how malleable pointers are in C++) the best you can do is conservative stop-the-world GC. That sacrifices a lot of performance over the incremental or concurrent GC algorithms you see in runtimes like the HotSpot JVM.
- deleted 13y ago[deleted]
- rwallace 13y agoThe article explained why RC is not deterministic.
- millstone 13y agoRC is much more deterministic than GC. Garbage collectors commonly defer object deallocation until some threshold is reached, and then do it all at once. This means that two iterations of the same loop, that do the exact same thing, may take dramatically different amounts of time. Reference counting is more stable and predictable, because the deallocation behavior depends only on the object graph in question, and not on some global state.
- millstone 13y agoThis jumped out at me too. I don’t think this point was carefully considered. For example, the Linux kernel uses reference counting - see https://www.kernel.org/doc/Documentation/kref.txt https://www.kernel.org/doc/Documentation/kref.txt . Does anyone doubt that this mechanism is better than attempting to garbage collect the kernel?
- general_failure 13y agoBrilliant, just brilliant. I found myself laughing and nodding all the way. The sad situation is we have no worthy competitor. Go?
- qznc 13y agoD [0], according to the author and me. Maybe Rust at some point. Go is not flexible enough: Required garbage collection, no type-safe generic programming (yet), opinionated concurrency model. [0] http://dlang.org/ http://dlang.org/
- copx 13y agoThe H.264 encoder I use is written in a mixture of C and ASM. It is damn fast and maxes out all cores. I dare you to write a full-featured, functional H.264 encoder in Haskell with equal or superior performance. Once such a thing exist I will start believing the hype. Until then I reserve the right to consider the current Haskell/FP craze the biggest amount of bullshit since the Java/OOP craze. Sorry people, I already know that magic language/paradigm which solves all problems of software engineering. Which allows me to write 4 times less code, said code being robust and maintainable practically by default, yet as fast as C/C++ if not faster, all that thanks to this great new model of software engineering! It is the (only) future! Yes, the Java/OOP/design patterns/UML crowd made exactly the same bullshit claims back then. Nobody talks like that about Java/OOP anymore because the bullshit eventually hit the fan known as reality. Oh and before Sun's viral marketing campaign there were the Lisp weenies. Again, same bullshit. We already have a "30x less code" language which comes bundled with an insufferable sense of intellectual superiority not backed by practical results. Oh, and I almost forgot the Python/Ruby "dynamic" and "human" craze. "Programming for human beings" - it's the (only) future! Back then the snake oil addicts paraded around dynamic typing and code which read like plain English as the salvation of the programmer. Nowadays they claim dynamic typing is the software engineering equivalent of the Holocaust and that good code must look like math! I am so tired of it..
- effn 13y agoSo, any programming language incapable of beating a heavily tuned C/ASm h.264 encoder is bullshit?
- deleted 13y ago[deleted]
- copx 13y agoNo, that wasn't my point at all. My point was that I mistrust all braggart claims about how language/paradigm X will turn water into wine.
- polymatter 13y ago
- Gupie 13y ago> C++ “solved” the problem of redundant casting and error- > prone size calculations by replacing malloc and free with > new and delete. The corrected C++ version of the code > above would be: > > struct Pod { > int count; > int * counters; > }; > > int n = 10; > Pod * pod = new Pod; > pod->count = n; > pod->counters = new int [n]; > ... > delete [] pod->counters; > delete pod; The 'corrected C++ version of the code' is actually: std:vector< int > pod( 10 ); ... I didn't bother reading any further.
- JanneVee 13y ago> Yes, initially you’ll be scratching your head trying to implement something in Haskell that you could hack in C++ in 10 minutes. If you’re lucky, and you work for Sean Parent or other exceptional programmer, he will code review your hacks and show you how not to program in C++. Don't underestimate "instant gratification" even when it comes to programming languages. Yes you might code yourself into a mess further down the line, but most of us are in the business of shipping software not worrying about its correctness.
- chrisdone 13y agoI'd argue that Haskell (which is what I use professionally, can't speak for Scala) lets you write your less well designed code for shipping, and then refactor it later into something clean. There's a very low cost to changing code, so you worry less about getting it right the first time.
- JanneVee 13y agoBut in some cases like mine you have legacy code. You still have to ship new features and bug fixes. If I get to green field something really new, then Haskell or Scala might be on the table but currently they are not options. Not even embedding them.
- static_typed 13y agoThe problem is not that C++ is hard, it's that Haskell doesn't solve the same kind of problems. We would all love programming to be easier, for the compiler or interpreter to just know what we really meant, rather than what we actually typed, but sometimes the tools are sharp, are a bit more manual, exactly because they offer more control. The constant sell of Haskell or Go as the panacea for all programming problems is like someone else telling us all to adopt socks made of rubber - a few make like that, may even blog and evangelise about it, but the rest of us find it uncomfortable and annoying.
- zvrba 13y ago> But you will need strict discipline and total control over your collaborators to pull that off because C++ is so permissive. Except it's not. The key is proper encapsulation into classes and generous use of private instance variables. The real problem is social: people want to get something done quickly, so instead of talking to the original author[1], they put a new method in the class (or declare a friend) and happily continue hacking, without thinking of far-reaching consequences of whether unrestricted (that's what public is) use of the newly introduced method violates class invariants in some way. [1] I'm aware that the original author might not be there anymore. Which makes a good case for documenting design and intent of the code. A QA matter. How does Haskell solve the social problem (directly hacking something into a module you don't own or fully understand)? > What you don’t realize is that it will take you 10 years, if you’re lucky, to discover the “right way” of programming in C++ IMO, only novices and beginners look for "THE right way". Advanced people realize that the "right" way depends on the broad context and look for (the) best compromise solution among a spectrum of solutions. I believe this holds for other computing-related things (designing a LAN, database tables, etc.), as well as real life (sports, martial arts, even everyday things like sitting and walking as any person who has had a lower back problem will tell you). The problem is again social: novices and beginners who refuse to "grow up" and who know just enough to be dangerous: they can produce working but messy code, and refuse to learn other ways of doing the same thing in an appropriate context. (E.g. when to use while vs for, or why copy-pasting large chunks of code between different functions is generally "bad".) Somehow I'm not convinced that Haskell is the magic bullet which solves the underlying social/human issues. > Haskell is not permissive, it won’t let you — or your coworkers — write unsafe code. He never defines what "unsafe" is. Mutation is not unsafe per se. > Don’t be fooled: accessing atomic variables is expensive. I've seen recent slides where the measured cost of an uncontended locked cmpxchg on Haswell was ~20 cycles vs ~5 cycles unlocked. This is NOT expensive, unless unnecessarily you replace all memory accesses with their atomic equivalents. > Most importantly though, threads are not a good abstraction for parallel programming No, but they are an essential building block. > Haskell is way ahead of the curve with respect to parallelism First, a computation can be abstraceted into a data dependency graph. Now, the reason that most of today's applications don't benefit a lot from the vast number of processors available is not that the underlying programming is somehow unsuited for parallelism. It is because that there IS NO parallelism available in these applications: data dependency graph is mostly serial, and if parallelism is available, it is on such a small scale that superscalar CPUs already make use of the large part of it. Also, with overly fine-grained parallelism you WILL end up in a situation where the overhead of atomic operations becomes non-negligible, even if it is only ~20 cycles. I believe that if people more often thought about their designs in message-passing terms, the dependency graph would also emerge, and they would see that there often is very little parallelism to extract through explicit parallelization. (Note that writing to a shared variable is just an extremely simple and efficient method of sending a message). This was also remarked on by Knuth: During the past 50 years, I’ve written well over a thousand programs, many of which have substantial size. I can’t think of even five of those programs that would have been enhanced noticeably by parallelism or multithreading. [http://www.informit.com/articles/article.aspx?p=1193856 http://www.informit.com/articles/article.aspx?p=1193856] So, IMO, easier coding for shared-memory parallelism is one of the worst reasons to switch programming languages. That's why I personally prefer Erlang-style concurrency (actors). Communication patterns and parallelism granularity is explicit, and communication cannot be decoupled from synchronization. [With shared variables, these two are decoupled.]
- roel_v 13y agoI'd consider myself a 'C++ programmer' - I've used it for years, it works very well for me for what I do with it, etc. However, what I find most frustrating is that nothing is intuitive. And there is always a reason for why it is like that, I know. My favorite example is the erase/remove idiom. Anyway, here is a question about C++. Last week I tried to implement a parser for a subset of CSV - one-byte-per-character, fields separated by comma, no quoting, fixed line ending. The only requirement was speed. So I started with a simple C++-style implementation, read one line at a time with std::getline, split with boost tokenizer, copy into vector of vector of string. But it was too slow, so I reimplemented it C-style - boom, first try, 30 times faster. Through some micro-optimisations I got it 30% faster still - copying less, adding some const left and right, caching a pointer. So if anyone is so inclined, how would I make the following more C++-ish and still get the same speed? Using fopen and raw char* to iterate over the memory buffer are what I'd consider the non-C++ aspects of it, but feel free to point out other idiom violations... bool CsvParser::OpenCStyle(boost::filesystem::path path) { FILE* fh = NULL; ::fopen_s(&fh, path.string().c_str(), "rb"); if (fh == NULL) { return false; } const int BUFSIZE = 1024 * 256; char buf[BUFSIZE]; m_Records.reserve(m_EstimatedRecordCount); bool at_end_of_file = false; std::string carryover_field_data; std::vector<std::string>* current_line = NULL; bool at_new_line = true; const char separator = m_Separator; while (!feof(fh)) { size_t size_read = ::fread(buf, sizeof(char), BUFSIZE, fh); char* start_of_field = buf; size_t i = 0; for (i = 0 ; i < BUFSIZE && i < size_read ; i++) { if (at_new_line) { m_Records.push_back(std::vector<std::string>()); current_line = &m_Records.back(); at_new_line = false; } if (buf[i] == separator || (at_new_line = (buf[i] == '\n'))) { current_line->push_back(std::string()); if (carryover_field_data.size() != 0) { std::string field(start_of_field, &buf[i] - start_of_field); m_Records.back().push_back(carryover_field_data + field); carryover_field_data = ""; } else { current_line->back().assign(start_of_field, &buf[i] - start_of_field); } start_of_field = &buf[i + 1]; } } carryover_field_data = std::string(start_of_field, &buf[i] - start_of_field); } fclose(fh); return true; }
- JanneVee 13y ago
- xerophtye 13y agoC++ Novice Question: Why are for loops bad? (as mentioned in the article). What's the alternative?
- BartoszMilewski 13y agoYou should use standard algorithms whenever possible. Sean Parent talked about it at Going Native. He was able to transform a horrible set of for loops he found in Google's code into a few lines of modern C++ using standard algorithms. But he _is_ Sean Parent!
- MichaelMoser123 13y agoHaskell is creating a new value for every parameter / function return value; That means that even for trivial tasks it is churning over non trivial amounts of RAM; the footprint of a Haskell program is therefore rather large; I guess that makes it rather impractical for real systems. But of course, this one is an interesting observation: "If nature were as serious about backward compatibility as C++ is, humans would still have tails, gills, flippers, antennae, and external skeletons on top of internal ones — they all made sense at some point in the evolution." I guess C++ is like Perl: for many things there is more than one way to do a thing; Don't like exceptions? Disable during compilation and code as in C with error codes; That's what makes the whole thing malleable; the right kind of flexibility is a winning feature.
- mtdewcmu 13y ago"...avoid class hierarchies and inheritance..." I love hearing this from OOP insiders. Virtual functions are particularly awful to track down, and are probably worse than GOTO ever was. At least GOTOs only went to one place.
- cLeEOGPw 13y agoIf he replaced "int * _counters;" with "vector<int> _counters;" he would have lost nothing and gained a lot of control. As for the pointer to the Snd object itself, in many cases it is sufficient to create object, not pointer, and pass the reference of the object, then in case of exception memory is always freed no matter how many ints he has push_back'ed and where the exception occurred. And if he really needs to have pointer, then he should create that pointer not in naked function that could return at any time, but make it a member of a class and delete the pointer in destructor. Then make that class as object, which will always execute its destructor, therefore always freeing the memory.