And we derive a few formulas along the way. integrals of x and derivatives of x2 (x^2, depending on your programming language) pop up all over the place.
I do wonder though -- for heavily skill-based endeavors (say swimming, sushi-cheffing, curling, etc.), the best way to learn is to do. First principles/mental model approaches tend not work so well in these domains, at least not isolation.
The best approach is probably a blend: learn by doing and understanding first principles.
I think it would be quite difficult to do in a reasonable amount of time, but using history as a course outline would be a cool way to explain the motivations/context behind the principles being discussed. That might better illustrate how math research works by explaining the gaps/interesting questions that existed prior to certain ideas and how those ideas evolved and lead to other gaps/questions.
The type of math courses I’ve gotten a lot out of already kind of did that, they just usually used more of a condensed, logical narrative than a historically based one.
It's still really important to work through problems mechanically (often with only partial understanding) if only to become familiar with patterns. Whether this exploration is done via a CAS or by hand, acquiring this mechanical familiarity is important if one is to go deep. Math is often not merely read but done.
Take something like automatic differentiation (AD) for instance. It's just the chain-rule in principle right?
One could try to study the principles of AD in textbooks/journal pubs and then try to implement it in code. Chances are one is unlikely get it right the first few times because anyone who's ever tried to implement anything from numerical computation papers knows that published papers regularly omit important implementation details (unless they also publish code). There's so much heuristic/unintuitive behavior [1] in the world of numerical computation that first principles alone is rarely enough to get you a decent implementation in code.
On the other hand, if one mechanically works through AD derivations for a bunch of functions and observing the patterns that emerge (without necessarily grasping all the principles at first), one begins to notice things, like difficulties posed by corner cases like non-smooth/discontinuous functions, non-n'th differentiable functions, etc. A CAS could be used for this exploration (manually doesn't necessarily literally by hand) but it's so important to actually try stuff out and really grasp how mathematical objects work in practice. Once this contextual understanding is acquired, going back to AD journal pubs and reading about the principles is likely going to make way more sense because one has seen the behavior "in the field".
I do think the pure mechanical repetition is often underrated as a autodidactic mechanism. (again I don't mean literally by hand, but rather "doing" instead of just "reading and thinking").
[1] non numerical comp folks are often surprised to hear this because they think everything's super deterministic -- it's not. Tiny random perturbations in matrix can change things wildly. Take naive Gaussian elimination -- the ordering of the rows of equivalent linear systems can vastly affect solution efficiency and numerical stability, but one can't appreciate that unless one understand how GE works mechanically and has worked through examples.
I feel the exact opposite way. The method you're describing is how I was taught calculus in high school, that is, with a strong focus on practicing mechanical manipulation of formulas rather than building deep understanding. And I just disconnected from that, I got no mental reward from procedurally finding the derivative or the integral of a function for the 100th time. Lack of motivation meant lack of focus, which in turn made my performance drop, and at the time I assumed I probably just wasn't as good at mathematics as I thought I was. That lasted until I got mathematics classes in college, where many of my mathematics courses used a more first-principles-based approach, and I performed well again.
> Sort of like teaching a student to write "hello world" before diving into the low level mechanics of a compiler.
I found Structure and Interpretation of Computer Programs (https://mitpress.mit.edu/sites/default/files/sicp/index.html) the most enlightening intro to programming book I ever read. Its approach is also strongly first-principles-based.
I'm not writing this comment to say that you're wrong; the method you describe may very well work well for you, and many others with you. Rather, I'm using the opportunity to spread an opinion that I feel quite strongly about: the best way to learn a topic is completely student-dependent and there is no such thing as the one true way in which a topic should be taught. The most powerful motivator is always intrinsic motivation, and different minds are motivated by different challenges. Unfortunately it is hard to bring into practice in a batch-processing based education system.