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

Having recently learned C++/C.. I don't see why it would be taught as a first language outside of specializations. The gains from C/C++ coding are vastly outweighed by the costs. The reality is that there is no good, agreed upon standard in C++ for how to manage memory... how would you teach this to junior engineers at university?



Having learned C/C++ as my first languages I can say I'm quite glad for it. I was able to learn so fucking much.

1. Object oriented programming, complete with inheritance and virtual dispatch

2. Pure Functional Programming, lambdas, const correctness, template metaprogramming

3. Type system fuckery - the things you can do in C++'s TMP is insane. Both nominal and duck typing in the language.

4. Hardware - I watched so many talks on how CPUs work that explained things via C/C++. I learned about tools like valgrind and cachegrind, how to profile code, etc.

5. Security - The original reason I wanted to learn them, to understand how to exploit C and C++ programs and their common vulnerabilities

6. Data structures - C++ is awesome for building data structures from scratch and understanding their low level semantics

I don't want to write them professionally, but learning them was massively helpful, with skills propagating through every other language I've used.


I'm glad someone pointed out these things, as I concur. I learnt C++ via the C++ programming language book, and it gave me many of the above benefits/insights. (The book has its faults though). It is akin to trawling through the CLRS book. It does make you a better programmer but no-one knows why. (An attempt at sarcasm - I know most of us never need to do advanced data structures/algorithms but it helps refine the mind for programming challenges).


7. Fundimental underpinnings - Every other language is written essentially in C - you can often understand how their features WORK if you know C extremely well.

... I'd argue that 1,2 are covered by rust. 3 and 6 by unsafe rust.

Once you have that, a transition to pure C for the full 7 makes sense, and would be trivial for a rust dev.


I'm fairly proficient in Rust and I think it has its own strengths for learning, but its own downsides too.

Pros:

