Good article. I would just add that Philosophy classes especially the more abstract 19th (Kant, Hegel, Schopenhauer, Nietzsche) and 20th century (Heidegger, Foucault, Mearleu-Ponty, Wittgenstein) philosophers are fantastic and often under appreciated tools for gaining deep abstract thinking skills that mathematics didn't teach me. Often times I've drawn on the modes of thought acquired from learning to read them when solving particularly difficult problems in software design and engineering.
I don't really buy it. I think practice with tackling bigger and bigger problems teaches you more about the need for the specific kinds of abstractions that are most useful for SE. When you get to problems that are too big to fit entirely in your head, you start realizing the absolute necessity for hiding implementation details, and when you work over time with other people using your code, the similar necessity for limiting the flexibility and expansion points in the libraries you write - i.e. not making things too abstract, in many cases.
So much of abstraction in SE is about chunk size - what's comfortable to fit in your head when thinking at any particular level - and minimizing surface area between modules, where enough experience with a wide selection of APIs to develop good taste is important.
Whereas I see a lot of mathematics as being about eliminating redundancy, seeing connections between things and reducing them to their most orthogonal and best factored form, with the minimal number of concepts; but with not a whole lot of concern for complexity specifically. The same approach applied to SE can be useful, but mostly only in central libraries that have the widest variety of uses. I'm thinking of collections in particular; there, you want a wide selection of querying and transformation primitives to make arbitrary data manipulation problems easier to express. But most libraries and APIs don't benefit from that kind of factoring; they are best approached from a UI perspective, looking at use cases and building in affordances that make all the common cases trivial, while making the edge cases possible. This makes them lop-sided and redundant, and probably would offend someone with a heavy mathematical orientation.
tl/dr: mathematical thinking is roughly the right kind of thinking, but practice of reading and writing code teaches thinking that's a better fit.
Reading and writing code does not teach you recursion. Certain abstract ideas fall into the domain of mathematics even if you can pick up some of them outside of a formal mathematical education.
Reading code using recursion certainly does teach you recursion.
Classification of ideas does not lend the classifier ownership over the idea. Ferns were around long before mathematicians.
(To a certain degree, I'm taking a devil's advocate position. I'm not arguing against the worth of mathematics. But not a lot of SE requires much mathematics; what I am specifically disputing is that teaching a lot of abstract mathematics necessarily results in a better software engineer than deliberate practice. Solving simple combinatorial, tree and graph search problems teaches you more about the practical uses of recursion than any amount of recurrence relations, IMO.)
I immediately rethought my assertion when I submitted but left it for argument. Like Picasso saying "computers are useless" to encourage deeper discussion. Mathematics lends rigorous proof, like with an induction proof. It takes a level of abstract thinking to decipher recursive code, the kind of training helped by a mathematics education. Software programming gives you exposure to existing abstractions but direct mathematics training gives rigor to developing new concepts. University disciplines, within the university, do have ownership over domains of knowledge. So computer science is really math and engineering.
Like philosophy, mathematics is about ideas. Understanding the underlying philosophical and mathematical ideas are enlightening and often practical. Benefiting from understanding these ideas or methodology does not necessarily mean I have to be good at the level of philosophical writing, or solving proofs.
Unfortunately, very little of software engineering involves new concepts; and when they are introduced, it's often ill-advised. It's usually better to build something out of two or three well-understood ideas that have stood the test of time in the industry than a single novel one, even if it's a lot shorter and less work for the initial implementer. There will be later maintainers who may not have had as much invested in their experience and training, and it's normally better for whoever is paying the bills that specific and exotic skills are not required on a continual basis.
New ideas really pay off when the constraints are such that conventional composition of existing ideas won't work well. But those situations are rare.
It might sound like I'm arguing against talented software engineers, or against education, training etc., but really it's just business pragmatics and economics.
I tanked at maths at school. I have no formal education after school. I don't know how or when I learnt recursion, but learn it I did. There are a few other things I learnt since then, like breadth- and depth-first tree traversals, shortest paths and so on. A lot I learnt from examples I found online. A lot of it I figured out myself. I can't even articulate how I do a lot of the things I do, but I do them. And they work.
That said, a lot of the higher-level stuff I learnt the hard way, like the difference between tiers and layers. That's abstraction. And it's why I disagree with Keith's post in general, and this comment in particular:
"...mathematics was the only subject that gave them that experience..."
I don't need maths for 99% of what I write.
[Edit] I don't dispute that I'm doing it (mathematics). I do dispute that an expensive maths education is a requisite for good code.
Good of course is an interesting word - there's a difference between the best architecture, the right architecture, and a successful architecture. All can be termed as being "good" architectures, but no amount of maths is going to teach you the difference.
Back when I was developing web apps, I was surprised to hear that programming was supposed to require any math. But I've found that, as I've built more interesting and sophisticated things, I needed more math. I took about 15 math courses in school, and I can't think of any I haven't found useful.
Lately I've been looking at using model checking in my work, which touches on much of the math I know. Advanced logic to give a specification, and automata theory to run it. Group theory to express symmetries that let it run orders of magnitude faster. Add a bunch of real analysis and statistics if you want to do it probabilistically. Apparently number theory crops up too.
Meanwhile, a friend of mine develops ImplicitCAD, a programming language for making 3D objects. How does he test whether his 3D models have holes? Algebraic topology.
Model checking is a pretty cool idea, except you really need to have it built into the language rather than as an annotation or seperate system. Maintaining a seperate model just gives you two places to make typos.
Conversely, it gives two opportunities to avoid not only typos, but "thinkos". Simple declarative definitions can often define the results of complicated algorithms. Algebraic topology is actually a nice example. Presumably a surface has no holes if and only if any loop on the surface can be contracted to a point (given appropriate definitions of all these terms, of course). While this equivalence is easy to verify,
def has_holes(s):
for c in all_loops(s):
try:
contract(c)
except:
return True
return False
isn't an effective algorithm (e.g., "all loops" is an infinite set). But algebraic topology shows how one might instead reduce the problem to computationally tractable linear algebra. Suppose, then, that you've implemented an (presumably nontrivial and therefore error-prone) algorithm to carry out this reduction. Then your patently correct constraint on all loops might be a useful source of tests.
(disclaimer: I know nothing at all about computational algebraic topology, except that it's fascinating. So please take my example with an unbounded grain of salt.)
It's actually quite simple: A surface has no holes if its Euler Characteristic is 2. Since 3D objects are already expressed in a triangulated form, this is quite easy to check.
I've used calculus for physics simulations in games.
I had to do a bunch of performance analysis, and a little bit of knowing what distributions actually meant helped a lot. I regret not having taken more statistics in college.
I was talking with a philosophy prof once, and somehow we got to DeMorgan's theorem. "I use that nearly every day," I told him, and it kind of floored him -- apparently he considered it "advanced" logic.
I used DeMorgan's laws when refactoring Boolean expressions for clarity long before I learned that the laws had a name - they're entirely obvious and self-evident. I think the relative pointlessness of specifically classifying and naming them makes knowing of them by name obscure.
These ideas are named to honor the person who did much of the grunt work to get them proven/accepted, but we continue to use the name as a convenience.
If you're working with educated people, it's a lot easier to say, "apply DeMorgan," than to say, "why don't you negate the clause, remembering to negate each of the internal clauses, and switching the and's to or's and vice versa."
There exist people who use the names to sound intellectual, and these people are annoying, but just because some people enjoy spouting (in the general public) "obscure" rules and names, that doesn't mean that using such names is without value.
In this case you could come up with a short name for it that doesn't refer to a person -- you could call it "logical duality", since, after all, it is both logical and a duality. But people know it as "DeMorgan", and in this context I think the most important thing is being understood. Those who don't know the law probably wouldn't recognize it if you called it "logical duality" either.
In the design of programming languages one can let oneself be guided primarily by considering "what the machine can do". Considering, however, that the programming language is the bridge between the user and the machine --- that it can, in fact, be regarded as his tool --- it seems just as important to take into consideration "what Man can think". (Dijkstra [1])
And this is why mathematics is useful to software engineering.
I had to puzzle it out the first few times. Then I found in a college course on hardware design that the rule was named after some guy, which I found gratifying.
I remember having quite a time doing a doubly-linked-list, the first time I had to think it through. Always wondered why that wasn't named after some bloke . . . :-)
Even obvious and self-evident theorems are still useful. The first theorem of graph theory is almost trivial. (If you add up all the degrees of the nodes in a graph, you have 2 times the number of edges.)
I can't imagine in what context that would be considered "advanced" logic. Getting a working knowledge of classical[0] logic is very simple; the only thing that tends to surprise people is the notion of a vacuously true conditional.
[0]By which I mean, Boolean, true/false, the sort you can use truth tables for. I.e., classical logic as opposed to, say, constructive logic. I don't mean, like, ancient Greek logic or whatever, which I'm told actually is pretty limited. Maybe he was coming at it from that perspective?
Philosophers generally do. It's mathematicians and the like who have actually run with it for very far. Though I did take an interesting advanced logic philosophy course once, learned a few three-valued logics.
I'm doing a math PhD and I feel ambivalent about this statement even for myself.
In Devlin's article, doing math is conflated with a formal education in it. He should know better as he has previously endorsed heavy criticism of the latter: http://www.maa.org/devlin/devlin_03_08.html
"...our present system of mathematics education is precisely this kind of nightmare. In fact, if I had to design a mechanism for the express purpose of destroying a child’s natural curiosity and love of pattern-making, I couldn’t possibly do as good a job as is currently being done— I simply wouldn’t have the imagination to come up with the kind of senseless, soul-crushing ideas that constitute contemporary mathematics education." (pg. 2 of Lockhart's article)
An interesting article, but built on the assumption that until a certain age you won't have any exposure to software engineering which wasn't true even in 2000. As a middle-schooler my programming ability was ahead of my math ability and I think I actually found math easier because of it. Stuff like numerical integration were things I "discovered" playing around with computers and I think that learning was much more valuable than later learning it calculus class.
He has a point, but after learning about the numbers and basic arithmetic you certainly have enough knowledge to learn to code, and who really knows if you need to know more math than that.
The best part of mathematics is learning how to reduce something into a solved instance of something else. Recognizing when things are the same in abstract. Very hard to do.
As for the question. In english we have many words for those people who work on buildings and even cars because both go back thousands or hundreds of years each. So we have janitors, masons, carpenters, plumbers, architects and civil engineers. Each word clearly delineating a different expertise and scope.
Cars are newer so we have mechanics, automotive engineers and mechanical engineers. No one asks if the mechanical engineer or the mechanic needs math. The answer is obvious and contained in the Words. Electricity is from about the same time as cars and it too has electricians and electrical engineers. Not as many as houses but no doubt with more variations than common vocabulary implies.
Software has words like programmers, computer scientist and software engineer that are overly broad, ambiguous and interchanged indiscriminately. Leading to arguments about what really should be tautologies. I expect in time there will be terms like plumber, detective, architect, scientist, archaeologist and engineer for software and they will all mean something. And the subject will no longer be new and such questions will no longer be asked.
EDIT: I'd also like to chime in for it depends. If you are building a CRUD website it depends. For example: It depends on if you want to A/B Test your site in a non cargo cult manner. It is important if you want to compare A/B Test to multi armed bandits within a general framework. In general, you can only know not enough math.
I am an electrical engineer by schooling, but now work as a software engineer. I have done quite a bit of higher math in school, but in my career, I find that basic math is more useful. Interestingly, although I know some higher math, software engineering requires intuitive understanding of basic math, which some of us skimmed over while cramming for calculus exams.
Depends on what problems your tackling. If your doing a basic crud website then no. However if you want to analyse customer data on that crud website, and provide recommender systems for it then yes.
The thinking is similar too, they're not isolated.
I personally think a large amount of value is in using artificial intelligence, machine learning and statistics to analyse data to optimise a business. I think future grads should be focused on that.
I don't have a formal CS education, but most of the algorithms, i find that i can find analogies from whatever math i learnt back in school and college. I didn't major in math either. I just had a Mech. Engineering degree. One difference is that when i was in school, i ended up learning math in two different languages. My school used English, and in my free time i was bored enough to pick up and read my dad's classroom textbooks(in my mother tongue Tamil). Currently i work as a s/w Engineer and would agree that a full-time formal math training is not necessary in the current marketplace. OTOH, I also have moments, when i do wish i had seen a consequence a lot earlier, before expending so much effort. And think those would be reduced by a good math training.
I suppose that depends on how one defines "engineering". I consider engineering to be a way of formalising methodology to get consistent, repeatable, and verifiable results. My opinion on this topic is based both on this view of engineering as well as experience having worked at different times as an electrical engineer and software developer. I would say yes, mathematics is indispensable for good software engineering, although it certainly isn't the only requisite skill to meet the above definition (nor always the most important).
I think the key difference here is differentiating between a "software engineer" and a "programmer." It's a very blurry line, but the idea should shed some new light on arguments of the form "I've never used college calculus to develop web-apps, therefore math is useless for a software engineer."
This isn't meant to disparage programmers; I am merely saying we should take note when we have our "programmer" hat on, vs. when we're wearing our software engineer fedora.
I'd say I use some math but that would mainly be high-school level geometry (for game animation and graphics) and accounting math for some business apps. But I'd assume people who are tuning 3D engines and low-level code are dealing with math and algorithms all the time. Up higher at the application layer I think you can get by without too much math, although it never hurts to have the knowledge.
Interesting. Ultimately just one person's opinion. I don't use any college math (since I didn't take any) and dont't find a need for it in most programming. In fact, programming is a lot more like writing. Maybe that's why they call it a programming language. Too bad when I was doing programming using more interesting math, more interesting math was not taught in school (US 7th grade and on)
You don't seen to have gotten the point, which is that you use abstraction heavily when programming, and your abstraction skills are the expected and only result of your math lessons.