I might have written too much about the languages I intended just to bring forward as example.
D is not high-performance (I clarified that in the post) the same way as C and C++ are not. They are not meant for HPC, they are meant to be "systems" languages.
The difference between the two is that HPC is usually about parallelism and has always been. Instruction level (SIMD and GPUs), threads, clusters and so on. D is a bit better than C++ as it at least standardizes SIMD a bit, but still IMHO it doesn't qualify as HPC.
C++ adopted threads only in 11, doesn't have SIMD, doesn't know about GPUs, it got "restrict" only in 11 as well and so on and on. It's clearly not for HPC.
For a start most traditional HPC is done not via threads but via IPC. He's now not talking about languages but their libraries / platform offerings. Just because it is in the c++ stdlib doesn't mean you couldn't do it. Indeed the only reason it has been integrated into the standard platform the language offers is because it was proven over many many years as an external library.
To both comments - it's not JUST because the lack of threads, don't take an example as the entire extent of the critique. It lacks threads. It lacks SIMD. It lacks control over pointer aliasing (restrict), something that FORTRAN did right decades before C++ and C is doing today but C++ still lacks, and it's quite fundamental to write high performance kernels. It does -NOTHING- of the things that are needed for performance, all these things had to be added by custom compiler extensions because it's a popular language and we have very, very good compilers, but the language standard itself lacks in a lot of ways for HPC
Fortan is -undoubtedly- thought as a HPC. That doesn't mean it's great or I would use it today, but yes, without a doubt it is one of such languages.
That's not to say that if today I had to write, as I do, a tight CPU kernel, I would not chose C or C++, these have the best compilers and tools and are more general languages.
But C++ was never designed to aid stuff like numerical computation, never. It was designed to be zero-overhead on top of C if you didn't use any feature with overhead. That means that it can go all the way down to C performance, and C is considered almost as a portable assembly, so it's quite low-level.
Low-level and high performance are not entirely the same thing!
In fact you can easily, easily outperform -standard- C++ in many interpreted languages that support vector operations or GPU offloading, for example matlab.
If you want a c-like cpu hpc language for tight numerical kernels to integrate with c functions, look for Intel's ISPC
The lack of GPU support is indeed widespread and really quite forgivable today. Threads, SIMD and restrict are not.
And you're right about C++11, my bad. It's funny how C is actually pioneering a lot of the changes actually required for performance while C++ thinks about standardizing Cairo for 2d graphics...
Probably the strongest point of C++, besides its performance, is its ability to interact with C easily and efficiently.
A huge amount of C++'s complexity comes from this requirement, but the benefits are enormous. It's such a big deal that MS eventually just started recommending people use C++/CLI to interop with C instead of using the usual C# Interop methods.
Too many people underestimate the extreme advantages that are still gotten today by that requirement.
The rest of it, yes, you could, but not that specific requirement. Doing that efficiently and easily enforces certain restrictions on the language, and the underlying runtime.
I actually think the strongest point of C++ is the nature of how template metaprogramming is done. Is there any other language that competes with C++ as effectively with templates? I feel like all these "C++ is bad" comments and articles are from people who've really only scratched the surface in C++. The expressiveness that's available to a programmer using templates in C++ is, to me, quite awesome.
C++ actually allows for type abstraction in a way that most mainstream languages don't.
There's definitely an argument for the expressiveness of the language, but what you're talking about is more of a mechanical aspect of the C++ language itself.
What I'm talking about is more about the usefulness of the language in a practical sense, not what it allows you to express.
Yeah, but, the usefulness is a function of the expressiveness.
The reason I picked C++ templates in particular was because they allow you to make very effective use of information at compile time. Other languages, at least in my experience, don't give me ways to really tell the compiler (or interpreter) my intentions as effectively as C++ allows me to when I'm using template metaprogramming. So, to that effect, C++ is superior on top of just C compatibility.
... Not that any of this takes away from your original argument.
The question you should ask yourself is - what other languages I do know to compare C++ to?
Do you know about hygienic macros in scheme? Standard ML parametric polymorphism? Haskell type classes?
But even more mundane stuff like D's templates? Code-generation and reflection in C# (not to mention generics)? Scala's generics and parametric polymorphism?
In fact I argue that a strict C++ replacement won't really cut it. But it's very wrong to say that "you'll end up with the same complexity and rules as C++", that's the justificationist argument that says that C++ is the way it is because given its goals couldn't be any better. And D is there to prove that line of thought UTTERLY wrong.
The idea that OOP is a fad and that everyone is abandoning it is... absurd. I think that the author thinks OOP means ObjectListenerBuilderProviderFactoryAdpterImpls and repeated use of words defined by Gamma et al. Actually, OOP is just the practice of encapsulation and abstraction, and the avoidance of globals/singletons* in favor of infinitely instantiable instances. These are not a fad, they are necessary components of all large-scale software.
The Linux kernel, which is entirely written in C, is a fine example of object-oriented programming. File descriptors are object references. The filesystem is a beautiful heirarchy of polymorphic nodes. There simply is no non-OOP way to implement these things.
Neither debug logging nor any other unique system resource has to be passed as a singleton. All that is needed is the appropriate ApplicationContext structure to be passed to each object that needs these facilities, and the ApplicationContext will contain all the singleton instances that are required.
Yes, you can do that, it just gets tiring, because now you have a boilerplate parameter being passed everywhere. It really has to be passed everywhere, because you never want to get stuck without the ability to debug some function just because you didn't pass in the debug logger object.
The environment pattern effectively makes this context implicit.
> There simply is no non-OOP way to implement these things.
Depending on your specific definition of OOP.
I suspect what the author is talking about is the high level of coupling that occurred in a looooot of 90's/early 2000's codebases. It was a time of learning for many many people, but our industry as a whole, and the C++ community specifically, has learned a lot from those mistakes.
There is an appropriate application of almost any tool, what's wrong is the hype behind certain ones. By abandoning the fad I don't mean that now everybody will never use OO again, but that OO had become the -default- paradigm for -everything- (even the only one that gets taught nowadays), which is completely utterly bullshit.
Tremendously insightful post. Sometimes the writing is a little rough ... don't let that fool you.
Ultimately, I think he's right: what we need is to be able to invent and use high-level languages and DSL's that are wonderfully expressive for our domain (with fast iteration and all that), but also to be able to control the low-level run-time code that gets executed as a result, so it can be fast and efficient.
That's the holy grail as I see it. And LLVM is a key contender to provide the backend of that vision. (TFA talks about a lot of other things, but this is pretty much how I interpreted its conclusion, and I agree).
(Repost) Really we should stop talking so much about tools, and what tool/language/ide/whatever is best. Many years ago people didn't have half the tools we have now, and they still did amazing things. Most of what we have today is very good already. IMO focus on building products, not on bashing the tools.
checkout http://prog21.dadgum.com/51.html
Seems like a big whine. Every time I read one of these, I see a few good points, but then I think to myself "I wonder what they are programming in".
I then wonder how long it will be before they get upset about some feature they consider to be inelegant and try to find the next fad or old language they had previously discarded.
I really wish people would stop doing this. They like to tear down, without really building anything! It's sort of a whinge to tear things down without really understanding why certain concepts or ideas were invented. Kind of lame.
Really I don't often use classes, unless they are providing a benefit. Just using them to group some state with some functions is not great because they have lots of drawbacks for that, I find an opaque pointer and C functions to be better at hiding implementation details and so on. I use classes basically when I need destructors and constructors, so for things that need to go in collections really. http://c0de517e.blogspot.ca/2012/09/follow-up-why-classes.ht...
39 comments
[ 3.0 ms ] story [ 84.1 ms ] threadhttps://news.ycombinator.com/item?id=7918768
https://news.ycombinator.com/item?id=7898113
Tl;dr: D: kinda cool, not enough though. Rust: kinda cool, not enough though. golang: kinda cool, not enough though.
Also how is D '''not a "high-performance" language'''?
D is not high-performance (I clarified that in the post) the same way as C and C++ are not. They are not meant for HPC, they are meant to be "systems" languages.
The difference between the two is that HPC is usually about parallelism and has always been. Instruction level (SIMD and GPUs), threads, clusters and so on. D is a bit better than C++ as it at least standardizes SIMD a bit, but still IMHO it doesn't qualify as HPC.
C++ adopted threads only in 11, doesn't have SIMD, doesn't know about GPUs, it got "restrict" only in 11 as well and so on and on. It's clearly not for HPC.
> C++ adopted threads only in 11
Fair.
> doesn't know about GPUs,
Is there a general purpose language that has GPU support out of the box?
> it got "restrict" only in 11 as well
AFAIK, restrict is still not part of the standard, despite compilers implementing it.
For a start most traditional HPC is done not via threads but via IPC. He's now not talking about languages but their libraries / platform offerings. Just because it is in the c++ stdlib doesn't mean you couldn't do it. Indeed the only reason it has been integrated into the standard platform the language offers is because it was proven over many many years as an external library.
That's not to say that if today I had to write, as I do, a tight CPU kernel, I would not chose C or C++, these have the best compilers and tools and are more general languages.
But C++ was never designed to aid stuff like numerical computation, never. It was designed to be zero-overhead on top of C if you didn't use any feature with overhead. That means that it can go all the way down to C performance, and C is considered almost as a portable assembly, so it's quite low-level.
Low-level and high performance are not entirely the same thing!
In fact you can easily, easily outperform -standard- C++ in many interpreted languages that support vector operations or GPU offloading, for example matlab.
If you want a c-like cpu hpc language for tight numerical kernels to integrate with c functions, look for Intel's ISPC
And you're right about C++11, my bad. It's funny how C is actually pioneering a lot of the changes actually required for performance while C++ thinks about standardizing Cairo for 2d graphics...
It's quite possible not only to offer a complete C++ replacement but to also substantially improve on C++ on all aspects.
Probably the strongest point of C++, besides its performance, is its ability to interact with C easily and efficiently.
A huge amount of C++'s complexity comes from this requirement, but the benefits are enormous. It's such a big deal that MS eventually just started recommending people use C++/CLI to interop with C instead of using the usual C# Interop methods.
Too many people underestimate the extreme advantages that are still gotten today by that requirement.
The rest of it, yes, you could, but not that specific requirement. Doing that efficiently and easily enforces certain restrictions on the language, and the underlying runtime.
There's definitely an argument for the expressiveness of the language, but what you're talking about is more of a mechanical aspect of the C++ language itself.
What I'm talking about is more about the usefulness of the language in a practical sense, not what it allows you to express.
The reason I picked C++ templates in particular was because they allow you to make very effective use of information at compile time. Other languages, at least in my experience, don't give me ways to really tell the compiler (or interpreter) my intentions as effectively as C++ allows me to when I'm using template metaprogramming. So, to that effect, C++ is superior on top of just C compatibility.
... Not that any of this takes away from your original argument.
Do you know about hygienic macros in scheme? Standard ML parametric polymorphism? Haskell type classes?
But even more mundane stuff like D's templates? Code-generation and reflection in C# (not to mention generics)? Scala's generics and parametric polymorphism?
The Linux kernel, which is entirely written in C, is a fine example of object-oriented programming. File descriptors are object references. The filesystem is a beautiful heirarchy of polymorphic nodes. There simply is no non-OOP way to implement these things.
* I cannot mention singletons without linking this essay of mine, even though I'm somewhat embarrassed that I never found time to fill in the rest of the site: http://www.object-oriented-security.org/lets-argue/singleton...
The environment pattern effectively makes this context implicit.
Dependency injection is the name of the game right? That's what videos on youtube are advocating...
But it's also a pain to pass everything that is needed down to functions, so let's stuff all the global state in a class and pass that class down!
I hope I just didn't get the sarcasm, really.
Depending on your specific definition of OOP.
I suspect what the author is talking about is the high level of coupling that occurred in a looooot of 90's/early 2000's codebases. It was a time of learning for many many people, but our industry as a whole, and the C++ community specifically, has learned a lot from those mistakes.
Yes there is. You can implement them as an endofunctor.
- Angelo from c0de517e
Ultimately, I think he's right: what we need is to be able to invent and use high-level languages and DSL's that are wonderfully expressive for our domain (with fast iteration and all that), but also to be able to control the low-level run-time code that gets executed as a result, so it can be fast and efficient.
That's the holy grail as I see it. And LLVM is a key contender to provide the backend of that vision. (TFA talks about a lot of other things, but this is pretty much how I interpreted its conclusion, and I agree).
I then wonder how long it will be before they get upset about some feature they consider to be inelegant and try to find the next fad or old language they had previously discarded.
I really wish people would stop doing this. They like to tear down, without really building anything! It's sort of a whinge to tear things down without really understanding why certain concepts or ideas were invented. Kind of lame.