Two Approaches to Learning Programming: Top-Down and Bottom-Up
programmingforbeginnersbook.com
programmingforbeginnersbook.com
Whenever anyone asks me how to get started in programming, I tell them to forget about buying any of those "Dummies Guide" books and instead just pick a problem they're really passionate about and Google anything they need to learn to make the idea happen.
Such an approach certainly doesn't teach you a lot of the most important thing about programming (garbage collection, what types of objects to use and when to use them, etc.) but it does get the job done.
And that's the thing I think matters most for those just starting out: if you try to learn bottom-up and get all the fundamentals, you're going to burn out.
Of course such advice goes right out the window if your goal is to actually become a real, breathing, programmer. Because you can't afford to make mistakes and the foundational stuff ensures you're less likely to do so.
Whereas just Googling how to put together a project will likely leave you with a functional project, yes, but also less-than-ideal code.
I'd never have made it through any of the bottom up approaches, because I'd have gotten frustrated with how much there was to learn before I could do anything useful.
My serious education took a fairly strict bottom-up approach, and it explained roadblocks I'd been running into before, improved my mental model of the machine (and variations between machines), and provided a solid foundation to build on.
My opinion is that top-down is good for passion, bottom-up is good for correctness, and a mix of both is useful. You need passion to put in the necessary practice time. You need a solid foundation to let you build non-trivial software.
Once a person has a handle on things like how code is structured and interpreted, syntax, objects, etc. then you can introduce them to the terminal and start teaching them Python if you want. But nothing comes close to driving interest like making a button on a screen that moves stuff around.
And I very much dislike JS for actual professional use.
Naturally, a lot of professors and highly talented experts tout this as the only way to go. It worked great for them and they don't see the point of any other path.
But, in my observation, "talent" is usually a false explanation of someone who is highly motivated by something I'm not aware of. Most "talented" people I've known were actually putting in a huge amount of work in the area.
On the other end... if the return on investment isn't clear. If the path to the payoff is branchy, windy and foggy. If you are motivated by results, not process. Top down is a good way to determine if it really is worth the effort. In the meantime, investing some extra effort in finding the payoff and the joy in the process would be wise when taking this approach.
I used to be better at that when I was younger...
Whether you start bottom up, or top down, your design may run into performance problems at some point. In cases where this is likely, it is better to determine key components, test their performance, and run calculations.
Missing next line: "Then you get a job and your colleague tells you that most professionals don’t code this way anymore.
Joking aside, it does seem that a mix of the two is nice. Bottom Up is boring when you just want to get things done and Top Down is magic until you try to leave the playground. The problem arises that each student will have different tolerances of each of those approaches.
Edit: Maybe an interactive book, or app, that lets you see a problem from both angles and let's you pick the problem you want to solve. Here is a problem: "Given this graph data summarize and display it". Bottom Up you learn DFS and Top Down you learn d3. With if you pick one or the other your given a library to fill in the part you don't like. You could always return and do the other part latter as well.
I started with basic lessons on Codecademy to learn the basic concepts and jumped between reading books and researching concepts and building small projects. I feel like I got the best of both worlds. When I hit a concept I didn't understand or needed clarity on, I went and researched the underlying fundamentals.
I've seen developers that have gone top down and they struggle with basic programming logic because they don't have the fundamental knowledge. On the flip side, I can't imagine studying CS and learning all the CS fundamentals without going ahead and building stuff the whole time.
Anyway, learning without building stuff is very un-fun. I can't imagine trying to learn programming by just reading books for months and months without access to a computer.
If you’ll start with C, there’s assembler and machine code underneath.
Underneath there’s memory hierarchy, CPU microarchitecture, buses, and other things like USB protocol stack.
Underneath there’re logic gates, comparators, summators.
Underneath there’s physics, quantum mechanics, electrodynamics.
Each of these abstraction levels is fundamental relative to the upper one.
The level of abstraction that you declare fundamental is arbitrary. You can define your “fundamental level” threshold much higher, e.g. JVM or S-Expressions, and start bottom up from that arbitrary level.
The level a median developer believes is fundamental drifts upwards over time.
70 years ago it was impossible to be a programmer without knowing about logic gates. The majority of modern software developers can’t design stuff from logic gates, they don’t even know much higher-level USB protocol stack, and yet they are able to do their jobs just fine.
That is certainly a lot of information to process, but if designed well it could be like one big project where you regularly end up with a result and then continue building the next layer on top of what you already have. There would be a clear path to follow in order to not get lost in any layer but if you wanted to, you could also keep exploring a layer for a while before moving on.
Not sure if that would actually be a good idea or not, but at least retrospectively that looks like an awesome way to really learn how to code.
In common OOP languages (i.e. Java), the mechanisms of OOP can be used as an ersatz DSL, albeit a bit limited.
Let me give you an example. QBasic is the first language that I learned. Suppose you want to draw a white pixel in the left upper corner on the screen. To do this, you can do: SCREEN 13 PSET (0, 0), 15
If you understand this and for-loops it is trivial to fill the screen with a color. Then the next step is to make the color of the pixel dependent on the position. I made some wonderful graphical stuff with this (rotozoomers, plasma, fire effects...).
Now, if I want to do this in C(++), I probably can, but it will take me at least an hour of research. Same thing for C#, Java, Haskell, and so on.
This is not a completely fair comparison since QBasic ran in DOS and there was no need to summon a window, but that is exactly my point: things keep getting more complex. To plot a colored pixel on the screen in QBasic, you have to know about pixels, screens and colors. To do this in a more modern environment, chances are you have to pick the right API and understand all abstractions it introduces (probably including windows, graphical contexts, buffers...). The trend seems to be to ever more abstract, complex, and powerful frameworks.
If you are already a programmer, this is a gradual progress and it is feasible to keep track of everything, but for new programmers it takes a looooong time to get up to date with all the new abstractions that people have come up with (and I think are not always that important to start programming).
Now I'm not saying that we should not introduce abstractions or frameworks or implying that DOS graphics were better than today's system with windows. I'm just saying that these advances come at a high cost, and I don't know if there is a solution.
I think that the Bottom-up method is better overall.