What bothered me a little bit while following the book was that copying the code doesn’t result in compilable code all the time because there is code missing that is only introduced later. I get why the author chose to follow this path, but I’m from the club that every commit should compile and was annoyed a bit by that.
It's hard to have the code compile after literally every single snippet. Sometimes, we need to change the signature of a function that already exists and is called, so there's going to be at least two snippets you'll have to apply before you're back to a working state.
It probably would have been possible to make this work by introducing temporary scaffolding code which gets removed shortly after, but it would have made the book much longer and more tedious.
Balancing thoroughness and brevity is always a challenge when writing.
The code is compilable at the end of every chapter and usually compilable at the end of every heading within a chapter. One thing I could have done that I didn't would be to place some visual markers in the book whenever you reach a point where things should be compilable. I'll keep that in mind if I write a third book.
That had better be "when I write a third book" Bob, not "if".
It's not just the technical content (Which is excellent), but your ability to convey and entertain that helped create such a classic book.
So if you do get a spare couple of thousand free hours, please ignore the pull of family, the economic safety of work and plunge head first into another oversized computer engineering project. You may now take my money.
I am the opposite. I think pedagogical materials like this should introduce things in the order that makes intuitive sense, and most of the time that means from the easiest to the hardest.
Doing it the other way is a common pitfall in teaching programming concepts. A very common example is the historically necessary boilerplate in Java’s Hello World, where quite a few concepts are present but handwaved away as you don’t need to worry about this now. The problem with this is twofold:
1. It is challenging to distinguish the pertinent from the impertinent. People who are just starting won’t be able to tell what parts of the code deserve their attention now.
2. It is challenging to retroactively draw attention to previously dismissed details once they do become pertinent.
I think there are other ways to address this, with additional formatting considerations in the presentation of example code. But there’s still a problem once the reader wants to tinker with the code, as any such formatting will be lost between a carefully tailored example rendering and the user’s code editor.
> Doing it the other way is a common pitfall in teaching programming concepts.
100% disagree
If someone is brand new to programming and you're expecting to teach them the following concepts:
A class, methods, static methods, data types, method return types, void return type, arrays, and namespaces just to be able to write a simple "Hello World" app [1] I think your approach is the one that's misguided.
The most common mistaken people make in teching is teaching things in the order the were discovered historically. Not always, but very often that is a distraction. The second most common is teaching from the outside in.
The best way to teach is to explain what your tyring to accomplish and start with a very simple example for people to play with. Then pick on concept and modify it so they can see the results of those changes. Then pick the next concet and modify that so they can see tangibly what that means.
In the hello world example, it would be starting with the program in [1] and focusing just on the constant string "Hello World!". Change it see what that means, understand what's going on. Then move out to the Console.WriteLine. Make a copy of that line have two lines of it then 3 to understand the method call. Then swap to Console.ReadLine to see what a different method call can do. Continue exploring out from that core concept.
The "static" identifier on a method class is not where to start teaching someone programming.
It's also why Racket removed a lot of the boiler plate from thier core teaching langauges for students. For them to not even have to see the things that are unnecessary at that point in their learning.[2]
You say 100% disagree, but then everything you say seems to agree with my points. I would even go so far as to endorse your response as a longer form elaboration of exactly what I was trying to get across.
I see you claim that, but unless I misunderstanding that completely contradicts our claim here:
> A very common example is the historically necessary boilerplate in Java’s Hello World, where quite a few concepts are present but handwaved away as you don’t need to worry about this now.
What I'm saying is exactly that. Handwave past all of the boilerplate like the static declaration and only focus on the most important to learn up front (ex what a string is).
Could you explain how your statement of initially teching the boilerplate is the same as my statement of ignoring it?
In my example, the entire time they are working with strings or readline/writeline method calls they are entirely ignoring what a static/class/args all mean and they are just boiler plate they have to type until they get to that stage in later lessons.
> Could you explain how your statement of initially teching the boilerplate is the same as my statement of ignoring it?
I specifically said that including the boilerplate is a common pitfall, and requires teaching around a bunch of impertinent concepts.
I also chose the example for a reason very close to your example with Racket: later versions of Java have similarly aimed to reduce the necessary boilerplate. And if I’m not mistaken, the learning experience is a motivating factor for that as well.
If emphatically agreeing with you in so many words isn’t enough to convince you that I agree with you, maybe you’re just looking for something to argue about?
> I specifically said that including the boilerplate is a common pitfall, and requires teaching around a bunch of impertinent concepts.
And again, I'm saying I disagree with this. You are saying don't include the boilerplate at all when teaching. I a saying, do include the boilerplate and don't teach it until students are ready to understand it.
As a separate topic, if the language doesn't need boilerplate to make the program work (like Racket) that's spectacular. But if it does, then I'm explicitly saying "show the boilerplate and explain 'you don't need to focus on it now. You will learn it later'".
It is best give people a fully working program at all times, even if they don't understand all of it. So they can play around with it, rather than just read along while the author writes about what would have happened if it were fully functioning code they could play with.
And to make it very clear, the example I linked to explicitly includes all of the boilerplate, and I explained exactly the best method to teach a student with that specific concrete source code.
Now all of that said - this isn't really important enough to continue arguing on the internet over. I think we both had good intentions but just weren't communicating clearly. I hope you have a great day.