Learning Standard C++ as a New Language (1999)
drdobbs.com
drdobbs.com
[1] CppCon 2015: Kate Gregory “Stop Teaching C" (https://www.youtube.com/watch?v=YnWhqhNdYyk)
I actually think there are also important lessons to be learned when trying to teach any programming language as a first language, because beginners are likely to offer some illuminating questions, and that begins with the boilerplate (the Dobbs article calls it "scaffolding" but I think boilerplate is appropriate).
The boilerplate in C++ is very bad. I am convinced that it would be less bad (maybe still pretty bad, but less bad than say C) if right early on somebody had sat down with students learning this as a first language and noted down all the warts they run into and set about fixing as many of those warts as possible.
Unlike other languages, C++ needs quite some C code to get the whole thing working sometimes. I do agree that when you learn C++, you should not focus on its C roots.
In contrast, with C++ your program has Hodge podge of high-level constructs like std::vector, string, RAII etc.. and suddenly you are in the void*, malloc, free land with your C code. The mental model of lifetime/memory of objects in your program is inconsistent and burdensome. People would rather program everything in C, at least it will be consistent albeit very low level.
I totally agree that sockets is a long overdue oversight in the language.
I don't think it's that shocking, is it? In most languages the networking support is basically just the C socket API exposed as well. A good API is a good API, it shouldn't really matter how it's implemented.
Also seems like a massively unfounded leap to go from "the standard library doesn't have it" to "complete lack of good C++ libraries for common tasks". C++ has never been a "batteries included" language. That doesn't mean good libraries don't exist for it. Boost is very common in the C++ world, for example. And that "experimental" networking library is basically just asio but adopted by the standard library, and asio is not experimental or unstable: https://think-async.com/Asio/
> Python for ex. might have C code behind the scenes, however you will interact with the C library in a pythonic way
Kinda odd to use Python as an example when it just exposes C sockets pretty much directly and entirely non-pythonicly https://docs.python.org/3/library/socket.html
> In contrast, with C++ your program has Hodge podge of high-level constructs like std::vector, string, RAII etc.. and suddenly you are in the void*, malloc, free land with your C code. The mental model of lifetime/memory of objects in your program is inconsistent and burdensome. People would rather program everything in C, at least it will be consistent albeit very low level.
Eh? No, people would just make a tiny wrapper around the C APIs and call it a day. It's a pretty odd stance to take to say that to avoid writing ~100 lines of C-style C++, you should instead write 10k lines of C?
Also other than void* (which is in C++, too), you shouldn't be encountering malloc or free when calling C functions. That's not how any good C API works, and it's certainly not how the continuously mentioned socket APIs work.
C++ has plenty of excellent libraries for such tasks (just think of boost), they are just not part of the standard library.
In experimental but there is the Networking TS: https://en.cppreference.com/w/cpp/experimental/networking
> even C++ thread uses pthread underneath
https://en.cppreference.com/w/cpp/thread was added in C++11. How it is implemented doesn't really matter, does it? It doesn't leak any pthread-ness.
I could agree that C++ has many constructs that allow one to get away without slightly advanced programming that would be needed when coding in C, but recommending that one shouldn't need to understand function is a bit much.
On the other hand, if you are trying to teach C++ to people who already know how to program, then you want them to be able to understand existing C++ code, not just write new code. So they need to understand the complex parts of the language and why they are like that, and the easiest way to do that is to start where C++ started, i.e. with C.
I remember the Dr Dobbs article from when it came out and I have to agree that I was still using all the old stdio.h, string.h, etc. functions. To this day streams, which was probably the first thing C programmers had to swallow, seem "unnatural", whatever that might be.
For newcomers to C++, now as well as in 1999 when the article was written, you have to really take the time to appreciate what C++ is trying to do. I switch between C#, C++ and Python and C++ programming has a certain feel to it that I think you have to learn (or be forced to) appreciate.
cout << "number of elements = " << buf.size()
<< ", median = " << median << ", mean = "
>> mean >> '\n';
This is clearly improved by just having string formatting (a feature C manages to have, but here's Rust's) println!("number of elements = {}, median = {median}, mean = {mean}", buf.size());
It's OK though, twenty years later C++ managed to get as far as std::cout << std::format("number of elements = {}, median = {}, mean = {}", buf.size(), median, mean) << std::endl;This is clearly disingenuous. C's string formatting is a completely different thing from that Rust snippet or your snide remark about std::format.
I'd rather use printf than cout, I think iostream is clunky, but printf is definitely a footgun & a fairly common source of bugs itself. So much so that compilers had to add support for specifically recognizing printf() calls & validating the inputs.
Also don't forget C still doesn't have standard placeholders for sized types. Gotta use that derpy PRId64 & friends which makes printf() almost as ugly looking as iostreams.
As published C++ 20 allows a compiler to swallow this nonsense:
if (untested_condition)
result = std::format("Oops {} {} {} {}", only, three, parameters);
... and spit out a program that will only blow up when untested_condition becomes true in production. Fortunately sanity prevailed as I understand it, and the revised document correctly requires that this is a compile time error.Unless you're talking a very old & not well maintained codebase, there's not really any benefit to starting with C if your goal is to learn C++. It's probably more harmful than anything, even, as it'll teach you things that are bad form in C++. Like using malloc & free - even 'new' and 'delete' are poor form in modern C++, it's all std::make_unique or std::make_shared.
I started* with Pascal, but I then moved to C++ the next semester. I only learned C as essentially a subset of C++. This was like 1996/97.
*Although I guess my first programming experience was with DOS/Windows Batch file scripting and some BASIC. Introduction to Programming with Pascal was the first programming language I took in as a class.
It's always hard to extend a language culture to include libraries, as some people will prefer to adapt or roll their own. If it's not automatically part of the language the community will fracture.