First, Jeffs view of programming is too narrow. Secondly, and more importantly, so is his view of math.
Being "mathematically inclined" does not mean being well educated in mathematics. You don't need to be able to rigorously prove the fundamental theory of calculus to be a good programmer. Most of mathematics does not directly apply to programming but the thought processes are extremely similar. If you see someone sorting papers and try to figure out why they are doing it inefficiently, that is mathematical inclination. Its about thinking in algorithms, not mastering differential equations.
He's created the strawman that a strong mastery of mathematics is required for competent programming. That is not whats been said. A strong mathematical inclination is a way of looking at problems that programmers and mathematicians share. Its about seeing "through" problems and finding solutions. Its about reducing problems to previously solved problems (or simpler versions of themselves), etc. I can list a dozen ways in which programmers and mathematicians do similar things.
But, playing along with the strawman, real math becomes necessary in normal programming fairly often. Not 3d, Jeff, even 2d. What's the distance between a point and a line segment?
"if we're going to talk about math, let's get out of the abstract and into the specific. Let's talk details. Examples. What could be more math-y than that?" (from the codinghorror post)
This topic seems to come up relatively frequently, and I appreciate Jeff's attempt to add to the conversation with some interestingly selected quotes. Still, the above quote to me highlights how many people, including Jeff, vastly oversimplify the math side of the equation. To put lbrandy's comment slightly differently, knowing a large number of mathematical facts will not make you a good programmer. But to me a basic explanation of “mathematical inclination” could be: a strong understanding of how a mathematical system is governed by rules, and how a problem can be parsed, compartmentalized, and addressed in pieces. It seems fairly self-evident to me that those skills would be shared by anyone whol could be described as even a competent programmer.
What's the distance between a point and a line segment?
let A, B be the 2D start and end points of a line segment. Let P be a 2D point.
We think about the problem and graph the problem like this:
P
.
A ------------------------ B
Then we realize that we can re-frame the problem in terms of a right triangle:
P
.
/ |
/ |
/ _|
/ | |
A ------------------------- B
Q
Now for some definitions. Let's define the vector operations that we'll be working with.
class Vec2( object ):
def __init__( self, x, y ):
self.x = x
self.y = y
This represents a 2D vector with properties 'x' and 'y'.
def length( V ):
return sqrt( V.x*V.x + V.y*V.y )
This computes the length of a 2D vector.
def normalize( V ):
V_len = length( V )
return Vec2( V.x / V_len, V.y / V_len )
This computes a new vector that points in the same direction as V, but is of unit length ( length( normalize( V ) ) == 1.0 ).
def dot( V1, V2 ):
return V1.x*V2.x + V1.y*V2.y
This computes the "dot product" between two vectors. I'll clarify this operation in a moment.
Finally, for clarity and succinctness:
V1 + V2 represents Vec2( V1.x+V2.x, V1.y+V2.y )
V1 - V2 represents Vec2( V1.x-V2.x, V1.y-V2.y )
S * V represents Vec2( S*V.x, S*V.y ), which
scales the vector V by a factor of S. So (2.0 * V)
would result in a vector in the same direction as V,
but twice as long.
Goal: find the length of PQ
First, we examine our graph above and write out the known and unknown quantities.
AB = B - A
AP = P - A
AB_len = length( AB )
AP_len = length( AP )
Q = ?
AQ = Q - A
PQ = P - A
It looks like our first step is to compute Q.
A dot product trick
The trick we'll use to solve this is via the following rule:
For any line that passes through A and B, dot( normalize( B - A ), P - A ) is the distance between A and the closest point on the line to P.
Huh?
Let me explain this thoroughly, so you can add it to your own toolbox for your entire life.
Building an intuitive understanding of vector math
Imagine a line segment AB and a point P. Now picture point Q, which is the closest point to P on a line that passes through A and B, just like the graph above. You can use the dot product to find the distance between A and Q.
First, compute the vector AB by computing (B - A).
You can visualize this as follows. Picture a line segment from point A to point B. Now move it so that A is coincident with the origin (0,0). Since you moved it, you didn't change its length and you didn't change its direction, just its location. So the result of (B - A) could be intuitively described as "a line segment that begins at the origin (0,0) whose length and direction are equal to AB's".
The next step in the dot product trick is to set the length of (B - A) to 1.0, which is "unit length". A few related trivia notes:
- if a vector's length is exactly 1.0, then it is called a "unit vector".
- when you set a vector's length to 1.0, you have just "normalized" the vector.
- normalized vectors are a succinct way to represent a direction in space, whether it be 1D, 2D, 3D, or any other D.
- remember the 2D line equation "y = mx + b"? 'm' is the line's slope. In 2D space, slope is just an alternate way of representing a vector's direction. You can compute a vector V's slope as "rise over run" (V.y / V.x). The only advantage of using slope to represent a direction in 2D is that it's efficient to compute and to use. There are two big disadvantages. First, it's not immediately clear how we'd compute slope in 3D. But more importantly, you can't represent vertical lines with a slope. A vertical line has no 'run', so (V.x / 0.0) == undefined. In programming terms, this could cause problems. So slope is generally avoided for those reasons. I explained it here because I am hoping that it helps you to understand vectors more intuitively.
So, let's enumerate some features of unit length vectors:
- they can be used to represent any direction in space.
- the range of each component of a unit length vector is never outside of [-1.0 .. 1.0].
- if you compute the dot product between a unit length vector and a point, you have projected the point onto the vector. The result of the dot product is the distance between the origin and the closest point on the vector. -- dot product trick
- the dot product of two unit length vectors is equal to the cosine of the angle between them. In other words, let V1 and V2 be unit length vectors. dot( V1, V2 ) == cos( angle between V1 and V2 ). Related facts:
-- the dot product of two unit length vectors is always in the range [-1.0 .. 1.0].
-- if V1 points in the same direction as V2 (that is, V1 == V2), then the dot product is 1.0.
-- if V1 is perpendicular to V2, then the dot product is 0.0.
-- if V1 points in the opposite direction of V2 (that is, V1 == -V2), then the dot product is -1.0.
-- And now, for something fun (and totally optional -- if you don't really understand, don't sweat it. But hopefully it will be interesting rather than confusing): Imagine a light bulb at point L. Now imagine a sphere at point S, being lit by that light bulb. Imagine a point on that sphere, P. You can compute the lightbulb's effect on the sphere at that point as follows:
L = lightbulb position
S = sphere position
P = point on sphere
Ldir = normalize( L - P )
surface_normal = normalize( P - S )
light_intensity = max( 0.0, dot( surface_normal, Ldir ) )
# that quanitity is called "NdotL" in computer graphics.
# you would then multiply that quantity by the light's
# "attenuation", which dims the light as it gets further
# away. But that's outside the scope of this example.
# If you're interested in computer graphics,
# the book "Realtime Rendering" is fantastic.
Solving the problem, finally.
So, let's use our newfound ninja-guru knowledge of vectors and dot products to solve the original problem. After glancing at the above graph again, we remember we need to compute the length of the line segment PQ. One way to solve it is to compute the point Q, then length( Q - P ) is our answer. Getting down to business:
def dist_point_to_line( A, B, P ):
# represent the line segment AB as a vector.
AB = B - A
# determine the direction of B relative to A.
AB_dir = normalize( AB )
# compute the distance between A and Q using the dot
# product trick. The first argument is a unit length
# vector. The second argument is a point *relative to
# that vector*.
AQ_len = dot( AB_dir, P - A )
# Now that we know the length of AQ, we can compute Q.
# To do this, think of the following equation as "start
# at A; move along the direction AB_dir by AQ_len units;
# that position is Q."
Q = A + AQ_len * AB_dir
# return the length of PQ.
return length( Q - P )
I hope the explanation was been illuminating, and not too confusing. If you have any questions, feel free to ask.
I got bad news. The question was to find the distance between a point and a line SEGMENT.
Luckily, since you know some math, and you understand what a dot product is, and how it relates to a projection, you can trivially extend your solution by checking to make sure Q is on AB, and then adjusting your answer if its not.
Ahh, yes. Good catch. In the algorithm, simply clamp AQ_len to be >= 0.0 and <= AB_len. (Notice that you compute AB_len as a side effect of normalizing AB.)
There's also the trick way to do it, namely the distance from (x0,y0) to the line ax+by+c=0 is |ax0+by0+c|/sqrt(a^2+b^2)
This has the advantage that it generalizes to arbitrary dimensions. For example, you can do it to find the distance from a point to a plane (|ax0+by0+cz0+d|/sqrt(a^2+b^2+c^2)). The math behind it is pretty much the same, except you're projecting onto a normal instead of onto the line itself.
>What's the distance between a point and a line segment?
I think I agree with you. I would argue that the mathematical ability needed to solve the question above is to realize how to phrase a query to google, find the resulting formula, and turn it into code. You don't need to be able to derive it, for the vast majority of jobs out there.
Also: I've noticed that most programming is equivalent to what in grade school and high school they called a "word problem". Most of the class would groan when we had to do these; I loved them. I suspect if you struggled with word problems, you would have a hard time programming.
phrase a query to google, find the resulting formula, and turn it into code
You left out the part where, months later, you pay a mathematically-inclined consultant hundreds of dollars to fix the bugs in the formula that you cut and pasted without understanding it. ;)
Numerical methods was a very interesting class, even on day one. You'd be amazed how easy it is to screw up simple formulas by doing the math in the wrong order -- the finite precision of floating-point arithmetic means that you have to be constantly on your guard.
>> If you see someone sorting papers and try to figure out why they are doing it inefficiently, that is mathematical inclination.
Not really, I would say it was a logical inclination not necessarily a mathematical one. And therein is the rub I see programming as logic and problem solving with little to no inherent math unless I am dealing with a mathematical problem. Kind of like the way writing books is not an inherently mathematical in nature even if quite a bit of math is involved in writing a mathematics text book.
This is bordering on semantics. What's the difference between mathematical inclination and logical inclination? The field of computer programming has made a separation in alot of people's mind that simply didn't exist before. People, especially programmers, view mathematics far too narrowly because they lack historical context.
George Boole was a mathematician. The logic textbooks are full of words that betray their background, e.g. the "lambda calculus". All of these things have their roots in mathematics. And before there was computer science degrees, these things -were- mathematics.
I doubt, very seriously, that Djikstra would draw much of a distinction between "logical inclination" and "mathematical inclination". So while you might, the original context of the quote in question needs to be considered.
Agree fully with lbrandy's point. Just to add a little more, people seem to get confused between the expression of mathematical thoughts and having mathematical thoughts. Mathematical symbols are abbreviations for ideas that, if expressed in natural language, would become tedious. Mathematical thinking is something people do everyday. For example, parents have to use combinatorial optimization everyday to figure out a best strategy for running errands. Few parents are schooled to a formal expression of the mental processes they go through in determining a solution but they weigh different goals and optimize nonetheless.
Oddly, a study that is all about exploration of ideas and abstraction has been narrowly defined in many people's minds. Hopefully mathematics educators can break these limited views in years to come.
What's the difference between mathematical inclination and logical inclination?
Logic is a strange area since it bridges fields, primarily math, philosophy, linguistics and computer science.
In my experience, designing software more frequently taps into logic as applied to philosophical arguments and conceptual formal logic more than heavily mathematical areas of logic. The reason is that creating software is basically the process of taking something from the real world and reducing it to a series of logical components and relationships. This is pretty much the exact process for applying formal logic to philosophical questions.
On the other hand, actually coding the software taps far more into the mathematical and linguistic aspects of formal logic, since it's involves piecing together units of mathematical logic to construct a logical machine.
In practice, this whole process is obviously more nuanced, interconnected and filled with gray areas.
It's also certainly possible to argue that all reasoning is math, but this isn't a new concept and dates back to Plato.
Maybe it's my engineering background, but I don't feel like this is semantics - it's unfair to categorize logical thinking as "mathematical" thinking. There are plenty of us from different backgrounds who are big on logic, and IMHO make great programmers. Mathematicians are far from the only ones who can think logically, and the term is at least somewhat misleading.
Uh, logic is a branch of mathematics. From wikipedia:
Logic is the study of the principles of valid demonstration and inference. Logic is a branch of philosophy, a part of the classical trivium, as well as a branch of mathematics.
Only by tradition, and in my experience the philosophy department only teaches the class that serves to introduce formal logic to all undergrads. Philosophers deal with words. They like to discuss the various ways a verbal problem might be reduced to logic, and they might be interested in what can be said (in terms they already use) about a system of logic, but that's the limit of their interest. If you take a graduate-level math class in logic (or metamathematics or foundations or whatever your local math department calls it) or even if you just take an upper-division set theory class, you'll learn more about mathematical logic than anyone in the philosophy department wants to know.
Most or all undergrad pure logic classes, as far as I've ever seen. There aren't usually a whole lot of pure logic classes, so it's entirely possible that your school(s) might only have had one.
Philosophers deal with words.
Philosophers deal with logic in arguments. I took a couple logic classes during my undergrad and they were entirely symbolic logic. I also took a couple philosophy classes, and they used symbolic logic extensively to describe the flow of logic in arguments. Skimming through MIT OpenCourseWare indicates it's similar there: http://is.gd/qaE0
If you take a graduate-level math class in logic ... even if you just take an upper-division set theory class, you'll learn more about mathematical logic
So you are saying that heavily mathematical logic is more heavily mathematical? Interesting. Do you also learn about tautologies in these classes?
I'm guessing that you are actually implying that mathematical logic is more useful to programmers. As I stated elsewhere, during my undergrad I took classes that touched on both philosophical and mathematical logic concepts and I definitely find myself using both. In my experience: symbolic/philosophical concepts in high level development, symbolic/mathematical concepts in low level development.
The distinction I'm making is between logic that is purely symbolic, where conclusions follow mechanically from assumptions and rules, and logic that is applied to verbal argument. You can describe verbal argument using symbolic logic, but applying symbolic logic to words easily results in ludicrous conclusions unless you apply other filters.
I'm not saying that mathematical logic is more heavily mathematical, I'm saying that philosophers are only interested in mathematical logic concepts they can extract from their mathematical context and apply in words. Aside from that, they are not interested in mathematical logic at all. Whether they are interested in mathematically defined concepts such as "complete," "consistent," and so forth depends entirely on whether the concepts have suggestive names that seem to imbue mathematical results with meanings beyond mathematics.
I'm arguing that the application of logic to arguments and ideas that was part of philosophy has greater impact on high level application design and architecture than math. Taking a real world concept, need or set of actions and translating them into a structure that can be constructed with a programming language uses logic in fundamentally the same way philosophy does, although in an academic setting this area is computer science. Math is most useful at an implementation level, generally coming into play when dealing with components, algorithms and other more narrow implementation details.
The point is that logic used in computer science/information science is a hybrid that is informed by other forms of logic (including linguistics), not just math.
I'm saying that philosophers are only interested in
I don't know what philosophers are only interested in because I don't know what a "philosopher" is.
I think I misunderstood you; I thought you meant mathematical logic (the kind that can be generated mechanically from axioms and rules) and not the kind of logic that requires judgment and applies to words and concepts. If you meant the second kind, then I retract what I said. But you did say, "formal logic, with symbols," and that kind of logic is a pretty weak tool to apply to arguments and ideas.
As for what a philosopher is, we're all philosophers, but not all of us get paid for it.
That raises an interesting question, doesn't it? I wonder how many mathematicians turn out to be good programmers vs how many philosophers turn out to be good programmers?
From experience, I have concluded that whether mathematicians become good programmers depends on whether they have an engineering aesthetic. Mathematical elegance and engineering elegance are not exactly the same thing. A mathematically trivial solution can be a huge practical mess. Mathematicians with no engineering aesthetic can't see the difference and tend to produce big blobs of unmaintainable code. Mathematicians with an engineering aesthetic are some of the best programmers I've worked with.
I've only worked with one philosopher. He's very creative and produces reams of working code, but new requirements always mean new reams of code. Everyone suspects there must be a lot of redundancy in his code, but then, nobody has needed to look, because it all works....
Why would you consider unfair to call logic thinking as mathematical thinking? Maybe it is the engineering background indeed, at least it is for myself. Maybe it was all those "engineering math" mandatory courses... you know, calculus, differential equations, linear algebra, statistics. If we keep thinking about math in terms of some sort of computation which ought to result in a numeric answer... then, absolutely, I agree that has nothing to do with logic.
However, least see what happens when one does not apply mathematical thinking into his own reasoning. I do it myself from time to time and refer to it as my "rat intelligence". You go over and over the facts, one at a time, trying to figure out the way out... It feels pretty much like a rat walking through a maze inside of my brain.
But it comes to a point, when the problem is very hard, that no matter how many times the rat goes over and over the same data, it does not find the answer. In that case you need a superior type of reasoning. You need to step aside and look at the problem as a whole. To find patterns that you can abstract out and rephrase the problem in a way more tractable. And I think in this broader sense logic and math use the same type of mental tools (principles) to attack the same issues.
Actually, all of those computations "which ought to result in a numeric answer" are done according to the principles of logic. Maybe I see it more clearly having taught myself calculus and more advanced math without having someone to "explain" things to me, but all mathematical problem solving is also logical reasoning.
Between any arbitrary point on a line segment, the point on the line segment that contains the shortest point, and the point in question, you have a triangle.
You can take the length between any point on the line segment and the point in space, find it's magnitude squared, and subtract the magnitude squared of it's projection along the line segment. This gives you the distance of between the point and line segment squared by pythagoras' theorem.
x
/|
/ |
/ |
-a****-----
a is the arbitrary point on the line, the *s are the projected segment, and x is the point you want to find the distance from.
I have not found in practice that programmers need to be mathematically inclined to become great software developers. Quite the opposite, in fact.
To anyone unsure about the above quote. Jeff is full of shit. Often he dances on the edge of wrong advice, today he has leaped over it.
You don't need to be a math whiz, but you damn sure need to be math inclined. At the very least you need logic. Any kind of graphics programming - math.
But if like Jeff your career consists of simplistic apps in VB, well then I still wouldn't call you a great software developer without math.
Don't aim to be at best average in your career, it makes for a shitty professional life, which is a big chunk of your whole life.
Thank you, HN. I started to comment on Jeff's post itself, but on the way down I saw so many people agreeing with him that I gave up in dismay. I'm happy to see the HN crowd has better sense.
All I'll say is, if you lack math background, then you may well end up doing things like making mincemeat of trying to explain NP-completeness. Just to pick a random example (heh).
I think that Jeff just takes math for granted. Without algebra, you would have a really hard time even understanding your run-of-the-mill business apps: order of operator precedence, the general notion of a variable, functions, etc. Let alone compound interest, expontential growth, etc. We're not talking combinatorial logic or multi-variable calculus here. If you complete your basic education in a first world country, you probably have some grounding in basic mathematics and logic, whether you realize it or not. Learning to program makes real a lot of these concepts that were probably sitting in the back of your brain unused for some time.
Graphics programming is a very small subset of programming in general. You're basically saying "all programmers need math because some programming needs math"...
There's plenty of cutting-edge stuff to be done that doesn't require an intimate knowledge of mathematics. I would have to say that being good at arithmetic seems to be pretty important in programming, though.
Graphics, physics, all my work in biotech, all my work in video edition, all work I've ever done. Vast sectors of programming are math intensive. There are few which aren't.
Also arithmetic and even more so logic pretty much = applied math.
Pattern recognition, control systems, encryption, image and video compression (discrete cosine transforms in JPEG, discrete wavelet transforms in JPEG2000) any type of simulation (e.g. SPICE for electronic component simulation, RF simulation for electromagnetism, finite element models for mechanical systems) ...
Any type of planning system requires math (e.g. convex optimisation, network routing, etc...) - these types of things have huge applications in areas such as industrial engineering and network routing.
Basically all the interesting parts of programming require math.
"Knowing even a little of the right kinds of math can enable you do write some pretty interesting programs that would otherwise be too hard."
(one of the Yegge quotes in the article)
I think this nails it.
It's a Blub thing. Jeff sees little use for Math because he does not know of any mathematical solutions for the problems he encounters. But...how can he think of a mathematical solution for a problem if he doesn't know very much Math?
Google, of course, relentlessly applies Math to everything they possibly can. I think that has worked out rather well for them. The flip side is that they might lose a good designer occasionally with good subjective judgment about hard to quantify things.
"It's a Blub thing" nails it even better, IMO. PageRank, MapReduce, the Amazon recommendation algorithm, clustering algorithms, .... inventing those required a solid knowledge of and comfort with mathematics.
Of course, strictly speaking this doesn't mean that mathematics is necessary to do great work. Other qualities - say a good understanding of community (think Flickr), or psychology (Facebook), or design (37Signals) - can be equally useful. But, yeah, that post has "Blub" written all over it.
But doesn't that quote at the same time draw the very distinction between math and programming that Jeff is talking about?
"Knowing some math can enable you to write some programs" - two separate activities, one benefiting the other. So, as a thought experiment, a non-mathematically inclined programmer with strong engineering / design aesthetics who implements an algorithm that has been prescribed by a mathematically inclined person may often produce a much better result than the mathematically inclined person would on their own.
Programming is related to and benefits from mathematics, but it is not only mathematics. It brings a whole range of skills into play.
I get the impression that Jeff is a much better blogger than programmer. And he's not my favorite blogger. I say this not just from his self-deprecation, which I've learned not to take at face value. But these weird non-sequitur "questions" he comes up with for article titles suggests he is not at an adult level of proficiency with his craft. Asking whether programmers "should be 'mathematically inclined'" is like asking whether movie directors "should be visually creative." They damned well better be, or go find something to do with their lives that is not a waste of their and their audience's time.
When I was, oh, twenty or so, I used to be one of those systems programmers who thought that the fanciest data structure I'd ever need was a hash table. If you write real code, that other human beings use, one of those humans will eventually use it in a way you didn't anticipiate. And in that use, N will suddenly be large! The user will expect your code to work, and with reasonable resource consumption. "Mathematically uninclined" programmers' code will die with large N, and they're not "inclined" to fix it.
I think that Mathematics is a much larger field than most people realize.
How can programmers not be mathematically inclined? Thinking logically about how to model and solve a system using abstract concepts. Computer science is a subset of applied mathematics.
Exactly. Jeff Atwood doesn't even mention recursion in the article once. Even he can't claim it's a highly specialized technique. I mean, ever try to walk through the DOM in JavaScript without recursion? Recursion is very closely related to induction, which in turn is a fundamental tenet of discrete mathematics.
I really should stop clicking on Coding Horror links on HN. Jeff is a very different style programmer than I am (and possibly a much better one). But his lack of understanding of the "other programming" is completely infuriating.
Thinking logically about how to model and solve a system using abstract concepts.
Which is often just as much or more in line with philosophical applications of logic than purely mathematical. As I noted in other comment, you could then argue that all philosophy and reasoning is basically conceptual mathematics, but people don't generally view philosophy this way despite the concept dating back 2500 years.
People don't view philosophy that way because philosophy never gets far from words. Philosophy and math started to fork at the point where people realized that substituting words into logical schema and then using logical transformations to create new sentences doesn't work reliably, and in fact doesn't really aid thought at all except by suggesting possibilities. At that point, logic became a philosophic failure, a dead end. A curiosity at best. There's still kind of a conceptual overlap; a philosopher might find it stimulating to think about the concept of N-value truth systems. However, he wouldn't think that mathematical theorems about such systems have any strict philosophical consequences. They would just be spurs for thought.
This was not the case at all where I did my undergrad, judging by the OpenCourseWare it doesn't appear to be the case at MIT and I would assume this is the same at any of the other major universities. Arguments were consistently and constantly described using symbolic logic and derivations.
I don't understand the animosity you have for philosophical logic. I've always felt it was an interesting compliment to what I did in computer science and it made me appreciate discrete math concepts to a greater degree. The fundamentals building blocks are the same, just a different application.
I don't have any animosity for philosophical logic, but I'm irked by the impression that mathematical logic's relevance to philosophy is as a tool of thought, i.e., that being a philosopher has some essential connection to being a practitioner of mathematical logic. Mathematical logic plays a similar role in philosophy that UML and design patterns play in programming. UML was hoped and perhaps originally intended (I don't honestly know) to be a powerful tool that could be used in CASE tools to accomplish programming in an easier and more reliable way than the clearly insufficient way that program now. It turned out that problems could be solved that way, but only after so much difficult "traditional" preliminary work that nothing was saved. By and large, UML is only used for documentation of patterns and high-level documentation of systems. You can undoubtedly program without using UML and patterns as tools, and people disagree about whether they are even useful.
In a similar way, it was hoped that a sufficient understanding of logic would enable one to reach philosophical conclusions more easily, with complete reliability. This sounds ridiculously naive to us, but we have the advantage of hindsight. At one time it was thought that with the investment of sufficient philosophical thought, logical rules of thought could be distilled and used to settle real problems. Unfortunately, it turns out that every application of logical rules requires so much examination of the validity of the application that little advantage is derived from logic beyond its ability to suggest and describe possible lines of thought, in the same way that UML and design patterns suggest and communicate but cannot replace the work of programming nor ensure the validity of resulting programs. Symbolic logic cannot be used to validate philosophical thought. To take an example of a deeply "logical" work, if you translated Spinoza's Ethics into symbolic logic, you would see nothing except some very trivial stuff and probably numerous errors. The profundity of Spinoza's work has little to do with logic in the mathematical sense. Once philosophers realized that, mathematical logic quickly became an ex-wife they had dinner with once a month. Never entirely forgotten, always thought of with affection, an important part of one's development, not without interest, but not looked to as a source of growth and vitality. You can certainly be a keen and insightful philosopher (though an ignorant one) without any understanding of mathematical logic, and a deep study of mathematical logic is rather useless for philosophy.
Now we muse about the "unreasonable effectiveness of mathematics in the natural sciences." At one time we hoped pure logic would help us decide questions about God and morality, and now we have learned to be surprised that it is useful for anything at all! Mathematical logic is an active field of mathematics, and philosophers have many problems to ponder, but there is no philosopher reading set theory abstracts looking for support in a dispute about aesthetics or ontology. Logic has become a branch of mathematics partly because it is necessary for mathematics and can be studied as mathematics, but also because no field outside of mathematics requires the solution of any complex problems in mathematical logic.
Even Godel's Incompleteness Theorem, while containing rich philosophical implications, did not actually apply to any philosophical ideas outside of math or logic because philosophers had long since given up using mathematical rules to "prove" or "derive" philosophical results. Philosophers were, as always, using language to express, justify, and criticize philosophical work. The use of logic as a tool for rigorously validating philosophical arguments, which was the original basis for the connection between philosophy and logic, is still a pipe dream.
I don't mean to denigrate either mathematics or anything outside mathematics by this. I have a math degree, but I'm the first person to admit that mathematical logic tells you nothing reliable about the relationship between "Every X is a Y, and Z is an X," and "Z is a Y." A proposition in symbolic logic can be derived mechanically according to its rules, but philosophy is uncertain and requires judgment. Mathematics is a useful tool for the natural sciences; in philosophy, mathematical logical is occasionally a stimulating subject for thought, but not a significant tool.
>The use of logic as a tool for rigorously validating philosophical arguments, which was the original basis for the connection between philosophy and logic, is still a pipe dream.
That's not strictly true. The Arab and Scholastic philosophers constructed a philosophical world-view, largely based on Aristotelian logic, which internally consistent fairly comprehensive. What resulted in its downfall, was not the failure of logic, but the desire for absolute truth. All forms of logic, whether mathematical or syllogistic, require argument from premises, which means that ultimately one must start with first premises that cannot be proved and must merely be agreed upon (making truth a matter of consensus.) Descartes tried to rectify this situation by assuming away all assumptions and proving first premises in a vacuum. He didn't get far (made too many logical fallacies) but he started a fad that overtook the philosophical realm and continues to this day.
My point being, that the problem wasn't the language (despite what the deconstructuralists might say,) which, if common and well defined presents no barrier, but changing ends in philosophical discourse.
From crazy Jeff's own comments, and his own mouth:
> I was writing an Asteroids clone in Flash a few years back, I wrote my own insanely complicated functions for calculating directional velocity instead of using SIN and COS
fantastic, LOL! This supports Steve's position -- it illustrates that you'd need enough math background to at least know in what general direction you should be looking. And save yourself some coding time and pain to boot.
Jeff Atwood on April 1, 2009 06:17 AM
I'm not qualified enough to comment on it. But I personally think Jeff is completely wrong. I'm a SDET (Test engineer) and am a history major. Couple of months back I asked people for math books related to computer science. I got some good feedback. I bought two books a)- What's mathematics b)- Discrete Maths by Susana App. I'm nowhere near a hardcore computer science student as I'm studying on my own. However, I've been able to solve recurrences, inductions and basic mathemtical proofs. I came across this beautiful function named "Ackerman function" and reading it was a pleasure. I don't take care of plants in my garden because it's necessary. I just do it for pleasure, literally. Same goes for maths though I'm pretty damm sure I will never able to do maths as good as Knuth but still.
I've a long way to go. But I've ordered some books on proving theorems. I don't intend to become a hardcore mathematician but I would just like to get through this once (just for the sake of pleasure). Here is a personal story a)Once I finished basic Discrete Maths I was writing a command-line based twitter client for personal use and using their API recursion just came as a natural choice (it was so natural that I had to think of how I did it after seeing my code running--believe it or not) b)- I'm fairly confident (and cautious) when I write recursive code now. I'm , by all means, a very average programmer but I would like to think that I've improved a bit.
I agree with Djikstra that learning your own language in depth is important for non-native speakers. Learning your language in depth widens your horizon and it creates clarity of thought. At least, I think it's important though I'm still a mediocre English speaker (yet).
When Dijkstra said what he did, programmers made computers process data in an environment with a very high data/cycles ratio, and doing that efficiently has a pretty large intersection with math.
Today, there are very few environments that has a higher data/cycles ratio than anyehere in the Apollo program in the '60, and most of the "hard" problems you'll run in to on a day to day basis have been commoditized - you'll be hard pressed to find a programming language where quicksort is even marginally hard to get to. Projects like My/PostgreSQL, Lucene and so on makes fulltext searches over very large corpuses of data crazy simple, even on consumer hardware. When I did a Scientific Computing project in college three years ago, we ran out of data long before our laptop fans came on.
Math matters in computer science, but tooling is moving the "competent programmer"-demography farther and farther away from the "computer science"-demography. And that is a good thing, just like the separation of programmer and user which happened in the early 80's (I guess)
Final thought: A former boss once told me, regarding education, that he knew plenty of very good, but no really great, programmers that didn't go to college for math and/or comp.sci.
Yes, competent programmers should be 'mathematically inclined' in a general way, not because high-level math is itself necessary for most programming but because 'mathematically inclined' is a decent proxy for the ability to manipulate abstractions, which is necessary for both math and programming.
"A Mathematician's Lament: How School Cheats Us Out of Our Most Fascinating and Imaginative Art Form" explains why there is a common misconception on what the mathematics is.
A complete prescription for permanently disabling young minds — a proven cure for curiosity. What have they done to mathematics! There is such breathtaking depth and heartbreaking beauty in this ancient art form. How ironic that people dismiss mathematics as the antithesis of creativity. They are missing out on an art form older than any book, more profound than any poem, and more abstract than any abstract. And it is school that has done this! What a sad endless cycle of innocent teachers inflicting damage upon innocent students. We could all be having so much more fun. </quote> ([pdf] (25 pages) http://www.maa.org/devlin/LockhartsLament.pdf )
"...to attack hard problems you need powerful solvents. I find math is a good source of metaphors good enough that it's worth studying just for that..."
I've had a personal experience with people (not developers) who couldn't understand the concept of simplifying equations. So it was "add 20%, +8, x 2," or something to that effect. I said "you mean x 2.4 + 16". Their response was "just do what we said." So I think a minimum level of math is required, just like a minimum level of language skills.
Would the code for the simplified equation be commented so that a business type who wondered why it was represented that way would understand what underlying expression went into the code?
I heard a scary story from a professor of economics who teaches business students. She said she talked about multiplying some value by 20 percent, and wrote on the blackboard "* .2," and then had students ask her why she wrote ".2" on the board when she had just said "20 percent." It probably avoids business logic mistakes to make the steps VERY explicit, so that the businessperson doesn't try to "correct" some error in the formula.
I remember working in a bank and a colleague having to explain operator precedence (multiplication over addition) to a "programmer" who did not understand why his program did not work. Scary to think about people like that writing software to handle people's money.
"Would the code for the simplified equation be commented so that a business type who wondered why it was represented that way would understand what underlying expression went into the code?"
Why would a "business type" be looking at raw source code? (unless maybe said code is in COBOL)? I am not being sarcastic, but I've found even good business folks, being lost in (what to my eyes was) very clean code.
I was wondering if it might be useful for subsequent programmer to be explain on the spot (as, for example, in an IM conversation--thanks for that follow-up) that the code is indeed doing what is desired by the business logic.
While I agree that programming and math are different fields, I have trouble believing that a great programmer would be unable to get through calculus (and vice-versa).
Another reason for the association of programming with math is that the two fields have an incredible intersection. As a math major, I took a lot of math courses that cross-listed with computer science or had a heavily computational component. Anyone who has taken numerical analysis or worked through the last third of the advanced algorithms book has seen the extent of this relationship.
There are huge classes of differential equations that can't be solved without programming. Same for optimization problems (the simplex method has to be one of the greatest intersections of math and programming in history). Simulation (and not just brain-dead random number slamming) has made it possible to solve probability problems that were unsolvable a couple of decades ago.
So while I tend to view math as domain knowledge for a programmer - ie., an area where you apply programming (like chemistry, real estate, acounting...), the relationship seems deeper and more natural.
One thing that comes to mind is SQL. I've met many programmers who avoid complex SQL queries and use a "select all, then for loop" approach. Creating a complex SQL query is pure logic a ka maths.
Specifically it's operations on sets. Trying to manipulate, in your head, many sets of information - with aggregation and outer joins - to yield a solution set is highly mathematical.
more specifically on relations, though most database schema in the wild are not really relational. I've personally found knowing relational algebra a great help in designing db s, formulating queries and so on.
Logic is not "a ka maths," it's very much interdisciplinary, and it's the bridge between math, philosophy, computer science and linguistics. That's why even something as simple as an SQL query uses concepts drawn from each of those fields.
No, this isn't a joke. This is straight party line Jeff Atwood. Atwood babbles about his pseudo "intellectual curiousity" all the time. Jeff posts a lot of strange stuff. I think Jeff doesn't know C nor any other non-VB, non-.NET language and doesn't really know how computers work and does not math and tries to justify this lack of knowledge on his blog. It's one thing not to know something. It's quite another to pat yourself on the back for not knowing it. But he does this with quite a lot of words, usually not his own. He does this with many other things too; for instance, he essentially applauded himself for not knowing or having any idea once explained what the phrase "begging the question" meant.
Yet, somehow he is making a living off barely visible ads and no real job that he discusses; surely Stackoverflow is not making that much money.
Yeah, I knew he didn't know C. I agree about SO being more popular or whatever than many YC startups. However, my point was just kind of to be surprised that he is making enough money as a full time blogger posting such nonsense. :)
A lot of useful programming tools are mathematical. Bloom filters, machine learning, and big-O analysis (especially with amortization) come to mind. A competent programmer should be able to dive into those things if needed. (Needing to study up on Wikipedia first is fine, of course.)
It totally depends on the type of programming. A lot of programming these days deals with business systems (after all, business tends to generate money. At least, I think that's the point). You may not need any kind of complex math to present interesting web applications or generate reports, or process credit cards. However, if you're in the business of developing applications to sell, or figuring the shortest path to send parts down a conveyor, or writing a compiler, you can see how you might need differing levels of complex mathematics. It all depends on your situation.
I do, however, agree with the point that in the general case, programmers tend to be able to learn quickly, and learn the types of things to help them with their current problem. But if you don't have a grounding to even know where to begin looking for answers, you have a bigger problem.
Certainly all programmers do not need heavy math skills. But it certainly never hurts. All things being equal, I know which one I would rather go with.
The problem is that what Dijkstra means by "competent programmer" is not what Jeff means. It's not just that they are talking about different levels of competence – they aren't even talking about the same discipline.
Dijkstra may have meant something like "doing meaningful work in computer science" or "solving algorithmic challenges". Jeff Atwood seems to mean something like "gluing libraries together to accomplish a business objective".
At the beginning of Jeff's post, it almost sounds like he has something interesting to say about the Dijkstra quote, but that's just because he confusingly uses the same word to mean something almost completely unrelated. As he says "the vast bulk of code that I've seen consists mostly of the 'balancing your checkbook' sort of math." I don't think that's quite what Dijkstra had in mind. Likewise, I suspect finding new algorithmic approaches to tough computational problems is not high among Atwood's interests.
I don't think you need to be mathematically inclined, but if you aren't then you probably won't enjoy programming very much (though you can certainly be competent at something without enjoying it). Not that daily programming involves a lot of non-trivial math, but for me programming is essentially a collection of little problems to solve, which I enjoy. Math, at least the parts of it I enjoy, is the same thing, a collection of little problems to solve.
Granted, this is coming from someone who enjoys math (the parts I understand anyway) and programming. I'd be curious to hear from someone who enjoys programming.
Er, if you are going to invoke Dijkstra, then you need to be aware of proving programs correct, and without at least a mathematical inclination, you are lost, no?
As one of my math teachers said once, mathematics' greatest advantage to programmers, or people in general, is to train the mind at thinking analytically. Most people who have a good background in maths won't necessarily use it everyday, but the process of learning and using it itself makes you think more rationally, and gets you used to solving difficult problems with whatever tools are available.
I think that the "right-brained" software engineers and programmers defended, especially in the comments, are probably why so much software sucks so bad. I think Dijsktra overstates the importance of "proving" in programming, but the necessity of mathematical type thinking for a clean design and a clean program is fairly clear.
Programming doesn't require much math per se, but almost all domains in which a computer can help do require math.
If you don't know any math you could waste your time rederiving concepts from first principles when you could just have learned the established theory.
If you hate math, and need a means to learn it forcibly, code video games, particularly 3D ones. The experience will probably break a few bones, but you'll come out learning more than you ever would have if you just kept writing webapps all day.
Three of the four members of the US's team to the International Olympiad in Informatics (IOI) last year also attended Canada/USA Mathcamp. Take from that what you will.
To be fair, the ability to solve very difficult algorithmic problems is not particularly related to the ability to do many, many different kinds of programming.
Being "mathematically inclined" does not mean being well educated in mathematics. You don't need to be able to rigorously prove the fundamental theory of calculus to be a good programmer. Most of mathematics does not directly apply to programming but the thought processes are extremely similar. If you see someone sorting papers and try to figure out why they are doing it inefficiently, that is mathematical inclination. Its about thinking in algorithms, not mastering differential equations.
He's created the strawman that a strong mastery of mathematics is required for competent programming. That is not whats been said. A strong mathematical inclination is a way of looking at problems that programmers and mathematicians share. Its about seeing "through" problems and finding solutions. Its about reducing problems to previously solved problems (or simpler versions of themselves), etc. I can list a dozen ways in which programmers and mathematicians do similar things.
But, playing along with the strawman, real math becomes necessary in normal programming fairly often. Not 3d, Jeff, even 2d. What's the distance between a point and a line segment?