Hacker News new | past | comments | ask | show | jobs | submit login

C++ is not very canonical OOP. And by that I don’t just mean it’s multi paradigm nature, but it’s realization of OOP features. Using C++ teaches you mostly about using C++ and doesn’t really transfer across the paradigm.



I think that statement would have to be classified as inaccurate. using C++ teaches you mostly about general purpose programming and it's pretty easy to go from C++ to python to Java to bash, etc.


Nonsense. C++'s template system behaves unlike any other language (things like SFINAE and the techniques that use it do not transfer), C++-style RAII is relatively unusual, I don't think any other language requires the programmer to think about virtual versus non-virtual inheritance, the C-derived sequence point rules are obscure and much looser than most languages' evaluation rules, the exception-safety rules are unique to C++, most languages don't make you track the minutiae of a dozen different integer types with inconsistent promotion rules, textual macros are abominable, C++ has more obscure control flow constructs than most languages... meanwhile the language has no standard support for true sum types, garbage collection, unit testing, poor library tooling, a limited type system... which means you don't learn the general-purpose techniques that rely on these things.

If all you know is C++ you will be able to produce a limited amount of working code in a handful of C++-like languages, sure - but even in Python or Java or Bash you'll produce very unidiomatic code if you write in C++ style. If you tried to work in e.g. Smalltalk or Erlang or even OCaml you'd really struggle. It is not a good way to learn general-purpose programming, because the language is hugely complicated and most of the complications are C++-specific.


