There is a book called Concrete Mathematics and one of the primary authors is Donald Knuth, basically it's "Programmers math" and in my opinion, would make your average developer who completes the text into an exceptional developer.
Almost no one (outside of those who were friends with math majors) are actually familiar with the nature of proof-based mathematics. When you hold out "programming is math" the general public, policymakers, admissions offices, kids who might want to be programmers, etc. don't make the association to Analysis and Abstract Algebra, they make it to high school Algebra, Geometry, Algebra II/Trig, Precalculus, and (maybe, for the better kids at richer high schools) Calculus.
This has the effect of selecting programmers for their skill, patience, and diligence in executing the algorithms they're given. This is exactly backwards!
In my opinion, if you're looking for an analogy to a high school class, programming is chemistry. You're given a reasonable number of facts about the world, some lab and algorithmic procedures, and a problem. How to string together your intuitions, information, and procedures to arrive at an answer is entirely up to you.
I see the argument about chemistry, but I do think there's a very strong crossover of doing math and building software (in the large). In math, you begin with a set of base known statements. Whether starting from the axioms, or working within some system, you begin to build a vocabulary of the system, a feel of the way objects within the system interact, and an understanding of the limitations of the system you're currently in. Through the course of needing to get things done, you combine these various abstractions together to create more useful ones, constantly making your system a little bit more powerful. Often, taking steps back from your system and combining things into elegant ways gives insight into other patterns present in the system, and recasts solutions in slightly different lights with hints as to what they could have been, had you known what you know now. Then over the course of time, you begin to bring in new foreign systems, which you might not understand fully, and you use inelegantly. But again, working through issues, you build up that vocabulary and intuition to solve problems in your space, constantly putting tools and tricks into your belt on how things could fit together. Occasionally something will be insufficient in your tool belt, or a concept you weren't quite clear on will come up in your problems, causing you to go back, learn a thing, and come back armed ready to keep making progress.
To me, that all sounds like what I do when I'm building software.
Hmm...when I was a CS major, a discrete math course was required, and it was all proofs. I believe that is still common. I don't find the proof aspect that relevant to programming, but the concepts of discrete math, such as sets, graphs, definitely are.
As far as things that aren't programming go in relation to programming, contest math, with its focus on efficient and creative problem solving, is probably more similar to the daily experience of writing software than any course I took. The exception would be Math Modeling and other courses that actually required programming.
By Curry-Howard isomorphism proofs in some particular proof system are equivalent to computer programs.
Our high school experiences couldn't have been more different.
In math class we were given the definition of a limit and derived all of the rest of high-school calculus collaboratively from there. Similarly for high-school linear algebra: couple of quick axioms and then all further theorems and algorithms derived from there.
Meanwhile in Chemistry class they'd give me a failing grade because I failed to memorize the exact charges of the various polyatomic ions and solving the rest of the problem using variables in place of the charges wasn't good enough.
I have no dislike for logic, formal proofs, category theory and such: I can live in that world just fine. However, almost none of the problems I've ever had to dealt with in my 15 years programming made me wish for large amounts of that: I've used bits here and there, but going all in never made any sense.
The hard part of most tasks I had to do in professional programming is to gather enough information to even begin to write one of those formal specifications: Knowing what real business needs are, understanding how distributed systems fail, working around bugs, reading library code quickly and effectively, learning how to factor code in a way that would evolve well with changes in what the application needs to do... that's where the value is. 99% of that is talking to people and making educated guesses about the future: The implementation itself is trivial. With that, was able to get solid code working in languages that were ill equipped to handle any of the fun pieces of math that you'd need to write mathematically-minded programs.
If anything, the experience I've had working with people that were heavy on the math has been dismal. I worked with a rather well known dev who has published books, gives a lot of talks in FP circles, and is a lead dev in a huge mathematically driven library. We worked on on a rather novel distributed systems. He hid in a corner with a copy of Mathematica for a couple of months, and came back with a paper that proved a well performing solution to one of the things we had to do with our distributed system: Great!... Except, not so, because his proof only worked in a mythological environment where there is no latency between nodes. Under real conditions, the algorithm's properties led to unacceptable results, and he just hid behind the proof.
I don't have papers and patents behind me. He knows a lot more category theory than I do. But It took me a day to implement a completely unproven algorithm that had far better performance properties in a real case. This is not due to any special brilliance of mine, but because I sat down and approached the system like a scientist or an engineer would, instead of like a mathematician.
In my opinion, teaching the scientific method and the basics of engineering in other fields will serve your average programmer far better than being better at math ever will.
Formal mathematics training isn't necessary to be successful - many of us know many people who have picked up the intuition that those formally trained understand at a deep level & have been able to use it to great advantage. However, I argue that more training in areas of logic & reasoning would serve people well in all facets of their lives, including helping people be successful in software development over the long term. I know that I use my knowledge I gained from decades of mathematics to code strong abstractions faster than just about everyone else I have worked with so far (I've made mistakes too, but nothing terribly costly & unrepairable) - it helps me nearly every day I code & learn new things.
I saw a few people that had no problems with the math courses in CS but that never really got the programming part. (No names or details, people might be recognized.) But this is of course anecdotal.
(My surprise over this was similar to when I realized that rationality and intelligence didn't have as high correlation as I expected. I know some intelligent people which are Truthers and believe in other conspiracy theories. Others can't reason when their emotions are involved.)
> Great!... Except, not so, because his proof only worked in a mythological environment where there is no latency between nodes. Under real conditions, the algorithm's properties led to unacceptable results, and he just hid behind the proof.
Then he did a bad job. His failure does not undermine the power of taking a formal approach to a problem. He should have accounted for this latency in his initial model. What he did is the equivalent of someone working on an autonomous car and assuming that a noisy GPS signal is good enough to do control with.
Teaser:
"When DEK taught Concrete Mathematics at Stanford for the first time he explained the somewhat strange title by saying that it was his attempt to teach a math course that was hard instead of soft. He announced that, contrary to the expectations of some of his colleagues, he was not going to teach the Theory of Aggregates, not Stone's Embedding Theorem, nor even the Stone-Cech compactification. (Several students from the civil engineering department got up and quietly left the room.)"