C++ in Coders at Work
gigamonkeys.wordpress.com
gigamonkeys.wordpress.com
If you need to do systems level programming (eg. write a database), and you want to go beyond C's code organization capabilities, and you can select a sensible subset of C++, it's a great language, and you get to control all aspects of memory and CPU.
We're writing our database(s) in C++, and we're pretty much loving every minute of it, and would not switch to C, Java, Erlang or whatever.
Of course we're a startup, so we got to select our own subset, write our own containers, etc:
http://github.com/scalien/scaliendb
One downside is it's hard to find good C/C++ programmers on the market. The vast majority of applicants cannot complete our first interview filter (removing a characters from a C string and writing an instrusive stack in C++):
It's interesting that C++ is increasingly becoming a niche skill. When I started programming you pretty much had a choice of C++ or VB if you wanted a job.
Suits me fine though. A lot of the most interesting work (DSP, kernels, graphics etc) is in C++.
EDIT: downvoters: if you think I'm trolling, please note that I've written more code in C++ than any other language. I would love a "better C" that's universally better than C++. If you disagree with my points, please elaborate.
D is doomed by the Phobos/Tango schism, no-one would risk their business on it.
The Objective-C additions just aren't very low-level. They're basically an object runtime library with some syntactic sugar. This is fine for situations where you want something a bit more high level and dynamic[1], but gives you no advantage over C in something like device drivers or programming embedded devices, because you just aren't going to use those features. Minimalistic (optional!) vtable dynamic dispatch is great for these uses, though, and generic programming can be really nice (despite C++'s version in the shape of templates) even for low-level applications. RAII also is really nice.
D is doomed by the Phobos/Tango schism, no-one would risk their business on it.
If D was that much better, I think a sufficient open-source ecosystem would spring up around at least one of the two libraries that you could realistically use it. As it is, I doubt it would be popular even without the schism.
[1] Though in my opinion, most iOS apps would be easier to write in a managed language, especially if you could call out to C/C++. The Obj-C focus is understandable from Apple's point of view though.
Maybe, but just as you can not easily dismiss C++ because so many people have written so many successful programs in it, it is difficult to dismiss all of the great software from Apple, and arguably the largest library of software for mobile devices in the App Store, written in Objective C.
You point out the resource constraints that make C++ superior to Objective C and other languages for drivers and embedded systems. Similarly, I suspect Objective C gives Apple the right trade offs for writing sophisticated software for mobile devices that is responsive, uses memory effectively, and does not kill battery life.
C99 is such a contender imho.
C99 is a pretty tiny (but welcome) incremental improvement on C. It's also almost entirely orthogonal to C++'s additions. Calling C99 a C++ replacement is pushing it, so you'll need to elaborate on why you think so. I'd be curious about an instance of something you can do better (let alone fundamentally better) in C99 than C++. I can think of plenty of examples of the opposite.
C++ sometimes makes me want to tear my hair out, sure[1], but when using pure C(99), I find myself thinking, "this code would be so much more compact in C++."
[1] This is usually because either I or someone else tried to be too clever. Otherwise it's because of something C++ does badly that neither C89 nor C99 do at all.
I didn't call it a C++ replacement. Just a C89 replacement. "A better C" :)
> I'd be curious about an instance of something you can do better (let alone fundamentally better) in C99 than C++.
It depends. If you need C++'s syntactic sugar for OOP-style code then yes - C++ is better for that. But if you don't do OO-heavy stuff you can use plain C and get away with less complexity (and more control over the instruction cache, etc).
I'm in the lucky position of not needing OO so I get away with using C. And C99 makes my life, compared to the old C89 standard (and the C++ C subset), easier. I can declare variables in the middle of a function (or even within the if statement!). I can initialize structs by its member's names thanks to designated initializers. And the implicit "upcast" from void* to whatever is a blessing (though possible in C89 it isn't available in C++). Oh, and I almost forgot variable length arrays.
> but when using pure C(99), I find myself thinking, "this code would be so much more compact in C++."
Well, this can go the other way round, too. Just take the right tool for the job.
There's no language currently out there that covers as much ground as C++ and is anywhere near as good at it. C99 falls into a similar bucket as Go or Objective-C in covering a subset of cases where C++ is useful.
I echo that sentiment. I'm using C++ in my current project (first time in many, many moons), and it dies what we want reasonably well, but it is bigger than any language needs to be.
Have you tried OCaml? It's has it's problems, but it's nowhere near as bad as C++.
In the Microsoft ecosystem, C# is this. No, C# isn't OS-independent or hardware-independent or HTTP-server independent. It's not meant to be. C# isn't meant to be an abstractly beautiful language like Lisp or highly performant and portable like raw C. And it's not intended to be part of the LAMP free-software stack; it's intended for a business context that can spend a bit of money to make money. (The C# compiler is actually free, though the IDE isn't and of course the underlying Microsoft OS isn't.)
It's C and most of C++ without the foot-shootiness or Java verbosity. For what it is meant to be and for the problem domains that it serves, C# really does make for great productivity. My company and I have used it as our primary language for several years and I like it a lot. Most of the productivity comes from tight integration to external ecosystem elements that make for a useful application, notably MS SQL databases and ASP.NET web servers, all wrapped within a solid IDE. More productivity comes from getting to ignore things like memory allocation and header files which the language just handles for you. Perfect for simply getting things done in a business context when things like price and portability are not a concern. (When they ARE a concern, then by all means use the LAMP stack and C# is not for you.)
Calling C# or Java a "better C" is therefore not terribly useful. C is not good at the things C# is good at and vice versa. I use about 6 or 7 different languages on a regular basis, and often the only choice is between C and C++.
I'm not sure where you're going with the second paragraph. C and C++ were never popular for general web app development.
You've been brainwashed by Microsoft. No one using LAMP cares about price (that much) or portability ('L' is for Linux). Freedom from vendor lock-in (and in this case, a predatory, vengeful vendor) is the biggest practical advantage. Stability and the thing actually fucking working is another (I never enjoyed babysitting Windows servers; do you?). It's also easier to build robust applications with LAMP.
Enjoy paying your Microsoft tithe, peasant.
No wonder you find C++ pleasurable, you are using it as C with classes! However, if you are working on an existing code base with mix of STL, boost and bunch of other libraries, you would start feeling pain of using C++. In my experience, every library author uses a different subset of C++ and as an application writer, you often have to grapple with the glaringly different idoms in your program. I find boost pleasurable to use; however looking at boost source is enough to melt my mind.
Almost everywhere C++ (language and libraries) try to satisfy every corner case and sacrifice usability of common case. e. g. STL iterators (at least I have BOOST_FOREACH to soften them). Ah well this is probably contributing very little to the discussion but I feel better now :) So let me redirect to [C++ FQA](http://yosefk.com/c++fqa/) and let yourself decide whether the points in FQA make sense to you.
https://github.com/scalien/scaliendb/tree/master/src/System/...
Yes, we try to avoid op.overloading, exceptions, and we explicitly don't use the STL, Boost, <any library>. All the code is ours, which is really nice if you're debugging, finding performance problems, etc. It was our experience on previous projects that pulling in outside libraries in a systems level project like a database ends up wasting time (spent in understanding, debugging and optimizing outside code) over just writing what you need. This has proven to be a good call, we fix all bugs, however deep or nasty very quickly.
Thanks for the UnitTest++ tip.
{ embedded programmer }
I also find C++ pleasurable (90% of the time) and in my code, I make heavy use of templates (including compile-time calculation/preparation of data, ie not only simple "templates as generics"), exceptions (well, not heavy use, I use them for handling exceptional circumstances, nothing more), STL (especially the containers), std::string (C strings and custom string classes are evil), Boost (not so much, but it has some great libraries), Qt (GUI mainly, but also the support libraries) and Intel Threading Building Blocks. I do not use multiple inheritance, but I certainly use classes and single inheritance, pointers, smart pointers and memory pools.
But I still like C++.
I agree that it has its problems and it certainly isn't a good language for beginners [1], but it is a very flexible and powerful language that is useful for a range of tasks from low-level to high-level code (though I guess it excells at mid-level: higher level that C, but low level enough for performance sensitive code, eg games). I certainly wouldn't recommend it for a lot of tasks, but I wouldn't avoid it either.
I'm not a big fan of the FQA, but the FAQ Lite is very good: http://www.parashift.com/c++-faq-lite/index.html also, Bjarne Stroustrups FAQ is excellent: http://www2.research.att.com/~bs/bs_faq2.html
[1] Even experts got this quiz wrong: https://scapecode.com/2009/10/a-simple-c-quiz/
We could reasonably replace C++ with a combination of C and a higher-level language. However, C++ is a much better language for our low-level code than C, and we have a lot of low-level code, so we have to take it seriously. If we took the route of using a high-level language to coordinate functionality implemented in C, we would end up using C++ to implement the "C" libraries, just for the benefits of RAII, exceptions, smart pointers, etc.
We could also succeed with a stable and efficient Common Lisp implementation. Other languages such as OCaml might work for us, but I'm not qualified to say.
We wouldn't bother changing at this point, though, unless we decided to create an entirely new product to compete with our current one. C++ is not a problem or a limitation for us. The shortcomings of C++ add a little bit of extra work, but they aren't a multiplier. Most other languages would aggravate our existing problems instead of just adding a constant factor of inconvenience.
And that's with templates, exceptions, STL, and Boost!
I have found C++ to be too complex to fit within my head. Even though I am programming almost exclusively in it for a while; I get a feeling that I am spending more time on placating the compiler than thinking about code.
For cross platform work that uses a lot of libraries I would not recommend C++. It is where my frustration stems from.
I think most good C++ programmers spend years coming up to speed. I know I spent many hours coding for fun in college and read through TC++PL a couple of times (also for fun) before I started programming in C++ professionally. It was a wise investment, no doubt about it. It's an open question whether it would be a wise investment today, though.
If you are going to complain about a self assignment check in the assignment operator function, maybe you should stay away from any kind of programming at all.
And I don't understand this complaining about which subset of C++ needs to be used. I have written scala code and it most definitely does not use every feature of scala.
The scenarios in which any of the C++ features need to be used is fairly obvious.
1. STL - use it all the time, it is one of the core libraries of modern C++ 2. templates/overloading - You will use these features when you use STL. You typically won't create you own template classes. 3. exceptions - This is one of the C++ features used less often. Dealing with it is no different from dealing with exceptions in other languages like Java.
> I find boost pleasurable to use; however looking at boost source is enough to melt my mind.
The idea is that you use boost source and not look at it. boost libraries are a very specialized kind of template meta-programming code that only container writers have to deal with. I like being able to use a smart_ptr without having to worry about silly memory leaks, none of which would have been possible without templates or operator overloading in plain vanilla C.
There are several deficiencies with C++, that I experience on a day to day basis, none of which are discussed in any of these online C++ rants. I have never faced any software engineering issues because of the multitude of C++ features. That has never been the problem. If anything all these features reduce the amount of boiler plate that I need to write to get my job done.
You may not like STL iterators, but they are a 1000 times better than some of the gnarly C macros I have seen in C code to get STL like containers in C. Once you have seen that kind of C code, you will be glad about the existence of templates.
The issue is picking the particular subset and then getting everyone to adhere to it. That works okay in mature engineering shops such as google:
http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
So I guess I'd say it requires more discipline than, say, Java. (One could similarly argue that writing good Perl requires more discipline that writing good Python.)
There's also John Carmack's quip:
IMO, good C++ code is better than good C code, but bad C++ can be much, much worse than bad C code.
Different folks internalize different features of C++, for good or bad. To take someone's comfort zone and institutionalize it is arrogant.
There's nothing wrong with that; having that stuff in your style guide means that you get more consistent code, which is easier for everyone to read whatever their personal preferences.
(General point: Having a rule that says "Everyone must do X rather than Y" doesn't mean claiming, or thinking, that X is better than Y. There's not much to choose between driving on the left side of the road and driving on the right, but it sure is valuable to choose one or the other and stick with it.)
http://stackoverflow.com/questions/5004162/what-does-it-mean...
I've never tried to find C++ programmers on the market, but I do seem to come accross fewer and fewer C++ programmers now. I use a lot of C++ myself (amongst other languages, including Clojure, Java, Python and recently SML). I think having learnt it long before becoming a professional programmer may have given me a kind of attachment to it, but I actually enjoy using it (most of the time, I do often wish it did things differently or supported features I see in languages like ML or Lisp derivitives).
As for your interview question, the first seems almost trivial. The second, an intrusive stack, isn't very hard either [1]. I'm surprised that most applicants have trouble with them!
[1] Heres one I slapped together in ~5 minutes (no comments, only tested by running that code, etc etc): https://gist.github.com/827619
The basic issue is that we didn't want to include external libraries, because it's a pain to debug, pain to build on multiple platforms and there are licensing issues.
Also we don't use so many datastructures, so we rolled our own and we are happy with them. For example we have an intrusive treemap, that has a function for returning the middle of a sorted key which is useful when you want to split a keyspace into two. Not sure if any of STL/Boost supports that.
Your solutions looks good, you are hired! ;) Seriously, we know that it is not that hard, but still the applicants have problems with it.
Sure, obviously for niche tasks a general library may not perform as well as a container custom-made for the task at hand. That certainly is a legitimate reason to roll your own (though, if it were me, I would make my containers STL compatible, similarly to how Boost is STL compatible, that way you can mix and match between standard containers and custom ones and easily convert between them (eg, by using compatible iterators)).
Regarding applicants, I am just as surprised as you are. I guess I didn't notice how much C++ is diminishing in industry (outside of its niche areas, anyway).
PS: You're database does look interesting. May have to keep an eye on it.
A game developer disusses why he often writes his own data structures and steps out of STL and gives concrete examples at http://altdevblogaday.org/2011/02/15/data-structures-one-siz...
(fwiw I don't have a dog in this discussion. I don't use C++ and never will. The above is offered only because I had that page open in another tab when I read your question, and it seemed relevant)
Personally, I will write my own data structures, containers or memory allocators when I have a task that doesn't fit nicely into existing libraries. There is nothing wrong with that. I am curious though when people only use their own. For example, I believe that when writing custom containers, providing STL compatible interfaces (perhaps alongside a non-compatible extension if needed) is a good idea because then you can use the STL when it makes sense, but your own when it doesn't (and pass data between them easily).
Having said that, I did not spend long looking at the code in question (nd in the sibling comment a good reason was presented for at least some of the custom containers), so perhaps it isn't realistic or reasonable to mix and match in this case. Still, I like to understand peoples reasoning because it helps me improve my own coding practices.
What is an instrusive stack?
I guess I was thrown off by the typo and was looking for something else.
Are you sure applicants aren't failing because the application problem for the intrusive stack is written in a confusing manner?
I tried editing the post, but edit functionality doesn't appear to be working correctly.
I don't know, its very possible. I found the application problem very easy to understand and writing an intrusive stack is really easy, so unless I'm very disconnected from the "average applicant", who apparently 1) isn't very good at C++ and 2) doesn't know how to implement common data structures, the problem must be with the application.
I love programming in a sensible subset of C++ too.
The problem is that C++ has long history and when it began, many programmers had erroneous ideas about OO - some skipped it completely, some built absurdly deep inheritance trees, some engaged in ridiculous tricks to stay within "doctrine" (remember a fellow who had a pointer-member to the same object in a parent and a child class just avoid something about down-casting).
So from this history, there's a lot of really bad C++ code "out there".
And just much, when you take two code bases or two groups of programs, each happy with their different sensible subset of C++ and combine them, without being careful, you also wind-up with a hellish mess.
But what I can say is that, compared to Java, the tools for C++ coding suck. Hard. In Eclipse you can write some gibberish and it automatically turns it into valid Java that mostly does what you want. The Java debugger is excellent and works without hickups. The experience you have with Eclipse and CDT just isn't the same. No automatic inclusion of header files, autocompletion doesn't always do what you want, no documentation included, even for the STL. Working with gdb is painful, most of the time it is not possible to properly inspect datastructures in memory and it is generally just easier to litter the code with print statements.
With regard to debugging, I think you're being unrealistic. You're comparing debugging on a fully introspective and managed virtual machine to debugging annotated assembly language. Apples & oranges. If a fully managed VM meets your needs, then use it. If it doesn't, well, welcome to low level programming.
You also make it sound worse than it is; JVM debuggers aren't perfect either: they debug Java-the-language fine, but other JVM languages are more problematic. Good luck with JNI, too. Likewise, there are C++ debuggers which are STL-aware, and even those that aren't can usually be coaxed into displaying pointers as arrays or as supertype pointers. Using gdb directly is rarely necessary; there are perfectly decent frontends. If you're having problems because you're trying to debug compiler-optimised C++, then you're simply running into the limits of the platform. Debugging post-JIT Java is no fun either.
On Windows you probably can't beat Visual Studio.
I'm currently having to use pure gdb to debug some Mac OS X kernel code, and I feel your pain. Using a frontend is much nicer.
This is purely out of curiosity. I'll stick to my standbys of Vim and a terminal window.
Everything from the debugger to the code completion does work well, which is more you can say about most C++ IDE on linux.
The second best I have seen was in KDevelop (when configured correctly -- I remember it only worked correctly when you pre parsed the STL library).
I am also very excited about the clang development. It was developed in a way that it should be very easy to integrate it (or parts of it) in an IDE. Xcode4 will do that. And others probably will follow at some point.
Whilst I couldn't find a way to automatically include header files, once they're added NetBeans automagically switches on autocomplete and finds documentation where available. I've used it for my own C++ projects (using headers and libraries from others as well as my own) and had no problem. I'm by no means an expert (used C++ for only a few months, coming from a PHP background) but I managed to get a few CGI applications working using Xerces-c
In Eclipse you can write some gibberish and it automatically turns
it into valid Java that mostly does what you want.
Isn't this the reason that many treat java programmers as suspect ? I think IDEs are fine once you have mastered the language and the syntax, but it often masks the gaps and deficiencies in one's own knowledge. I find that a bit scary.I understand that mine would be a minority view. Guess work at the IDE together with TDD has significant fan following. Apparently it gets the job done, if that be so, who am I to complain.
Edit: It seems I have hurt someone's ego :|
An IDE with code completion means you can get more done without having to waste time studying API docs; in fact, the IDE's editor can itself become the most efficient doc lookup tool. This gives you more time and attention space to point at your problem domain, rather than mere incidental details.
Object orientation with static typing is a big contributor to this, because you start out with what you want to act on - the noun, which is usually a local variable or field - and get completion on the actions available on that noun. The contrast with functional and procedural styles is stark: there, you need to know the symbolic name of what you want to do to something you already have in hand, but editor completion is almost powerless to help you, because of the order of tokens in the syntax.
I don't care for IDEs either: the farthest I get is my emacs textual expansion.
?? What's wrong with vim? (or emacs, or your flavour of choice)
Frankly, I think much of people's hatred against C++ is the relative lack of good tools on non-Windows platforms.
It seems when compared to other statically typed languages (it doesn't really make sense to compare with dynamically typed languages) C++ does a good job. The STL prevents you from having to reimplement many things you might otherwise need in C and the syntax is more natural or intuitive when compared with C as well.
I have a feeling people just prefer what they're familiar with and make sweeping generalizations or exaggerated claims about other languages and technologies.
People describe Objective-C as "c with objects" done the right way but I'd much rather code in C++ than Objective-C. I also don't really understand why people say they prefer to write in pure C, at least not in 2011. Hacking together a homegrown OO system in C with structs and function pointers and macros doesn't sound any easier or simpler to me.
Actually, POCO has all the stuff you need to write a web-app: templating, form handling, http request/reponse objects, etc. Not that I've done it, but it looks like you could write a web-app using POCO::Net rather painlessly.
I like C++ and don't understand the frustration others express. I don't use a subset, and neither do the other people I work with. We use pretty much the whole thing, TMP, macros and all.
Being well familiar with C++ I can never see a clear reason to prefer something like Java. Qt is better for GUI stuff. POCO is just as good, or better, for network stuff. With C++ you can go ahead and marry the host platform's system calls when that makes sense (i.e. write a unix program).
When it comes to scientific or graphics type libraries it seems like the premier solution usually has a first class C++ interface. The Java equivalents seem harder to evaluate. I did a bunch of GIS stuff recently, using proj.4 and various other things. It sure appears to me that the Java/C# equivalents of the GIS type libraries are less supported and less popular ports of the C++/C ones.
If you have perl/python and C++ in your tool belt, I just don't see the need to reach for the so-called C++ replacements. Aside from hiring considerations, that is.
I also much prefer C++ as a language but garbage collection is such a huge productivity win that I'll always use a GC'd language if it's appropriate. No matter how cleverly you abstract manual memory management away in C++ it's still a real chore and a source of bugs.
In C++ you have to declare your functions in a header, then you have to do it again in the .cpp, I dislike it because if I change one I have to change the other one.
I've used C++ at the last for companies I have been involved with. The only consistency has been that no place used the same subset of C++ features. It usually boils down to what subset the team members are comfortable with. Variations have included exceptions or not, whether or not to use multiple inheritance, STL or Boost (yes, boost isn't really part of the C++ standard, but things like shared ptrs are in TR1), whether or not to use TR1, etc.
I personally don't have a strong opinion, but there are people that abuse C++ in ways that produce lousy code -- classes as a way to have nearly global variables, the whole C with classes approach, etc.
You really should use the right language for what you are working on and that plays well with any libraries you may want to use.
https://developer.mozilla.org/index.php?title=en/C%2B%2B_Por...
For a more current view, see Linus Torvalds' comments [1] [2].
What I would like to see is a language very much like C (being low-level) with a few features built on top. What those features are I guess is the real trick.
One thing I like about C++ is the constructor/destructor mechanism. It's very explicit. The trend now is towards garbage collection (which, admittedly, you can implement in C++). This is a trend I largely agree with. It's quicker and cheaper to write software that way (IMHO). But there is still a place for simper schemes as all GCs I've come across have issues.
One thing I think such a language shouldn't be is object-oriented. To quote Joel Spolsky [3]:
> A lot of us thought in the 1990s that the big battle would be between procedural and object oriented programming, and we thought that object oriented programming would provide a big boost in programmer productivity. I thought that, too. Some people still think that. It turns out we were wrong. Object oriented programming is handy dandy, but it's not really the productivity booster that was promised.
Or at least such objects should be very limited in scope. Linus addresses some of the reasons for this, such as knowing which function is being called by simply looking at a code snippet (typically a patch in his case).
When writing low-level code I certainly do much prefer C over C++. But having the tools to build automatic reference counting into C would be really nice at times.
[1]: http://thread.gmane.org/gmane.comp.version-control.git/57643...
[2]: http://www.realworldtech.com/forums/index.cfm?action=detail&...
1 - Error handling - Go doesn't have any powerful mechanism for error handling. The code I have seen is rather inconsistent and it doesn't solve the main problem from C of forcing people to handle errors.
2 - Polymorphism - They left any kind of generics out. I think this could go a long ways for (1) too, just look at Either or Maybe type in Haskell. Combine this with some pattern matching and you have a really powerful way to enforce error handling and have polymorphic data structures and functions. IMO this is the biggest failing of Go.
I think the failure to provide those two things also makes Go a future mess. Adding them later either breaks a lot of outstanding code or it means you have to versions of Go, the original and new which is a mess.
Actually, the creators of Go are still not afraid of breaking things. For example, recent release (2011-02-01.1¹) changed the syntax of non-blocking channel operations, and it broke code.
[1] https://groups.google.com/d/topic/golang-nuts/uHfjRyO1Q6c/di...
It says something that for the built-in collection types, Slice and Map, they had to hack around their own API and implement this-case-only ad hoc generics. Slice and Map should be fully implementable within the language.
However, the make() functions for slice and map are the only functions in the language that allow you to pass in a type and get that type back as a return function. Why can't users have that functionality? Generics seem to be the easiest way to get it.
myslice := mymake((MyType)(nil), 10).([]MyType)
which is much uglier than the built-in way. However, I'm kinda okay with reflection-laden runtime tomfoolery looking a bit messy, mostly because I rarely use it, and when I do I like it to stand out and be obvious what is going on.
Anyway, it's not like a wannabe OO language would adopt Algebraic Data Types. "Those are for these ivory tower languages that no one use in the real world", one might say.
Qi: http://en.wikipedia.org/wiki/Qi_%28programming_language%29
There is no real argument made one way or another. If we look at the linked article there are real arguments as to why people don't like C++. Templates, multiple inheritance, and a whole other range of stuff. All Linus is yelling is "I hate C++, I hate STL, them Boost guys aren't worth anything" with absolutely no reasoning what so ever.
As a project leader it is okay for him to disagree about using C++ within his source code base, and within context it is a perfectly valid email, but to use as an example as to why C++ is bad, it is a very bad email to quote.
You may not like it, but it is extremely effective, and Linus _is_ herding thousands of developers, he has to be effective.
Now I agree that for a host of reasons (like taking one's own volition for the country's CEV), dictatorships do not rank high.
Why do we excuse bad behavior from people?
[1]: http://blog.c3lang.org/aims-and-rules-of-thumb-for-the-desig...
I mean, do you remember the C written in the 80s? Often, the only unit of modularity in common use was the translation unit, with static globals used freely, structures with no visibility protection, having their inner guts manipulated by different modules, frequently by manually tweaking the pointers etc.? If you had an API that protected structural guts, you were almost always essentially programming to an object oriented style, only with no help from the language and compiler.
Having said that, there are some things OO is bad at, eg concurrency.
OO prioritizes encapsulation ahead of immutability as a way of making the problem of a mutable struct tractable. Most OO programs are graphs (picture as a complex web) of mutable objects holding references to one another, synchronously passing control from one object's method to the next (picture as a spider travelling around the web, making modifications). Concurrency means there is more than one logical point of control flowing around the graph, making modifications. To ensure modifications are consistent, one must now fight against the interconnected nature of this graph, and make certain areas mutually exclusive; that means you need to set up gates on all the edges leading into those areas (often called semaphores or mutexes).
But OO gives you precious little help in setting aside these areas, and guaranteeing internal consistency in the face of multiple mutating points of control.
Programs in a functional style are different, with their heavy emphasis on immutability. In this case, the web, as it were, is fixed and cannot be changed; instead, if there is to be a modification, a new copy is created (possibly only of the local area of change, and the unchanged portion included via references). Since there is no way to change data, there can be as many points of control performing operations as desired. (Actually, one of the models of computation used for functional programs is that of graph reduction, which pictures the program as a web of expressions rather than structures; and that big expression is iteratively made smaller by calculating different parts of it. In principle, the more points of control you have doing these calculations, or reductions (in the same way as '1 + 2' can be reduced to '3'), the better.)
Programs written in an agent / actor style are also different. Here, there is no single point of control flowing from one node in the graph (web) to the next; instead, each node has its own little point of control, and it reacts to messages coming in from each edge, and sends out messages along edges in response. This makes the program locally single-threaded, but globally concurrent.
But there are moderating factors. Procedural programs that don't enforce strict modularity conventions tend to be bound in size by their complexity, a complexity that works against the level of understanding necessary to make things both concurrent and correct. Meanwhile, procedural programs that do enforce strict modularity will probably be using conventions that emulate a different paradigm, and will inherit that paradigms' costs and benefits WRT concurrency.
But Java naturally tends towards mutability. And you will have to work harder to make it immutable. Java also does not give you as many tools for this kind of style as functional languages usually give you.
First class functions, a rich type system and a library full of immutable data types come to my mind.
Worse, OOP tends to hide the mutable state away internally in objects (or in objects stored inside objects etc) - OOP's data hiding and abstraction support can go against you here. Sure, good programming practices and discipline (eg, const correctness in C++) helps, but the languages definitely encourage mutable state.
I wonder how using methods-as-messages and turning OOP into a message passing system not dissimilar to the actor model would work in practice (both from a usability/syntax and concurrency view).
And then, of course, you have mergers and acquisitions leading to code being thrown away or warehoused or merged with other systems, or new management deciding to start from scratch.
Basically, the industry doesn't really have a long enough attention span to really make the most of OO code reuse.
I think the people making this criticism are looking in the wrong place for the reuse, and / or had weird ideas of what could be reused, and how it could be reused, to begin with.
The reuse that OO gives us comes from raising the level of abstraction with which the program is written, in particular because runtime libraries are so much larger ("batteries included", etc.). The hierarchical namespaces and encapsulated structure of modern class libraries reduces their cognitive overhead. For example, in .NET, you can work with WebRequest, TcpClient or Socket, depending on what level of control you need; and the conventions for working with these things are pretty uniform across the board. Larger applications are self-similarly written at a higher level, reusing code within themselves in a framework-like way.
But the people who thought there was going to be some kind of central library of domain-specific classes in your company, that you would reuse in multiple disparate applications, I think that was always fairly naive; reuse implies coupling, and coupling of things that are individually subject to change in ways that affects their users is fraught with problems, and always has been.
The best candidates for reuse aren't usually representations of the domain concepts that are central to a business, because each application in the business will probably be wanting to do something quite unique with those domain classes. Rather, it's concepts that are self-contained, universal, not likely to change much over time nor need different intrinsic behaviour from application to application, which are best suited to reuse.
One way they justify this is to 'reduce coupling', and so your comment about coupling tripped a red flag for me. Whenever I want to take the piss out of an Architect I just tell them that we should 'add an extra layer of indirection' to the design. 99% of the time they agree without realising that I'm satirising them.
Actually, this could be a good thing, depending on what the goals were. For example, non-member non-friend classes are often more OO than putting everything into the class[1]. Furthermore, if you want to use function overloading for multiple dispatch, the keeping the functions separate from the objects is also useful. If your system is highly concurrent, keeping the code and data separate can be quite helpful. Also keeping data in structure-of-arrays form and using external functions to operate on these arrays can make huge differences in terms of cache usage, potential parallelism and vectorization of instructions.
Coupling might be a reason to do this, but its certainly not the first reason I think of. There are plenty of better reasons (and as always, not all reasons apply to all codebases).
TL;DR: There are lots of reasons why doing this could be a good thing.
(fwiw, I like to do this with my core data structures because I believe code and data should be kept separate (and that data is the more important of the two). I do like to provide normal objects as an API though, because I often feel that its a natural interface, but the internals of my code are rarely very OO in the C++/Java sense).
How much of that is due to OO, though? I reuse masses of code without OO all the time.
Well, perhaps, but I've seen it done successfully in NeXTSTEP/OpenStep shops back in the day, such as an investment bank. Not one big library, but a few frameworks so there's some separation.
The team I was on had our own frameworks, shared among the apps we developed. We also used/built our frameworks on frameworks from the bank's Architecture group, which were also used by other development groups.
Now, do you see a significant additional boost that were provided by the various OO styles out there? More specifically, what significant advantage do classes have over modules?
The problem was, back in 83 the compiler was the size and complexity of a C++ or java compiler from 1995. Couple that with some horrible implementations and Ada never took off much beyond Avionics/security/life critical applications.
Which is a shame, because comparing ada to C++ or java today and imnsho Ada wins hands down. The compilers are faster, the code very nearly as fast (In Ada you get things like runtime array checking which slows you down). Unfortunately the programming language wars aren't about technical merit (Java would never have been popular otherwise) and more about social popularity contests/network effects.
EDIT: I might add that at this point ada is /far/ simpler than both c++ anda java. Jean Ichbiah thought carefully about what was needed for large, long lived projects (millions of lines, 30+ years life) and it shows. They got pointers right the first time - access types. verifiability - testing your code is all the rage now, 27 years late. etc. Best yet, the ecosystem around the language is mature. That is unlike c++ you don't have a dozen different approaches taken (template hell), and unlike Java you don't have bureaucratic overload.
http://yosefk.com/c++fqa/heap.html#fqa-16.26
"C++ does not feel pain. It can't be reasoned with. Starting a fight is a big mistake. If you want to use C++, you must learn to love it the way it is, in particular, manage your memory manually."
Why then, you might complain, have we not seen the benefits of OO? Because the majority of programmers (usually by their own admission) suck at design.
…
I had been harboring some suspicions that our big codebases might benefit from the application of some more of the various “modern” C++ design patterns, despite seeing other large game codebases suffer under them. I have since recanted that suspicion.
http://bethblog.com/index.php/2010/10/29/john-carmack-discus...
As you can see, its no std::string, but it can still save you some time.
Probably the most succinct description of the relative strengths of Objective C and C++. Objective C for GUIs, C++ for drivers and embedded development.
Objective-C is just C; there is no inherent performance penalty other than the dynamic dispatch of messages. In situations where that would actually be an issue, you'd be avoiding object-oriented features in C++ as well.
However, driver performance bottlenecks are typically in I/O throughput, not the language the driver was compiled in. The fact OS X drivers are written in a C++ subset likely has to do with the demands of device manufacturers coming over from MacOS 9, just like the existence of Carbon was to appease application developers like Adobe.
NeXTStep had DriverKit, a framework for writing drivers in Objective-C, and this was on 1990s-era PCs. Driver performance is I/O-bound and typically has little to do with the language the driver was compiled in.
In contrast to that, it probably takes years to really understand everything C++ has to offer. And that is talking about the language only, no frameworks or libraries included. Hence, I would say that you can not really compare Obj-C/Cocoa to C++, since the former is a framework and the latter is a language. (This is assuming that most people mean 'Objective-C and Cocoa' when they say 'Obj-C')
If you want to compare Objective-C and C++ on a language level though, you are comparing two very different languages. Objective-C strives for simplicity and readability, which makes some things easy and some things harder. C++ strives for world domination. There is nothing you can't do with C++, but there are just so many things you can do that figuring out how to 'properly' do stuff can be kind of horrid. Really, there are so many different styles and dialects of C++ that you could use and freely intertwine that defining the language proper is a real challenge. Note that this is not necessarily a bad thing. C++ has a lot of strengths and is increadibly malleable for many different applications. But putting all that flexibility in one language certainly makes that language a truly complex beast, where even reading it can be a real challenge even after years of using it.
Personally, I am a sucker for simplicity and elegance and I would take Obj-C over C++ any day. On the other hand, I have seen some situations where Obj-C's message passing was just too slow for my application and I had to drop back to C function calls in some areas. Also, Garbage Collection and even Reference Counting have a certain performance penalty that might make Obj-C unsuitable for, say, embedded applications.
There is nothing you can't do with C++
That's a tautology for any Turing-complete programming language. C++ may strive for world-domination, but I prefer my languages to be capable of introspection.Complexity is not always directly proportional to the number of features supported.
Complexity is not always directly proportional
to the number of features supported.
This is the difference between Turing complete and Gosling Complete. ;-)C++ was designed with performance in mind. The main goal was to be as efficient as C and It means to not use any runtime.
Objective-C was designed to be source compatible with C and extends the language with a Smalltalk like syntax for OO. It uses a runtime which provides things like reflexion and GC.
Obviously, C++ being Turing complete these are all technically possible with C++. But in practice it would amount to "Greenspunning" the features of Objective C into C++.
The funny thing is Objective-C is also backwards-compatible with C and there is a huge world of difference between programming in Objective-C and programming in C++.
I really can't understand, how someone can favour C for C++. Ok, C is the easier language, but the better abstraction capabilities of C++ outweighs this on a big code base.
Like other construction materials are better than steel unless strength and reliability are a concern.
I think the key sentence is this: "I love to see how they do things because I think they don’t rely on it for the stuff that it’s not really that good at but totally use it as almost a metaprogramming language".
Using templates, it has by far the best metaprogramming abilities in a object oriented language. I haven't used Smalltalk, but I've done production code in C# and Java and whenever using them I always yearned to the metaprogramming abilities of C++.
Slowly but steadily I'm gaining ground on Lisp, so who knows, maybe lisp macros will satisfy this metaprogramming need in the near future :)
"I think I once managed to read all the way through Stroustrup’s The C++ Programming Language and have looked at at least parts of The Design and Evolution of C++. But I have never done any serious programming in it."
All I can say is, any programmer worth his mettle would make such a statement... Going through Stroustrups's book isn't possible if you're not interested in C++ programming (given that its not part of For Dummies series), IMHO. It is exactly like comparing it to a Novel. A programming guide is not about reading, its about learning.
I would describe it as Byzantine technology explained with an economy of words that approaches poetry, at least in the way you must ponder each sentence. And the exercises are stimulating, in the sense of a cattle prod. I enjoy that sort of thing, in reasonable doses.
Since then I've stayed away from C++ unless it's externally imposed, and built things with C and Python. I like a language whose basic features can fit in my small brain, a language that gets out of the way.
C/C++ are the base for everything you code today. People start learn how to code with languages like Java, jump straight into OOP. That's wrong.
Every developer should build at least a "hello world" in C, to know what's a real code. Ever developer must know about memory management, to scale optimize the code in any language. Other languages compilers do that for you, but you really need to know how it works.
Every developer should build at least
a "hello world" in C, to know what's
a real code.
I'm not following. Are you saying that "Hello World" is emblematic of "real world" C code?My opinion is that "Hello World" serves one purpose only in C, to show how much the C compiler agrees with the host OS.
Developers should know what's a pointer and how to deal with it, because this is what happens everytime you hit the 'Build and Run' in compiler or run your Python script.
And even a hello world in C can show all of that.
And since when does writing "Hello World" in C teaches you how to use pointer and how to deal with it.
Because if you don't even know the most basic things like the stack and the heap and memory addressing and the mechanics of calling functions, how can you expect to be a "developer"? Fine, let people start learning with languages that abstract all of that away, but for a well-rounded, complete education as a programmer (I'm not talking school-eduction, I'm talking general education) you need to know about these things.
People have disliked C++ long before those languages existed or became popular. A lot of people who have written and maintain large C++ code bases will tell you straight up that they prefer C to C++.
A lot of people who have written and maintain large C++ code bases will tell you straight up that they prefer C to C++.
Perhaps that's the problem right there. As someone who has written a lot of C++ for quite some time, the most nightmarish aspect tends to be working with antique codebases.The way people program in it has changed drastically over the last ten or so years. It's possible to have a reasonably painless experience with modern C++ that is pretty much impossible with codebases with significant history.
A lot of that is because the compiler support simply wasn't mature enough, so people did what they had to do to ship. If all you're dealing with is old C++ code, it's extremely easy to find that you prefer coding in C rather than C++ (which is almost what that old code really is).
I'm maintaining a C++ web application written 12 years ago. It's not pretty. I cannot describe the difficulties even an experience C++ developer would have in trying to understand and maintain it.
Fortunately modern C++ is pretty good. We've managed to tack on a legacy compatibility layer via the Boost libs to give us a Python wrapper. It's still running in production and is still pretty useable.
However, C/C++ still requires a fairly high cognitive load for a diminishing return, IMO. There are other languages that are easier to understand and maintain whose implementations are getting increasingly better at competing in areas where C/C++ used to be the go-to choice. There are simply fewer cases where I will reach for C++ these days where it used to be the only choice.
I'd just say that it's not the language that rots, but the libraries, and preexisting code. There are still some areas where C++ is a good choice, but for things like a webapp, there would have to be a really compelling reason to choose it.
EDG was the first front-end to really get solid. Then Visual C++ got its act together and started releasing highly standard comformant C++, and then GCC did.
Now if you're writing standard compliant C++ it will likely work on the big 3 front-ends.
With that said there are some complexities in C++, but fortunately you can largely be oblivious to it until you need to use them.
Crockford correctly points out that Javascript has a very solid core. C++ shares that. With that said, I still prefer not to program in it... Just not a fan of non-GCed languages for the most part.
A language is a means of communication, and C++ fails miserably at that.
Don't take this the wrong way, but programming isn't for everyone. For some of us, it's in the blood. It's what I do during the work week and on the weekends for fun too.
Your complaints are valid of course, but take a look at all the systems developed for boilerplate elimination. I have used preprocessor metaprogramming, template metaprogramming, and "external Ruby script" metaprogramming - sometimes all in the same project.
But it's not everyone's cup of tea.
Some people swear by Python.
I still code, but it's not what I do for living, and incidentally, I do enjoy using Python (and also Scheme)!
I really fell in love with the cleanliness and simplicity of Lua for a bit there. Used it to prototype stuff that I'm not rewriting in C++ with great pain. I sure would benefit from having a good debugger though.
You can do procedural, functional, OOP, generic, template meta-programming etc. It has something for everyone and does not try to force anything down your throat. That is why I love it.
I use it daily and am very productive with it.
Edit: grammar
It forces me to relinquish a host of assumptions about most programs. This is a huge source of bugs.
> I use it daily and am very productive with it.
Meaning, you write lots of code? Or you solve lots of problems that weren't introduced by C++ in the first place?