1. Way easier to get "live" help, I've found the barrier to ask for Rust help is lower than any other language I've ever used (and I've used a lot)

2. Way easier tooling like cargo, error messages are far better, especially with regards to generics vs templates

3. Some things are more explicit in Rust. Like `Box<dyn Trait>` is very explicit about dynamic dispatch, I don't recall that being the case in C++.

Cons:

1. Rust's "codex" of knowledge is nowhere near C++. There are tons of conference talks, books, blog posts, etc on C++. Not just on C++ but also on hardware as seen through C++, security, etc.

2. Implementing low level data structures in Rust is an advanced practice. Implementing them in C++ is trivial. I get that it's trivial because C++ doesn't give a fuck about your pointers, but if you're just trying to learn data structures you really just need to be focusing on happy paths and whatnot (as a student).

So idk, at this point I tend to recommend Rust, but I also end up having to link people to talks on C++ sometimes! Herb Sutter and Scott Meyer are amazing speakers and writers and that's a very hard thing to replace.


An accurate summary. I was reflecting exactly your cons when I left gaps in what I said Rust was good for.

Con (1) (Existing examples / training) is a legacy language strength in general, C++ is going to lead in this for a long time.

Con (2) (Low level data structures) I 100% agree. A toy example of a datastructure in C++ is going to be really easy to express but also dangerous to use.

I think you'd really enjoy this chapter of the Rust Docs on making your own Vec https://doc.rust-lang.org/nomicon/vec/vec.html

And you are correct (Con 2 again), it IS an advanced practice. The result of making a data-stucture the rust way is a bulletproof class anyone can use, rather than a C++ foot-gun so it's worth the effort (but less so for learning).

You might find you can make your whole module unsafe and write a very similar data-structure in rust to your C++ solution (pointers and all) and it would compile and run fine.


The big thing to know about rust datastructures is that you need to use unsafe to implement anything cyclic. There is nothing wrong with using unsafe for a few lines of code - just review carefully.


I'm always conflicted with this.

My gut says any new student should start with an interpreted language like Python or JS/TypeScript. As that gets you to running code, and core concepts like variables, loops and if statements in little to no time.

However, there is value in learning some of the under the hood concepts such as pointers, structs, memory layout, endianess, pass by reference, compilers etc.

I don't think schools need to teach employable C/C++ skills, but C/C++ is a great language to play with and experience these core concepts.

However I'm not sure if the value in learning these concepts are real, or it's just my own interests/nostalgia. You can have a successful career in this industry without having to manage a single byte of memory, and it arguably makes sense to accept abstractions at their face value so you can focus on what builds your skills/product.


> pointers, structs, memory layout, endianess, pass by reference, compilers etc.

C++ is a bad language to teach any of these concepts. Sure, people will be exposed to the concepts, but they are presented in a rather esoteric fashion. Not to mention, actually leveraging those concepts in is bad practice anymore, i.e., using a pointer arithmetic to loop over arrays instead of iterators or the like.

I didn't grok a lot of those concepts until I took computer architecture, which was taught in assembly language. And we weren't taught x86, but a toy assembly language designed for teaching.

Another big pain point I had in school is that every professor / TA had different opinions on what was a right and wrong way of doing things in C++. And sometimes their opinions would conflict with the damn documentation too. There's nothing like having to relearn core language concepts every year at the whims of professors. This is probably where most of my disdain for the language has come from.


the chance of you being taught correctly by your so-called "professors" (they are not professors unless they have been appointed to a chair) is vanishingly remote, but this has zero to do with the language


C and C++ are still horrible languages even if you want to teach those concepts, because of how many footguns they have. That's why Pascal was so popular as a teaching language, historically speaking - it still has pointers and other stuff you need for manual memory management, but it's much simpler and more regular both syntactically and semantically.


no, it has exactly the same issues as c and c++, and some of its own, such as arrays of different sizes being different types. guess why it isn't used anymore


Arrays of different sizes are different types in C, as well - this is obvious when you are dealing with pointer-to-array types.

That aside, Pascal removes a lot of UB and other footguns by forcing explicitness for e.g. casts and pointer arithmetic, or providing (verifiably safe) byref argument separately from raw pointers. Strings and arrays are a mess in standard Pascal, which is why everybody used dialects that solved them - most notably Borland's, of course, which was used for a lot of DOS and early Win32 software.

Anyway, I'm not suggesting Pascal specifically today. The point is that C and C++ were never good teaching languages, which is why something else was usually used as one whether we look at 80s, 00s, or today.


>However, there is value in learning some of the under the hood concepts such as

>[...]

>I don't think schools need to teach employable

My University taught the intro CS class in Scheme; years after I graduated they switched to Java and last I saw it was Python (based on visits back to campus and wandering through the bookstore to see what textbooks were for sale). I just checked and it still Python, based on the course description ("how to design and implement algorithmic solutions in Python"). I see a few 2xx level classes are in Java, and after that it stops mentioning specific languages.

Anyway, it's tough since there is pressure to teach the concepts, which argues for certain languages, yet also produce employable graduates, which argues for certain other languages.

Finding overlap is tricky... teaching theory in Haskell, under-the-hood concepts in assembly, software development gluing libraries together in javascript/c++, may in fact be the superior approach... but there is fatigue associated with learning languages just to learn more languages when maybe a nice general language that serves many educational needs is a better way.

Python might be the sweet spot to start out with, and indeed it looks like the 3 intro classes at my alma mater, are taught in Python. I'd like to think the driving force behind this is that 1) Python works well, and 2)using one language for first year students (well, 2nd semester 1st year or perhaps 1st semester 2nd year) lowers the mental overhead on the students.

Going heavy on C/C++ early essentially selects people that already come in with a programming background. Some folks don't get that, or not much of it, in high school and want to enter the field anyway. And I think it is fair for them to reasonably expect, like you can with every other academic field, that they can do that via the starting curriculum.


I have written maybe one binary search that went into production code in 20 years of software development work. It is absolutely an under the hood concept.

But knowing how it works so that I can leverage the concept efficiently is super important. Having a sorted or unsorted list/array/tuple/whatever-linear-thing and an functions that search them and then knowing what the performance characteristic will be like and how I should put those two things together is not something that can easily be googled.

I agree it doesn't need to be a first year thing, but it does need to be part of a robust computer science education.


Exactly. And understanding WHY you should prefer using a Struct (or class) instead of a dictionary / hash-map. Can you feel the PAIN of all that additional cost??

The Python / JS world is all dictionaries. Such a developer might never understand why their language runs slower.


I would suggest Pascal or a compiled BASIC dialect to learn those things.

The nice thing with these languages is that they are relatively small but still has these concepts, thus perfect for learning.


I learned programming in the 90's using C++.

When someone expresses this intent I always ask the same question. Am I a supergenius or are you mistaken?


One could learn in C++ using a variety of methods… including the ignore memory management variety.

The question is why? For a student learning dfs for the first time or hash tables/queues etc. python will be much easier to learn. Java/rust/go will likewise be easier if you want to talk about types.


Java and Python's notions of type safety are completely brain damaged. I can't imagine how things would have gone if I'd learnt them as first languages.

Rust, C and C++ get that better, in my opinion (you have to consciously choose to write type safe code in two of those languages, but at least it is possible in all three). Go's thread safety is way behind Rust's. meh.


I would argue C++ type system is superior to even C# and I'm a huge fan of C#.

But more to the point, people claim it's somehow harder in C++ to learn programming so either I'm super smart or they're wrong.


Could you tell me some differences that you see as significant between the C++ and C# type system?

I can think of a few but they seem like compiler sugar only. For instance C# classes are treated as a &ClassName or std::shared<ClassName> (handled by reference transparently to the programmer).

Otherwise I think that C, C++, C# have very very similar type systems. They don't have alternatives to dynamic dispatch (virtual / override) like enums with value (a Rust feature). They don't have ways to add functionality to existing 3rd party classes. C# Interfaces are basically simple C++ classes with every function marked virtual.

C# feels far more dynamic with reflection and whatnot but you say type system, which is a different thing. LINQ again stacks well with C# and makes it more expressive, but doesn't change the type system.

I'd argue that '99 C++ is very similar to C in the type system, with a little sugar around classes having an implied *this and vtable mangement around virtual. Otherwise you can impl something like C++ classes using C structs.

Are you talking about C++ template programming and meta-programming? Because I personally view that as an advanced preprocessor / precompiler step that outputs large amounts of simpler C++ code without templates and doesn't change the "type system" a great deal.

Perhaps you are referring to some very modern C++ features I haven't used yet? Most likely they only brought C++ back in line with a subset of Rust / C# features.


C++'s type system is both more consistent and more expressive.

GC'd languages fall into roughly 2 categories.

1. those that are pure but lack strong primitives (Python, Ruby, et al), 2. those that bifurcate their type system and treat primitives as a special case (Java, C#, et al).

2 is done as a compromise for performance since they'll start making guarantees such as preferring stack allocation. This is the primary difference between 1 & 2, what the language promises with these types (if they have them).

C# learned from Java but added "value types". So now understanding what a piece of code actually does requires you to know not just the type, but whether it's a value or reference. Create a tuple with a string and 2 ints and default construct it. You get (null, 0, 0). Now do it with MyTypeA, MyTypeB, and MyTypeC. You have no idea what that tuple will default construct to unless you know more about MyTypeA, MyTypeB, and MyTypeC.

Default equality is it's own bag of worms.

Whereas in C++ it's a lot simpler. It's value, a reference, or a pointer, and you know which it is by looking at the callsite. C++ has similar ambiguity with respect to function callsites with references vs pointers, but the convention in the C++ community is to pass by pointer if it's going to be mutated and by const reference if it is not.

IOW, the rules for the C++ type system are easier to learn and use effectively, and their semantics are easier to understand from the code.

The existence of typedef automatically makes it more expressive than C#.


Fair points. I agree that having to memorize which types are arbitrarily treated as pointers in Python is a huge pain. Python also adds pain with the "default argument" issue.


The C# standard library is more consistent and powerful (batteries included, more modern). That means there is a "standard, correct" way to do most things in C# in a multi-platform way. C/C++ has massive variety here.

Memory management is trivial in C#.

So yeah, C# is easier to learn. Perhaps you're super smart?


I'm curious, how did you hear standard library when I said type system?


Ah, I guess I was responding to this paragraph of your message

> But more to the point, people claim it's somehow harder in C++ to learn programming so either I'm super smart or they're wrong.

TBH I consider the type systems of most imperative languages to be extremely similar. The only difference worth discussing is enumerators which can hold data. C++ doesn't have these, not sure if C# has them now. Rust has them.

I'll create a new comment under yours for a more specific discussion.


The C++ of the 90s was a much simpler language, closer to "C with classes" (and often used as such) than modern C++. It was much easier to learn everything about C++ back then.


How is this relevant?


boomer sooner


The point is

Just because we can teach programming with cpp, does it mean that we should?

Seems like no.

There are better designed langs and ecosystems that allow students to move faster.

Go python c#


But there is! Use local variables and value semantics. Use references to borrow stuff. Never touch new or delete. Use smart pointers when need an owning pointer (rare). Anything beyond that: ask next in seniority to supervise. That should be enough to live a happy C++ life for a junior.


Ah, I think the parent was referring to C++ circa 1990 to 2010 - prior to the much more happy modern world with standard smart pointers.


I definitely would not advocate teaching students C++.

C on the other hand is a relatively compact language and is the lingua franca of operating systems and shared libraries.


My recent hot take is that students should never learn on a language older than they are. There are so many options, why did I have to battle linker errors in my intro to CS class with C++? Nothing we were doing required C++.


new / delete?


I use malloc more often than I use new and delete!!!




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: