Hacker News new | ask | show | jobs
by jbandela1 728 days ago
> One can roughly divide mathematical education into three stages:

Similarly with programming.

1. Write programs that you think are cool

2. Learn about data structures and algorithms and complexity and software organization.

3. Write programs that you think are cool. But since you know more, you can write more cool programs.

If things are working as they should, the end stage of mathematics and programming should be fun, not tedious. The tedious stuff is just a step along the way for you to be able to do more fun stuff.

7 comments

It's kind of like how people who are really, _really_ good at something approach it with a certain simplicity and straightforwardness. Superficially, it looks like how a novice would approach things. But look under the covers they are doing similar things but with a much deeper understanding why they are doing things that way.

Example, (1) You start programming with the simplest abstractions and in a concrete way. (2) You learn about all the theory and mathy stuff: data structures, algorithms, advanced types, graphs, architecture, etc. Eventually you become very skilled with these, but at a certain point you start to bump up against their limitations. Technical disillusionment and burnout may set in if you are not careful (3) You return to using abstractions and architecture that are as simple as possible (but no simpler), but with a much deeper understanding of what is going on. You can still do very complex stuff, but everything is just part of a toolbox. Also, you find yourself able to create very original work that is elegant in its seeming simplicity.

I've noticed the same thing in other fields: the best approach their work with a certain novice-like (but effective) simplicity that belies what it took for them to get to that point.

Or alternatively:

1. Programming in very concrete/practical terms because you do not know how to think in precise and abstract terms (do not know math)

2. Thinking more precisely and abstractly (more mathematical way)

3. Only do some key important abstractions, and being a bit hand-wawy again in terms of precision. The reason: important real-world problems are usually very complex, and complex problems resist most abstractions, and also being totally precise in all cases is impossible due to the complexity.

All-in-all it is due to increased complexity in my opinion.

Example: 1. Writing some fun geometry related programs 2. learn about geometry more seriously 3. write software based on a multiple hundred thousand line CAD kernel.

Other example: 1. Write fun games on C64 2. Learn about computer graphics in University 3. Contribute to the source code of Unreal Engine with multiple million lines of code with multiple thousand line class declaration header files.

This is true but I think it's iterative, cyclic. It applies to any art and craft, really. You alternate between perceiving and projecting, receiving and creating.
Any skill really. You alternate between theory and practice.

For example in sports you play for fun, then do some coaching to get better, then play for fun using your new skills and so on.

Yes -- I also wonder if a description involving learning plural software languages might fit:

1. Hack programmatic-functionality in a first language

2. Master the intricacies of a first language, understanding all programmatic concepts through the lens of that languages specific implementation-details. Pedantically argue with those familiar with different language implementations, due to a kind of implementation-plurality/ essential-form blindness

3. Learn additional languages, and 'see past' specific implementation details and pitfalls of each; develop a less biased understanding of the essence of any task at hand

> 1. Write programs that you think are cool

> 2. Learn about data structures and algorithms and complexity and software organization.

> 3. Write programs that you think are cool. But since you know more, you can write more cool programs.

Hegel :-)

Also (in C++ lingo):

1. Start by writing programs with vectors and maps.

2. Learn all about data structures, algorithms, cache misses, memory efficiency etc

3. And then write programs with vectors and maps.

> 3. And then write programs with vectors and maps.

But the maps this time are absl::flat_hash_map (or another C++ alternative hash map such as Folly F14, etc) instead of std::map (or even std::unordered_map).

Also in Haskell:

1. Start by doing everything in ReaderT Env IO

2. Learn all about mtl (or monad transformers, free monads, freer monads, algebraic effects, whatever)

3. Do everything in ReaderT Env IO

> 3. Write programs that you think are cool. But since you know more, you can write more cool programs

The integration phase goes much deeper. The first stage is about learning how to write programs. The second is about writing programs well. The third is to intuitively reason about how to solve problems well using well-written programs; you can still code, but it's no longer where the lifting is.