Fighting the Culture of 'Worse Is Better'
An anonymous reader writes: Developer Paul Chiusano thinks much of programming culture has been infected by a "worse is better" mindset, where trade-offs to preserve compatibility and interoperability cripple the functionality of vital languages and architectures. He says, "[W]e do not merely calculate in earnest to what extent tradeoffs are necessary or desirable, keeping in mind our goals and values -- there is a culture around making such compromises that actively discourages people from even considering more radical, principled approaches." Chiusano takes C++ as an example, explaining how Stroustrup's insistence that it retain full compatibility with C has led to decades of problems and hacks.
He says this isn't necessarily the wrong approach, but the culture of software development prevents us from having a reasoned discussion about it. "Developing software is a form of investment management. When a company or an individual develops a new feature, inserts a hack, hires too quickly without sufficient onboarding or training, or works on better infrastructure for software development (including new languages, tools, and the like), these are investments or the taking on of debt. ... The outcome of everyone solving their own narrow short-term problems and never really revisiting the solutions is the sea of accidental complexity we now operate in, and which we all recognize is a problem."
He says this isn't necessarily the wrong approach, but the culture of software development prevents us from having a reasoned discussion about it. "Developing software is a form of investment management. When a company or an individual develops a new feature, inserts a hack, hires too quickly without sufficient onboarding or training, or works on better infrastructure for software development (including new languages, tools, and the like), these are investments or the taking on of debt. ... The outcome of everyone solving their own narrow short-term problems and never really revisiting the solutions is the sea of accidental complexity we now operate in, and which we all recognize is a problem."
is a blogger who thinks about stuff and posts it "news"?
This sounds a lot like the mantra of the FreeDestkop.org folks and/or Redhat with the "moving Linux into the 21st century". I'm not going to call it a 'planted' article, but you know.
There's a difference between linking C libraries (Many non-c++ languages can do this) vs Stroustrup's insistance that a c++ compiler must be able to compile C code. this requirement is one of the reasons C++ is such a mess.
Back in the day. The clue is in the name. If it wasn't compatible but simply similar then it would have been called something else. Java perhaps.
C++'s strong compatibility with C was one of its strongest selling points relative to other object oriented languages back in the '80s.
And that compatibility still is important today. For one thing, APIs can be written in C (starting with the POSIX API) and be used by programs written in either C or C++.
Here's an idea: if you don't know shit about C++, don't post shit about C++. Save your precious insights for systemd maybe?
It's easy for a programmer to say "We should stop worrying so much about compatibility and interoperability" when they don't have to deal with customers, support, or actually selling the end product. When a customer calls up and says, "Hey, how come this new version of Windows doesn't work with any of my old Windows software?" you can't just tell them "Because our programmers thought it was better to get a fresh start."
SJW's don't eliminate discrimination. They just expropriate it for themselves.
Obligatory XKCD
SJW's don't eliminate discrimination. They just expropriate it for themselves.
So.. preserving backwards compatibility and interoperability across versions is a bad thing? If he's unhappy with the feature set of C++ (and I wouldn't blame him for that), then how about simply picking up a different language instead? That's what a new, non-compatible C++ version would be in any case.
Look at how great it has worked out for Python. It's been six years since the only mildly incompatible version 3 was released, and it has still not managed to become dominant over the legacy version 2. A more radical break would almost certainly have had an even tougher road ahead.
Trust the Computer. The Computer is your friend.
Seems like someone (or a consortium of someone's) should take C++, drop the C compatibility requirement, make whatever "cleanup" changes that allows, and call it C+++. Just make sure there's a module ready to go for gcc.
...which hasn't been the case in a long time.
/* correct C, incorrect C++ */ /* correct C, incorrect C++ */
Pulling two examples out of my ass:
int *foo = malloc(sizeof *foo);
and
int bar(void);
C++ and C are two different, incompatible languages.
CLI paste? paste.pr0.tips!
"Technical Debt is a thing, people"
I never heard the term before, had to wiki it, then realized it was a fundamental of software engineering that I was taught decades ... ago :( so old
Don't create app functionality that the user won't use. More bells and whistles mean more dev time, test time and more to maintain, it's a simple concept.
That's why apps now have functionality metrics (Firefox seems really big on it for example).
Sig. Sig. Sputnik
Worse is better is basically the KISS principle for software. C++ is not an example of that, but C is. This guy is an idiot.
This is my signature. There are many like it, but this one is mine.
.
So he thinks that compatibility and interoperability are not features which he likes. OK, I'm OK with that.
However, that is his opinion, nothing more, nothing less.
There are reasons why interoperability and compatibility are desired. It is not the easiest path to provide those characteristics, on the contrary, it is easier to just say, ~screw compatibility, screw interoperability~, and you'll probably finish your task more quickly.
So then the question becomes, why do people invest extra effort in order to assure interoperability and compatibility?
...which we all recognize is a problem....
And now he presumes to speak for everyone....
Overall it sounds like he just got out of a bad meeting in which someone told him that his opinions are not worth the air used to utter them, and now he's trying to convince the world that he is right and the world is wrong.
And that compatibility still is important today. For one thing, APIs can be written in C (starting with the POSIX API) and be used by programs written in either C or C++ or in language X, or language Y, or language Z.
FTFY. This is due to calling conventions, not due to a 'language compatibility'
Here's an idea: if you don't know shit about C++, don't post shit about C++?
Here's an idea: If you don't know shit about the basics of programming, don't post, like, at all. Especially avoid calling others idiots when you're at the same time making clear you're even less competent.
CLI paste? paste.pr0.tips!
Sacrificing backward compatibility and interoperability for radical changes would lead a large population of rapidly mutating code and runtime environment. You see this both in biology and software. Malware proliferates, ditches backward compatibility and interoperability and tries to adapt as quickly as possible to exploit newly discovered vulnerabilities. Giant organisms and big pieces of software change slowly, spend enormous amount of energy and effort in maintaining a thriving eco-system.
Radical changes (saltations) has its advantages but also limitations. Slow incremental changes has its limitations but also advantages.
sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
Once upon a time, I wrote "clever" code. Truly beautiful, almost poetic in its elegance. Note I said "elegance", not "simplicity".
I don't know who to credit for this (probably read it on Slashdot), but a single perspective completely changed the way I view coding:
It takes substantially more effort to debug than it does to write code in the first place. If, therefore, I write code as clever as I possibly can - I can't effectively debug it (without investing far more time than I should) if something changes or goes wrong.
Now, that doesn't mean "worse is better"... I can still produce good code; I can even still write the occasional clever function when performance demands it. But for the 99.9% of code that has almost no impact whatsoever on performance, I can just say "if X then Y else Z" rather than using cool-but-cryptic bitmasking tricks to avoid executing a conditional instruction. And hey, whaddya know, I can actually read it at a glance six month later, rather than praying I didn't forget to update my comments.
On the flip side of this, a few weeks ago I helped a friend put together a spreadsheet with a few complex formulas in it. I love me some IFSUMS, arguably the best new feature of Excel in the past decade. Note that clause, "in the past decade". This weekend, she called me because her nice helpful spreadsheet wouldn't work - On Excel 2003. It seems that while 2003 has IFSUM, MS didn't add IFSUMS until 2007. The choice of one seemingly harmless backward-compatibility-breaking function made the whole thing useless in a given context. Now, in fairness, I can hear you all screaming "just upgrade already!"... But in the real world, well, we still have people using Windows 95.
Wrong.
C++ has zero problem dealing with structs as function parameters (usually pointers to structs) which have arbitrarily complex internal structure, including embedded pointers. Since C does not provide OO encapsulation, it is often useful for calling code to manipulate pointers directly.
In Perl, you've got to wait until someone provides a binding for these complex cases... or, yeah, "why don't you do it yourself? It's open source."
I think the author's original focusing on C++ as an example of "worse is better" is a sad distraction. Clearly C++ was designed with the goal of being compatible with C. There are plenty of examples of languages which attempted to solve object-oriented programming but threw away backwards compatibility as a design goal: D, Java, and C# come to mind.
That said, I think he does have an interesting point about our unwillingness to sit down and carefully consider our response to problems as they arise during development--that we are constantly chasing incremental changes without considering the technical debt that arises. I've seen it particularly inside many of the companies I've freelanced to; they consider their software an asset rather than a depreciating liability, that must be preserved at all costs--even if that cost is increased technical debt that makes maintenance nearly impossible.
But the real source of the problem, in my opinion, is not a culture which thinks "worse is better." It may appear that way, because many companies engage in tradeoffs which, to the casual observer, seems like they really consider "worse" as "better." The real problem is that many corporations and many organizations don't necessarily reward competence, because they are often run by the incompetent. The Dunning-Kruger effect extends beyond self-assessment. Thus, they treat software as an asset rather than as a depreciating liability: management is unable to properly assess their internal processes and the value of the result. All that work, and we're supposed to throw it away?
The scary part is that to many of the organizations I've freelanced to, too much competence creates organizational friction. The places where I've done work who've ranked my work the best are exactly the places where I've "phoned it in", so to speak, only going a little bit above the call of duty. Go too much above the call of duty, pause everyone to have a considered response and to carefully do what is right, and you find yourself up against very powerful forces who, thanks to their inability to self-assess, push back hard.
So Paul, is this a plug for your book or yet another argument for functional programming?
Not much useful information or examples as to why or where "Worse is better" is harming the world of computing. There is always a better tool to help solve a problem. But for many reasons they may or may not be appropriate. You the programmer should know when and where to use them.
One of my favorite quotes (the bold text at the end is the good part):
That applies to not only Unix and operating systems but any tool that is made to solve a problem. Just replace the word codebase with the tool name of choice.
I think we are seeing fresh starts. We've seen a shift away from desktop applications towards web as a common framework, that's become remarkably more useful. And now we are seeing moves towards mobility. Both web and mobility have forced a genuine separation between view systems and business logic that in the desktop world was a goal often not met. Then with the rise of devops architectures are becoming even more factory component where the parts are interchangeable and thus design mistakes can be corrected.
In terms of the languages themselves as fewer of the languages outside view languages need to be performance front ends, nor need to have a broad audience they've been able to specialize into particular domains. So if anything I see the opposite.
The author if this article is a Scala guy. Scala is architected the key compromise of free intermixing of imperative and functional code so that programmers don't have to cross the conceptual barrier switching to functional. Which means that it effectively introduces programmers to functional concepts at the line level but not the program design level. It is really an imperative language with lots of functional data manipulation structures you don't see the full power of functional. It is hard to think of a language which more directly followed in C++'s footsteps of bolting object-orientation onto C, then Scala which bolted functional onto a Java type language.
Does anyone have any idea of the hacks he's talking about?
Since C++ is intended to and has always been a superset of C, how could there be any problems and hacks caused by compatibility with C? How could it be any better by discarding part of the language itself?
A problem I've been seeing lately is that everyone seems to think software is carved in stone. In the past 3 or 4 years I've heard a LOT of excuses why some flaw in one system or another made a feature impossible. In these cases, fixing the flaw would be pretty trivial. Instead of doing THAT, people just build another layer of crap on top of the previous layer of crap and try to kind-of get something working. Code is not immutable. If it doesn't do something you need it to do, MAKE it do what you need it to do. Write a library, redesign a layer, simplify an interface, whatever. Don't just wring your hands and make the problem worse! Code is made to change. No design is ever perfect right from the start. If you try to make your design perfect from the start, you'll just end up paralyzed, afraid of doing anything because you might do it wrong. Start with a design that seems reasonable and adjust it as needed. Write small, decoupled libraries that can support that, and write unit tests to insure that each component behaves as expected. It's really not that hard, people!
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
Worse is better, or interoperability, is often mandated at the behest of the customer who often doesnt understand what theyre really asking for and its context. Customers dont understand that interoperability and compatibility fundamentally alters the scope and performance of a project. Often legacy features get included at the request of PHB's that become stakeholders out of fear, meaning feature X is only included because some irrational end user doesnt want change. Healthcare records are an excellent example as the driving force for their presentation and feature set are a typically a group of elderly physicians who just want what theyre used to using without the inconvenience of losing face over a technology they dont understand. Banks command interoperability and compatibility for different reasons, mainly because financial systems are predicated upon very basic yet powerful and secure mainframe systems that arent negotiable for upgrade.
the sad solution is to learn the objective of the application, ignore the customer, and focus on training after the system is developed. Work inside the maintenance cycle of the programs existence to identify flaws, but try to restrict increases in scope and vigilantly fight back against changes that are pedantic and clearly for the benefit of a single individual or flawed process.
Good people go to bed earlier.
worse is worse is the problem.
worse is better: a bunch of lisp/haskell weenies complaining that people use C
worse is worse: node.js
Copyright (c) 1990 - 2014 Dice. All rights reserved. Use of this comment is subject to certain Terms and Conditions.
How did breaking compatibility worked out for python 3?
I don't see what a compiler's ability to do with other formats/languages has to do with a different format/language.
GCC can compile fortran, and that has nothing at all to do with C++.
For large sets, this will be our guide even unto death, for the LORD will work for each type of data it is applied to...
I would assert precisely the opposite. "trade-offs to preserve compatibility and interoperability" do not cripple the functionality to users-- failures to engineer compatibility and interoperability is what cripples functionality.
The number of times that there's been a new feature and I've said "oh, excellent, it's true that my old files no longer work, but this is so wonderful I don't care" has been very close to zero. The number of times there's been a new feature and I've said "those assholes, I have twenty thousand files that don't work any more, what in the world were those idiots thinking?" is decidedly not zero.
http://www.geoffreylandis.com
If being perfect means not having critical core features then you're confused about what is and is not perfect. Compatibility is important. In many applications it is vital. Period - end of story. Does maintaining compatibility make the project more complicated? Yep. Coding is hard.
Next issue.
I've decided to stop wasting my time responding to AC trolls/sockpuppets... so if you want a response from me... login.
And yet C++ is not a strict superset of C and thus compatibility has been broken for decades anyway. Meanwhile ObjectiveC, which did keep to a 'strict superset' pattern has remained a pretty clean language. The problem with C++ is not C compatibility but of trying to keep expanding it to include new and incompatible patterns or indecision regarding which patterns to use. Stoustrup wants C++ to be the mega language including all features of every other language, THAT makes it a mess.
I am kinda with you on that 'actual problems' issue. C++ would be a good language if they focused on minimal changes that address real issues instead of designers seeming to add stuff for the sake of designing. Maintenance is never sexy I guess.
Interoperability is king.
I don't care how awesome your new application is, if I can't get my data into it and out of it, it's worthless to me. I've been down this road. If I have to start a massive project just to start using your application, or plan for a massive one to stop using it, that's a cost to me... a big one. And if my people have to go to training just to be able to use it because you didn't want to bother meeting a standard... or I have to hire people strait out of college? Again, that's a huge cost. If your application is 10% slower because of interoperability, even that's inconsequential... I can order server cores off the internet, it's not that big of a deal. Got an idea for a new feature? Great! But if you can't get that feature to work inside the existing standard, you don't have a new feature. There's likely a reason it's not allowed.
Ordinarily, it doesn't. But the thing is, there are two things called GCC: the GNU C compiler (which handles C) and the GNU Compiler Collection (a set of compilers which, though they share the same backend, are still separate entities).
GCC, the C compiler, cannot handle Fortran. GCC, the set of compilers, can handle it via g77 (the old compiler) or gfortran (the new one), but the C compiler can't. This is considered the traditional way of doing things.
What makes C++ different from many languages is that its maintainers insist that C++ compilers must be able to handle C code. It's not enough to have a different compiler in the set, the way GCC does: it must be doable with the C++ compiler itself, in the same application. And so g++ can do it too, because that's what the standard requires of it.
That's what makes the difference. Ordinarily, as you say, a compiler's ability to handle multiple languages shouldn't affect any of the languages in it. But C++ was defined in a way that not only makes those effects possible: it makes them mandatory.
If you don't like the mess in C++, find a better language and use that. C++ is actually the most popular language for performance-critical code? Hm, I wonder how that happened? Because of or despite its C compatibility?
The world is full of bad technology that is popular because its version 1.0 was really popular at the time. The fact we still use all of it says something about the market for technology; apparently, backwards compatibility to a fault makes for more long-term popular systems than do-it-right-this-time. It is, unfortunately, the way of the computer industry. Or fortunately, if you need a job.
I sometimes ask revealing, often ignorant-seeming questions. Maybe they're harder to answer than you think.
OK, so we can't give the tasks to fresh recruits. So we give them to people who have 5+ years with C++. What happens when those people disappear? What happens when you can't find enough engineers anymore with the kind of experience? How do you get from zero knowledge to competence in not blowing up C++, if not by actually blowing it up a few times?
I sometimes ask revealing, often ignorant-seeming questions. Maybe they're harder to answer than you think.
It's a combination of 'Standards are never finished being implemented' combined with features never being explicitly declared.
Both C and C++ have been hobbled for years not by their backwards compatbility, but rather than features that are intentionally ambiguous or undefined because those are 'Implementation specific details', without regards to the effect of those lacking declarations effects on both cross platform compatibility as well as auditability of the resulting code. If there is no guarantee as to the functional equivalency of code produced by two compilers on the SAME arch (nevermind on different ones) how can you expect there to be the opportunity to 'start over' by dropping legacy support without a stable and documented legacy codebase for the new designs to be developed on?
Just as an example: Look at K&R, ANSI, C90, C14, etc. Many of these standards were never fully implemented in any particular compiler. K&R was supported in early gcc releases but deprecated and then dumped in gcc-2.95->early 3.x releases. Many of the later releases break features of the earlier ones piecemeal despite the original standard never having had a 'stable' release that could properly generate code for all applications (While rare, there are still many corner cases, even in perfectly 'valid' C programs that thanks to developer error, or mistake implementation of standard features resulted in code generation bugs. Some of which weren't fixed before a standard was deprecated or altered for compatibility with C++ for instance in a manner that broke a formerly 'conforming' application.)
Point being: Lots of compatibility has been thrown by the wayside in the name of forward progress, but it hasn't SOLVED anything because nobody seems willing to bother taking time out from their new features to ensure a stable and standard complete/compliant codebase from which to iterate into the next generation. The result of this is a constant churn of mostly working code with all sorts of corner cases resulting in unexpected operation, security errors, or simply some 'end user' being unable to compile an old version because the new compiler can't bootstrap the old one, the old one requires since-lost voodoo to compile the new one, and the amount of work and digital archeology to determine what changed in the standards to make the old code properly operate under the new ones may not be worth the expense in time/knowledge to do so.
Apologies if this is overly verbose, meandering, or obtuse. I figure if nothing else this might provide a basis of concepts someone more articulate can turn into an acceptable discourse on the shortcomings of the 'development culture'.
I phrase I picked up years ago seems to apply here, 'standard is better then the best solution'. It is not a culture of 'worse is better', but of competing interests where the pure joy of developing languages is not the primary metric for determining what the best course of action is.
Without worse-is-better, you make sure the job is completely done before release. So, it takes years to make progress, you end up building an extremely complex system to cover every possibility. Because of that very complexity it is difficult to extend for new requirements, which become apparent after the system is specified and before it was built.
If you want to build a nuclear power plant control system or something equally as critical and unchanging, sure, go ahead and engineer everything out the wazoo. Otherwise, get things done, even if they are "worse".
I'm with you on this. As a programmer, the thing I hate the most is "Gee, Mom, look what I can do!" code -- obtuse code written to impress rather than be simple, obvious and functional. And yes there are indeed times when something mind-bendingly complex is needed to achieve the required goal, but by and large, the KISS principle applies. As to the article's main point, I have to ask what is the purpose of breaking backward compatibility: Making it faster to produce readable, easily maintainable code, being the first one on the block to use something new and shiny, or simply to appear to be one of the Elite? Always keep in mind, however, that programing is more an art than a science, and creativity often comes from the simplest of tools, not the most expensive or the trendiest. And creativity is why we fiddle with all these bits, right?
"My country, right or wrong; if right, to be kept right; and if wrong, to be set right." --Senator Carl Schurz (1872)
We had FoxPro 6 and Windows 98, when XP hit our desks, FoxPro no longer worked. They made me use (ugh!) MS Access.
So I have a few dozen Access apps when they "upgraded" to Office '03, and not a single one would run. Access had become a completely different program with completely different code and was completely incompatible with Access '98. I had to rewrite every God damned program!
OTOH the NOMAD mainframe databases seldom had glitches. I'd been a PC kind of guy, but NOMAD on the mainframe and Microsoft's stupid, anti-user bullshit started changing my mind.
Free Martian Whores!
So far, I don't think I've seen a single comment here that got the point of the essay.
He's not talking about incremental "improvements" to existing languages, he's pointing out that the common attitude of "we'll make this language easy to learn by making it look like C" is a poor way to achieve any substantial progress.
This is true but everyone who's invested a substantial amount of time learning the dominant, clumsy, descended-from-microcode paradigm is reluctant to dip a toe into anything requiring them to become a true novice again.
I've long been a big fan of what are now called "functional" languages like APL and J - wait, hold on - I know that started alarm bells ringing and red lights flashing for some of you - and find it painful to have to program in the crap languages that still dominate the programming eco-system. Oh look, another loop - let me guess, I'll have to set up the same boilerplate that I've done for every other loop because this language does not have a grammar to let me apply a function across an array. You want me to continue doing math by counting on my fingers when I've got an actual notation that handles arrays at a high level, but I can't use it because it's "too weird". (end rant)
There have been any number of studies - widely ignored in the CS world - going back decades (see this http://cacm.acm.org/magazines/...) - pointing out how poorly dominant programming memes mesh with the way most people think about problems and processes. Meanwhile, the 1960s called - they want their programming languages and debugging "techniques" back - "printf", anyone?
All of my competitors should adopt the author's philosophy of software development immediately. His ivory tower FP idealism is worthy of emulation by all.
I will keep muddling through based on years of experience, leveraging existing code and know-how, maintaining backwards compatibility, planning long-term changes that sometimes take years to complete, deprecating unneeded features in as non-disruptive a manner as possible. And then, when the opportunity arises to do something radically different (like with the C++ "auto" keyword), make it happen. We're called pragmatic programmers. We are clearly losers. Do not emulate what we do.
the growth in cynicism and rebellion has not been without cause
I would assert precisely the opposite. "trade-offs to preserve compatibility and interoperability" do not cripple the functionality to users-- failures to engineer compatibility and interoperability is what cripples functionality. The number of times that there's been a new feature and I've said "oh, excellent, it's true that my old files no longer work, but this is so wonderful I don't care" has been very close to zero. The number of times there's been a new feature and I've said "those assholes, I have twenty thousand files that don't work any more, what in the world were those idiots thinking?" is decidedly not zero.
And this is why there are so many programming languages with massive overlap in usage. Because once you start down a path, you can never, ever, everver change. If you want something that 42 years down the road that breaks with convention, go create a new language.
You can pick up C++ in a couple of weeks. Most programmers can. However, it takes years to become proficient in it. The same can be said for most languages.
That's Management's job. If they run a sweatshop that churns through brogrammers, then they shouldn't be using a dangerous language like C++.
There was a posting a number of months ago, where there was hand-wringing about bad Software Development Managers. Good managers hang onto good talent. They run a shop that attracts and keeps that talent. There's no "One Rule to Rule Them All" in good management. Different companies have different environments, different cultures have different expectations and drivers. Way too big a topic in the standard "C++ is the Devil" screed. Folks aren't interested in that stuff anyway. They just want to bang their own private drum about the language. Good management requires a level of "soft" thinking that seems to escape most commenters here.
If you are one of our competitors, then I heartily recommend C++ as a great learning language. You should use it for all your projects, and start off those bright, shiny new engineers on your core libraries.
Have fun!
If it didn't meet the requirement to be fully compatible with C, it wouldn't be C++.
Like the man says, you're welcome to fork a new language that's C++ without C compatibility. Frankly I don't see the point. If you don't need C compatibility there are far better OO languages than C++.
Moderating "-1, Disagree" is simple censorship. Have the guts to post your opinion.
Is it actually correct or is it "but gcc allows it anyway!"?
Either way, we might as well do it the other way around and consider int foo(); in C and in C++. In one of those languages, foo does take any arguments.
CLI paste? paste.pr0.tips!
The two languages are not incompatible
That's vague. The real question is whether C++ is a strict superset of C. Answer: it is not.
Some constructs valid in C are invalid in C++. Some valid C code is also valid C++, but behaves differently.
See Section 1 and Section 2 of this Wikipedia article.
Backward compatibility. Which btw Microsoft has broken a time or three.
To accuse the C++ community of not having engaged in "reasoned discussion" about backwards compatibility is silly. Chiusano may not like the tradeoffs that C++ makes (I don't), but they are the result of a glacially slow and tedious community process and discussions. Whatever C++ is, it is by choice and reflection. Furthermore, "worse is better" refers to keeping things simple by cutting corners, and you really can't accuse C++ of keeping things simple.
(Charges about too much backwards compatibility are ironic from someone who promotes Scala, a language that makes many compromises just in order to run on top of the JVM and remain backwards compatible with Java.)
Have gnu, will travel.
I found that I can determine how bad a programmer is by how much he hates C++. There is a direct correlation. If you hate C++ or find it difficult to learn, there are many job opening for janitors.
Clojure should solve the problem of using too much stack through recursion by properly impelementing tail-recursion. When writing recursive functions, the programmer should always write the function so that it can be "properly tail-recursive". If not, you are saying at the outset that you are creating something that will use unbounded memory to do a computation that *could* always be done in a fixed memory size. Writing a recursive function that is not properly tail-recursive is simply bad programming and an anti-pattern. Either refactor the algorithm into something iterative or make it properly tail-recursive. Then, the max stack size will never be an issue.
Backwards compatibility is a good thing, but too much of it can be bad. There are glaring errors in languages which have not been fixed in the name of some faux backwards compatibility argument.
I'll start with one that was fixed.... thirty years after the fact, all the while arguing that it couldn't be fixed, in the name of backward compatibility. The example? ANSI C gets the right answer for sqrt(2) while the original C didn't.
An example of things that C got wrong and have yet to be fixed? the bug inducing = assignment operator, the lack of arrays bound check and the completely unnecessary and time wasting #include <stdio.h> at the beginning of every program.
Observe that those glitches were blindly copied by most C language derivatives (C++, Java, C#, Scala).
I'm not a big fan of Go, but at least if goes back to the := assignment operator.
Try compiling this as both C and C++. It's completely valid in both languages, but the output will be different in each.
I am TheRaven on Soylent News
The outcome of everyone solving their own narrow short-term problems and never really revisiting the solutions is the sea of accidental complexity we now operate in, and which we all recognize is a problem.
It strikes me that this describes our economic system as well.
"What the American public doesn't know is what makes them the American public." -Ray Zalinsky (Tommy Boy)
No need to get all twisted up over quality and function. I was just on a major health insurance provider website and it's seemingly unable to produce lists of providers nor even display the right coverage that I have or even the plans I signed up for. But luckily logon was a bitch and the whole thing is clunky slow.
I think we're going with shitty is good enough, and if it's not, then fuck you anyhow.
I can answer these, as I was there.
"Hey, how come this new version of Mac OS doesn't work with any of my old Mac OS 9 software?", said Mac users in response to Classic support being dropped with the release of Mac OS X 10.5.
Because Apple was unwilling to port the Classic 68K emulator to Intel because of the difference in processor byte order, among other things, making such a port not worthwhile in terms of performance of the Classic software. The user experience would have been crap, and so the decision was made by upper management to not support Classic going forward on Intel.
For the PPC versions of Classic, they could have been supported under Rosetta, but it would have meant an approximate doubling of the number of APIs that were dragged forward onto Intel, for the dubious benefit of "Some Classic software will run, and some won't; sorry the stuff you personally care about doesn't".
"Hey, how come this new version of OS X doesn't work with any of my old PowerPC software?", said Mac users in response to Rosetta being dropped with the release of OS X 10.7.
This one was more related to the lack of a willingness to "freeze-dry" old versions of the libraries. The Mac OS X B&I ("Build and Integration") process required building from scratch the libraries, when building them fat, even though this was a process decision, rather than a technical one.
Effectively, it's not practically possible within the Apple process to reproduce a binary build that's identical to a previous binary build. This is because Mac OS X builds are hosted on a system where the builds depend on being incrementally built into the host environment, rather than actually cross-built to the target. What this means is that the "build from scratch" process to produce the PPC portion of the fat binaries for all the system libraries couldn't be pegged at a particular Mac OS X version, while moving forward with the Intel portion of the binaries, and therefore it was not possible to maintain binary backward compatibility - which was what both Rosetta, and before it, Classic, existed to do.
Debian Linux has this same problem when you build in a chroot to avoid "polluting" the host build environment. It's one of the reasons a build chroot is used by Linaro to support ARM architecture builds on Intel, and that's the same reason that ChromeOS for x86 is built in a chroot environment on a debian variant maintained internally for desktops at Google, rather than being simply directly cross-built into a directory tree hierarchy.
Unlike FreeBSD, neither Linux nor Mac OS X is capable of targeted cross-builds, without pollution of the build/host environment, and without using build products as part of the build.
So technically, the answer for both Linux and Mac OS X is the same: poor build environment engineering - "Worse is Better", exactly what the original article talks about - infects both operating systems.
From TFA: "Other professions, like medicine, the law, and engineering, have values and a professional ethic, where certain things are valued for their own sake." Evidently the author is unfamiliar with common law, in which the law evolves over time via practical application, much as programming languages evolve and mutate. This is contrast to statutory law, which is created from whole cloth, much as one might create a new programming language which has roots in other languages but is fundamentally different from any of them.
If the analogy is apt, "warts" presumably appear in the law. Lawyers, judges, or legislators might wish to remove them. However, practical considerations such as disruption of some existing body of law might prevent that. Also, warts are, by definition, subjective. So, one man's wart might be another man's treasure.
Going back to programming, the use of pointers in C++ is both a wart inherited from C, and a useful feature that can't be removed without fundamentally changing the language. Thus, we have C++ templates for smart pointers, which seek to ameliorate the wart without actually expurgating it.
It's idiomatic in a C++ header that uses extern "C" { ... } to define an interface to be used by both programs written in C and programs written in C++. (When the properly constructed header is included in a C program, the preprocessor eliminates the extern "C" { ... } block.)
The problem is that you don't have to consider just benefits, desirability, goals and values. You have to consider the other side of the equation: cost. And for programming languages like C++, the cost of breaking compatibility can be huge. If you change C++ in a way that isn't compatible with existing behavior, you have to check every single program written in C++ for bugs, errors and just plain failure to compile anymore. The cost of that's going to outweigh just about any benefit short of "creates a literal Heaven on Earth for every single person in the world". It'd be simpler to create a new language based on C++ with the desired changes made to it, which is what tends to happen. The same applies to software frameworks and architectures.
"I wandered off or a while and when I came back they'd added the STL,which provided some badly-needed data structures and language capabilities"
Most of the common STL containers would be a few hours work to write something reasonably functional. Binary tree maps perhaps a day to get working properly but nonetheless, nothing a competetant programmer couldn't do. In fact this was done in C for years without the STL so your complaint is a bit weak.
Is it actually correct or is it "but gcc allows it anyway!"?
Yes.
Judging by the output of the UX crowd over the past few years, they actually seem to believe that worse is better. It's kindof funny seeing him arguing against the proposition.
In contrast, Objective-C is a superset of C (all the new stuff is embedded in things that are syntactically incorrect in C). There's advantages to both approaches.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
Not all C++ compilers handle all C code. Visual C++ never did fully implement C99 (Herb Sutter, in charge of Visual C++, said that those looking for a C99 compiler for Windows should go elsewhere). Since C and C++ are so similar, many implementations will compile C code if presented as C code, for convenience.
This is NOT part of the standard. The standard lays out what a C++ implementation must do, and compiling C programs is not one of them. Many C programs are also valid C++ programs that do the same thing, so those must be compiled. There is a standard way to say that things should be compiled in a way compatible with a C compiler (C has a de facto ABI, unlike many languages). There is no requirement that a C++ compiler compile a C program that is not valid C++.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
The best attempt at C++ - C I've see so far is D.
"When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
And D's "broad adoption" should tell you what value folks place on removing C from C++.
Moderating "-1, Disagree" is simple censorship. Have the guts to post your opinion.
Almost all the hacks imposed on C++ to remain compatible with C are linear hacks that don't combine combinatorially. That's what makes these hacks ugly: bending over backwards to achieve hack containment. The C++ standardization literature contains many of the fiercest debates ever waged among pointy hats concerning hack containment. Purity wasn't an option. Impurity segregation was.
The hacks in C++ that do have combinatorial complexity pertain to features of the C++ language completely unrelated to C, such as templates and namespaces.
The bending over backward to avoid non-linear hacks due to compatibility with C got the standards committee into a wee bit of time pressure. Both the template and namespace features were added "on the fly" against the stated policy of the standardization group to only standardize after there was enough experience on the ground to avoid the worst mistakes.
If the standard isn't finished on a timely basis: market fail.
If the standard is finished without templates and namespaces: paradigm fail.
If the standard makes blunders in defining templates and namespaces: an eternal witch's brew.
The committee members rather sanely (and unhappily) chose the least of several competing evils.
There's never been a language like C++ to get otherwise smart people to say stupid things.
* C++ contains many ugly hacks due to its C legacy
* most ugly hacks are combinatorial
* C++ contains many combinatorial hacks
* therefore C++ is riven with combinatorial hacks due to its C legacy
Yes, but the ugly hacks to support C are not the combinatorial hacks, and the combinatorial hacks to support templates and namespaces before their time are not the hacks to support C.
Of course, if you don't delve deeply enough to figure this out, one might just conclude that C++ was concocted by a brigand of insane ideologues. You'd be stupid and wrong, but if your surround yourself with an echo chamber of the equally lazy, there's hardly any detectable social downside (near you).
There's remains, however, this irritating tendency of the world around you not to adopt your favourite "clean" language and put C++ out to pasture once and for allâ"due exclusively to inertia, incompetence, and mendacity. Of course.
The next rank of fierce debate during standardization concerned the elimination of all proposed features where adopting the feature imposed a performance penalty across the board even when it isn't used. A few performance points here and there on a heavy-lifting, industrial programming language quickly adds up to entire data centers. Elegance was never a sufficient argument, unless the performance tax imposed was—at most—barely measurable.
Elegance looks like such a great thing until one begins writing an application at industrial scale. The hacks inherent in making any computational system work efficiently on industrial scale (with smooth degradation around the edge cases, and no crippling instabilities) instantly dwarfs the hackishness of the C++ language itself.
Neat, but what's the problem? The code is valid in both languages and the output is correct in both cases.
And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
scroll, scroll, "lisp", back.
We love standards. We have at least two for everything.
There's no time like the present. Well, the past used to be.