All the complications you list derive from the peculiar C++ language design principle of ensuring high performance despite sophisticated abstractions; popular languages are simpler because they stop at basic abstractions (e.g. C and Forth) or because they trade performance for elegance (e.g. C# and to a higher degree Python and Smalltalk).

C++ does more at a higher cost, and in recent standard updates the cost has been steadily decreasing.


> popular languages are simpler because they stop at basic abstractions (e.g. C and Forth) or because they trade performance for elegance (e.g. C# and to a higher degree Python and Smalltalk).

I'm not convinced. C++ offers some abstractions but is also missing some quite basic ones (no sum types, no true parametric polymorphism, polymorphic code can only be typechecked once fully expanded). ML-family languages offer substantially better abstractions at minimal performance cost or, in the case of Rust, no cost. Even for GCed languages my experience is that at practical levels of developer effort C++'s high performance on benchmarks is outweighed by the language complexity burden (e.g. Haskell code that solved the same problem as C++ code was not only shorter and more maintainable but also substantially faster; no doubt if we'd carefully hand-optimized every line of the C++ it could have achieved higher performance, but even unoptimized C++ took much longer to write than the Haskell solution).

> C++ does more at a higher cost, and in recent standard updates the cost has been steadily decreasing.

The big cost is the complexity of the language, and since the language rarely if ever removes anything standard updates usually add to that rather than reducing it.


ML-family functional languages, which you seem a fan of, also trade performance for elegance, with few fortunate exceptions in case elegance goes far enough to allow extreme optimizations that recover whole-program performance despite widespread inefficiency "in the small".

Significant bad parts of C++ have been deprecated or effectively replaced with something better; you just have to adopt the good way. For example, the new initializer syntax allows for simpler and saner rules about type conversions and lookup of constructors.


> ML-family functional languages, which you seem a fan of, also trade performance for elegance, with few fortunate exceptions in case elegance goes far enough to allow extreme optimizations that recover whole-program performance despite widespread inefficiency "in the small".

I'm not convinced. Small-scale heavily-optimized microbenchmarks show C++ as at most a single-digit multiple faster than e.g. Haskell. I wouldn't expect you to achieve even that much over Rust. And like I said, I've yet to see such a performance advantage to C++ in a real-world scenario - quite the opposite. It's not always a tradeoff - sometimes one thing really is better than another thing.

> Significant bad parts of C++ have been deprecated or effectively replaced with something better; you just have to adopt the good way.

And ensure that all your libraries/tools/coworkers have adopted the good way, which you have no way of enforcing; at best you have ad-hoc linters that flag up some (but not all) bad practices.


I'd have to disagree with the transitions from C++ to python or java and bash.

The complication is C++ specific and moving to java, bash or python is simply removing that complexity. Hence moving to C++ is easier then moving from python or another similar language because in most cases you would be adding complexity.

OCaml and Erlang are too different for me to comment about a transition in the functional direction.


But then the whole argument falls appart. Sure if you learn standard boring OOP in C++ then you can apply it. Thats what Java was designed for.

Hoever to even get there you first need to learn incredibly complex nonsense and waste massive amounts of time for knowlage that is virtually useless.

Then you might as well pick up Java, the most popular OOP language and learn it there.


well, that's just like, your opinion, man ( big lebowski reference for those too young to know ). The reason I disagree with you is because I have never met a C++ programmer who only knew C++ and couldn't easily do work in some other language, but of course plenty of people know other languages and can't do C++. Yes, SFINAE and RAII - you can go for many years of working in C++ without writing much code using either one of those.


That is more like an example of Blub paradox in action: You can write in everything as if it were C, you can't write C as if it were everything else.

Except that it makes a point that is subtly different from the one pg originally raised in discussing Blub paradox: If you only care about shipping something, you aren't inclined to think about abstraction as a goal state, and that's what these other languages are doing: handling things with a goal of adding abstraction that for a C++ user is out of reach or requires considerable knowledge of the C++ standard. Users of Python or JS don't know what a pointer is, and that's intended by design, because for most applications it is an implementation detail and automating it away is desirable.

When most software was written in assembler, data structures more complex than an array were often avoided, because it was difficult to code and debug them. And if you were an assembly coder of that era, you might well say that you didn't see the point of structured programming, or that you could easily get the same effect in fewer bytes. And to some degree, you'd be right, because you would just design a smaller scope of application that makes those techniques viable.

Trying to write something resembling modern C++ style in x86 assembly, in contrast, would be as fruitless as a JS coder trying to use C++ like JS, since your abstractions wouldn't be there. You'd have to learn the thought process of a lower level coder and apply those strategies instead of the ones you are comfortable with.


> I have never met a C++ programmer who only knew C++ and couldn't easily do work in some other language

Did they try the languages I mentioned? C++-trained programmers might be able to write lowest-common-denominator code in other languages but they'll struggle to write effective, idiomatic code in languages that make significant use of pattern matching/sum types or polymorphism, or rely on extensive use of higher-order functions.

> but of course plenty of people know other languages and can't do C++.

I'd agree that C++ programmers can usually write Java/Python, Java programmers can usually write Python but not C++, and Python programmers can usually write Java but not C++. But the implication is not that C++ is more general than Java or Python but just the opposite: programming in C++ requires learning a lot of C++-specific stuff that programmers in those other languages don't bother with.


> Yes, SFINAE and RAII - you can go for many years of working in C++ without writing much code using either one of those.

WTF, RAII is the corner-stone of C++ development. And I miss it (deterministic destruction) in every other language I use.

These days I use C# in parallel with C++, C# has using statement, but it relies on IDisposable, and IDisposable itself is a kludge (just look at guidelines on how to implement it "properly").


It seems a bit odd to complain that C++ doesn't support garbage collection. I mean yes, it's true, but... part of the point of C++ is to give you control of memory.


Sure, but certain programming techniques become impractical without garbage collection, and a general purpose programmer would be expected to be familiar with those techniques. E.g. C++ programmers tend to just not learn graph-based models/techniques because they're not a practical way of working in C++.


Graph-based isn't practical in C++? Why not?

I mean, yes, in C++ you have to clean up the memory yourself. That means that you need to know when to do so. That means that, for the graph nodes, you're probably doing some kind of reference counting, and it will be a bit fiddly to get right. If you do it in a base class, though, you'll only have to do it once.

I wouldn't call that "impractical" at all. (I might call that "reason to prefer a garbage-collected language for doing graph-based work", but if I needed to do such work in C++, I wouldn't be particularly daunted by the prospect.)


Fair point. I'd agree that a skilled generalist programmer should have no particular trouble doing graph-based work in C++. My experience is that monoglot-C++ programmers were less likely to learn those approaches because, just as if you need to do graph-based work then C++ is usually a less-good choice of language, if you need to use C++ then a graph-based model is usually a less-good way of solving a given problem (i.e. often the problem admits alternative approaches that are more easily accommodated in C++).


I would say learning C++ didn't quite teach me what I needed to go to bash.

Learning bash became easy when I learned pipelines and the GNU coreutils.

Now I wish I could take what I'd learned from GNU coreutils and apply that to C++.


Hmm, not my experience. C++ was my intro to OOP but I was aware of "pure" OO languages like Smalltalk. I feel like my C++ OO experience has taught me a lot although I think it's valuable to study another OO language side-by-side. A lot of OO patterns translate between languages although the implementation in C++ is often overly concerned with static types.


I agree. I wasn't trying to say C++ is great for learning OOP. I was saying that C++ is the best OOP-style language to learn in general because it allows you to break things and it encompasses other paradigms. Ruby is great for learning OOP, but it is far less general and far more protective than C++. But I'm sure others will have their own preferences but to me the lack of training wheels in C++ almost forces you to learn. Otherwise, you simply won't progress. I guess that could be a good thing or a bad thing as it might force some people to quit early on. Ultimately, I don't think learning C++ or anything language should be something you regret.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: