Open Xeverous opened 3 years ago
I think that it may be a good idea to only introduce build systems in the beginning, just to get started, and then delay a more extensive discussion until later. The reason for this would be that build systems can be a dry topic and you want people invested in the language before you get into the weeds. Same with static and dynamic libraries.
With regards to overloading and default arguments, I can see a case for default arguments purely based on the fact that they are common in other programming languages.
The reason for this would be that build systems can be a dry topic and you want people invested in the language before you get into the weeds.
Definitely this. There is delicate balance between build systems introduction and explaining all of the compiling and linking process (which is quite complex and platform-dependent). Not enough and the reader will get lost in setting up the environment. Too much and the reader will be bored.
I think more detailed statements can be made once the project gets more content and some examples. Only then we can make a conclusion what is necessary to briefly explain and what can be presented in an in-depth chapter about building.
With regards to overloading and default arguments, I can see a case for default arguments purely based on the fact that they are common in other programming languages.
This is a pretty trivial issue. I think it will simply boil down to what examples I can come up with. Default function arguments are more or less a simplified way of overloading so defaults will probably be first and then overloading can be explained starting by showcasing code equivalent to previous default arguments.
I would think the order for a complete beginer should be something like:
Something really simple, you want them coding, nothing else. Here you end with a hello world just to test that what they have works, tell them you will explain it latter.
Explain it line by line.
Dont get into too much detail into questions like "What does #include<iostream>
mean?". Dont give a long explanation, tell them that more details will come latter.
Out of here they will know how to ouput text, and will have the following template to use.
#include <iostream>
// using namespace std; <-- Im not sure of including this line.
int main() {
// Your code goes here
return 0;
}
List the basic ones. (int
, float
, etc. Dont get into containers yet)
Give just a general idea. Start making emphasis on good names.
Out of this one they can read input from the user and output it.
+, -, /, *, etc.
Now they can make basic operations on the data. Here is where you could start to intoduce some small problems for them to solve. You could have a space for them to upload their code, run it with the piston api, and check the result (Tell me if you need help implementing this).
Lambdas including a light introduction into <algorithm>
Standard library containers and references.
Light introduction to std::string
, std::array
, std::vector
.
static
, inline
, const
, constexpr
etc.
Give them a general idea of them, and make a big enfasis on const and const correctness
Exceptions depend on classes.
I disagree, you could introduce exceptions, and tell them how to implement their own latter.
Talk a bit about noexcept
class
Intro to OOP
struct
It does not need to be too long, just tell the diference, and say that it is there because of C.
Now you can tell them how to make their own exceptions.
And they sould have a general idea of the language. Then have a section to go into more detail.
Now they have their own types, let them overload some operators for it.
More containers, iterators, algorithms, etc.
constexpr
Now give them a full guide.
Introduce tools like clang-tidy
.
Specifically unit testing
We would end up with something like:
class
struct
constexpr
Im pretty sure im missing something, but im not sure what.
[includes] Dont give a long explanation, tell them that more details will come latter.
Agree. Initial explanation will briefly cover why it's needed. Entire preprocessor can be explained later in a specific chapter.
using namespace std;
<-- Im not sure of including this line.
The answer is no. There are multiple reasons:
using std::string
).I will probably even write a short warning that a lot of tutorials do it and why it's bad.
You could have a space for them to upload their code, run it with the piston api, and check the result (Tell me if you need help implementing this).
Environmental setup is for it so that readers can easily copy-paste programs from the site and run them on their own. I don't see any significant value in offering beginners online compilers.
The core guidelines and the GSL
This content is much better done at every possible moment rather than a full "lesson" on its own. If someone want that all-in-one lesson, they should just go to Core Guidelines page. IMO it's much better if I mention best practice + common mistakes right at the point where a given feature in introduced. Some readers like to go back to previous lessons if they feel they forgot something and placing specific guidelines inside lessons just feels worthwhile.
Im pretty sure im missing something, but im not sure what.
The full "list of lessons" would be a graph with ~200 elements (each being a short explanation, multiple ones per lesson) where there are multiple questionable dependencies. I might draw this graph at some point and attach a rationale to each dependency.
Other notes:
<algorithm>
which is great. This will be needed to be worked out - perhaps the graph can help.static
, inline
, attributes, override
, ...). I would favor learning it on-the-go some time after functions have been introduced.Environmental setup is for it so that readers can easily copy-paste programs from the site and run them on their own. I don't see any significant value in offering beginners online compilers.
My idea was to use for testing. They upload their code, and you tell them if their answer is correct. Will allow you to have a good list of test cases.
This content is much better done at every possible moment rather than a full "lesson" on its own.
True. My idea was to give them good habits during the whole tutorial, and at the end mention the core guidelines, because you cant cover everything in the tutorial.
The full "list of lessons" would be a graph with ~200 elements (each being a short explanation, multiple ones per lesson) where there are multiple questionable dependencies. I might draw this graph at some point and attach a rationale to each dependency.
Im looking forward to that.
[The graph] Im looking forward to that.
This could be a separate project on it's own... It could significantly help in figuring out order of lessons but I really need a tool for doing such fancy graph stuff (best in the form of automated script that reads file with the input).
@Polo123456789 do you have any idea when to explain RAII? I get conflict of interests:
Pointers aren't inherently bad. Any specific reason why you want to teach them as late as possible?
They aren't inherently bad but they are inherently complex.
Reasons listed in Kate Gregory - Stop teaching C talk:
*
and &
into code untill compiler agrees.Other reasons:
I would disagree, because I think at that point they are ready to learn about them but, at the end is your project.
If the problem was:
RAII naturally feels it should be in classes chapter but explanations basically seem to require pointers, unless I find a reasonable pointer less resource to manage
One that I could think of requires threading. You could talk about mutexes and
make them implement their own std::lock_guard
.
From RAII in cppreference:
std::mutex m;
void bad()
{
m.lock(); // acquire the mutex
f(); // if f() throws an exception, the mutex is never released
if(!everything_ok()) return; // early return, the mutex is never released
m.unlock(); // if bad() reaches this statement, the mutex is released
}
void good()
{
std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization
f(); // if f() throws an exception, the mutex is released
if(!everything_ok()) return; // early return, the mutex is released
}
I would disagree, because I think at that point they are ready to learn about them but, at the end is your project.
Ready does not mean optimal for.
My current plan (still quite tentative)
RAII is extremely important in C++, but I think that beginners don't need to understand it that early because before pointers chapther all code they will write will use rule of 0. RAII only makes sence once there is some resource to manage and for that I would really want pointers.
What do you think of this order?
Seems ok.
I have hit a somewhat dead end in ordering and it's really hard to write pages without knowing what can be assumed that the reader knows.
The current plan is to use Graphviz to generate a graph of all lessons and find dependencies between them. This is going to take some time but it should be a very valuable resource. Plus the same software can be later integrated into website build process - it would be awesome to draw graphs explaining stuff like pointers and data structures.
Writing now a year later, the project has got significant progress. The current order of chapters in the core tutorial is:
Notes:
Right now, the biggest tension in regards to the order is RAII vs inheritance/polymorphism. The reasons are:
std::vector<std::unique_ptr<base>>
to truly showcase dynamic dispatch and other mechanisms. Kate in her talk "Stop teaching C" says people will understand virtual functions very easily, even without any prior pointer knowledge. I just feel the quality of articles will be damaged if I can't showcase richer examples and need to use some "magic" like standard library smart pointers to have an array of dynamic types.Something must be choosen. Currently I'm more inclined towards separate tutorial for RAII and focus on good OOP in the main tutorial, potentially with reduced explanations on some stuff that involves resource manegement. It would be very good if someone could share their teaching experience. I also need good examples for pointers and inheritance topics.
After looking at the talk again (specifically 25:39 - 29:27), it's clear that polymorphism can be done before pointers and all the RAII stuff.
This is one of the hardest things to figure out (at least for me). This issue is intended to discuss the problem and list any noticeable things that could help in making better lessons order. Post your suggestions in this issue.
Current/planned order:
beginner C++ tutorial
= delete
C++ templates tutorial
std::enable_if
std::void_t
Notes:
dynamic_cast
) should be before classes.*this
as lots of canonical implementations do stuff likereturn *this;
.