I do get the feeling that mathematics is made somewhat hard to approach for people who grew up programming computers by both the notation that’s optimized for writing on blackboards and some unspoken cultural assumptions made by people who worked their way up to the stuff without the notion that a lot of the things might get programmed into computers or be analogous to computer programs.
There might also be a bias in math for excessively clever analytical solutions for things for which a more verbose and straightforward algorithmic approach would do as well. A recent blog post compared an inscrutable closed-form formula for calculating the weekday of a date into a much more readable programming language function.
I wouldn’t take that as a very solid example though, in a mathematical sense, the calender system is a massively complex way to represent what is basically the number line. A lot of interesting math is about working with entirely new structures, instead of dealing with accidental complexity in established structures. The programming analogy starts to have trouble on two fronts here.
One problem is that new structures involve new formalisms, and programming languages are more about operating within an existing formalism. Diving into metamathematics by trying to keep things within one formal system when discussing another sounds much more headache-inducing than just doing the informal discussion of the new formal system that mathematicians do now.
The other problem is that the verbose variable names programming languages use, that are helpful when working with somewhat real-world phenomena, become much less useful once you dive sufficiently deep into abstraction. There might not be a better term for the operands of a suitably uncommon and abstract structure X than “things X operates on”, so the single-letter names are as good as any. (You don’t even have to go into strange theory for this, just see the higher-order functions from any functional language, like map or foldl, which operate on sequences of any values of the same type. Haskell calls the sequences x:xs for “current x” and “the rest of the exes”, which is pretty much all you can say about them from the context of the higher-order function.)
There might not be a better term for the operands of a suitably uncommon and abstract structure X than “things X operates on”, so the single-letter names are as good as any.
No, they aren’t! You can’t search to jump between the usages and definitions of a single-letter name, but you can jump between the usages and definitions of a full-word name, even if that name is blarghle.
Haskell calls the sequences x:xs for “current x” and “the rest of the exes”, which is pretty much all you can say about them from the context of the higher-order function.
Haskell can get away with this because it has strict, well-defined scoping rules which ensure that the names x and xs never appear too far from their definitions, and there is an algorithm which text editors can implement to find those definitions. Math books do not have either of those benefits.
Even worse than trying to search for single-letter variables that are defined somewhere in a mathematical text is trying to find the definitions of operators, if all you know is the squiggle used to denote that operator. For example, integrals are denoted by a slide-looking squiggle, so if you see one and don’t know it’s called an “integral”, you can’t look up what it means. If you do find a definition, the Wikipedia page you’ll get describes integrals as “the signed area of region bound by (the function parameter’s) graph”, with a full-page of explanation and links to 5 or 6 pages of supplementary explanation. Good luck translating that into code!
What you won’t find is the 5-line program that shows you how to actually calculate an integral (for that, see this page from SICP). Mathematicians descend into maddening vaguery when trying to describe concepts that could easily be described by a very short computer program, because math notation (and therefore mathematical study itself) lacks an equivalent of the for loop. So instead, mathematicians think they’re describing something so fundamental that it’s ineffable—Integrals, man! Integrals! Either you grok it, or you don’t.
Haskell can get away with this because it has strict, well-defined scoping rules which ensure that the names x and xs never appear too far from their definitions, and there is an algorithm which text editors can implement to find those definitions. Math books do not have either of those benefits.
Actually, they do, since x and xs are bound variables. Now, variable binding in mathematics is more complicated than it needs to be, but “forall x ”, “exists x ”, “f(x) =”, “d / d x”, “int … d x”, “sum_( i = 0 .. k)” … are variable binding operators, which are quite comparable to the Haskell syntax binding x and xs in the definition of foldr.
Haskell also has support for free variables bound by a closure, where the scoping rules are not so strict and well-defined. But I would expect Haskell programmers to use more readable names for these.
I’m taking note of the latter and adding it to my list of “books to read when I have time and motivation for independent education.”
The addition of Scheme to the application of mechanics does seem quite useful from what I can tell after a cursory look. And there’s a nice bit more mathematical rigor than I had the luxury of in my physics classes. Overall, it looks like this text takes an approach that I’ll like a lot, once I get to it.
For the record, I’m a physics and mathematics undergrad, graduating next May. My schools physics program recently decided to actually start making us apply that programming they had us learn; I might consider trying Scheme instead of C if I feel like it.
A recent blog post compared an inscrutable closed-form formula for calculating the weekday of a date into a much more readable programming language function.
This is a good reference for the “clever, analytical” bias in math, but “programming language functions” are just as formulaic; they just lack the obfuscation of a thoroughly optimized closed-form solution: For instance, the “serial number of a day in the year” can be phrased as follows:
daynum(d, m, y) is a function on natural numbers which is defined if 1 ⇐ m ⇐ 12. We will define it by induction on m:
If m = 1, then let daynum(d, m, y) = d
Otherwise, let m’ = m − 1 and l = monthLen(m’, y). Then let daynum(d, m, y) = daynum(d + l, m’, y).
Proof: see the blogpost.
The case analysis in monthLen can be expressed as is, whereas the leapyear predicate is a matter of style: neither of Van Emden’s C translations match intuition closely, but the following is reasonably intuitive and mathematically clear:
leap(y): A year y is a leap year when it is divisible by 4 and not divisible by 100, or else when it is divisible by 400.
In sum, there is no compelling reason for using C code here, except for it being easier to run on a computer: mathematical language can be just as expressive or more so.
Code has a few other advantages, though they aren’t actually being used in this case. You can type-check it, which does for some types of math what dimensional analysis does for physics. You can also bring it into automated theorem provers and verifiers, which is much harder for prose.
I do get the feeling that mathematics is made somewhat hard to approach for people who grew up programming computers by both the notation that’s optimized for writing on blackboards and some unspoken cultural assumptions made by people who worked their way up to the stuff without the notion that a lot of the things might get programmed into computers or be analogous to computer programs.
There might also be a bias in math for excessively clever analytical solutions for things for which a more verbose and straightforward algorithmic approach would do as well. A recent blog post compared an inscrutable closed-form formula for calculating the weekday of a date into a much more readable programming language function.
I wouldn’t take that as a very solid example though, in a mathematical sense, the calender system is a massively complex way to represent what is basically the number line. A lot of interesting math is about working with entirely new structures, instead of dealing with accidental complexity in established structures. The programming analogy starts to have trouble on two fronts here.
One problem is that new structures involve new formalisms, and programming languages are more about operating within an existing formalism. Diving into metamathematics by trying to keep things within one formal system when discussing another sounds much more headache-inducing than just doing the informal discussion of the new formal system that mathematicians do now.
The other problem is that the verbose variable names programming languages use, that are helpful when working with somewhat real-world phenomena, become much less useful once you dive sufficiently deep into abstraction. There might not be a better term for the operands of a suitably uncommon and abstract structure X than “things X operates on”, so the single-letter names are as good as any. (You don’t even have to go into strange theory for this, just see the higher-order functions from any functional language, like
map
orfoldl
, which operate on sequences of any values of the same type. Haskell calls the sequencesx:xs
for “current x” and “the rest of the exes”, which is pretty much all you can say about them from the context of the higher-order function.)If someone wants to experiment with this, I’d like to see how programmers who know little math get along with The Haskell Road to Logic, Maths and Programming and maybe what programming-savvy physics students with some advanced math skills get out of Structure and Interpretation of Classical Mechanics.
No, they aren’t! You can’t search to jump between the usages and definitions of a single-letter name, but you can jump between the usages and definitions of a full-word name, even if that name is blarghle.
Haskell can get away with this because it has strict, well-defined scoping rules which ensure that the names x and xs never appear too far from their definitions, and there is an algorithm which text editors can implement to find those definitions. Math books do not have either of those benefits.
Even worse than trying to search for single-letter variables that are defined somewhere in a mathematical text is trying to find the definitions of operators, if all you know is the squiggle used to denote that operator. For example, integrals are denoted by a slide-looking squiggle, so if you see one and don’t know it’s called an “integral”, you can’t look up what it means. If you do find a definition, the Wikipedia page you’ll get describes integrals as “the signed area of region bound by (the function parameter’s) graph”, with a full-page of explanation and links to 5 or 6 pages of supplementary explanation. Good luck translating that into code!
What you won’t find is the 5-line program that shows you how to actually calculate an integral (for that, see this page from SICP). Mathematicians descend into maddening vaguery when trying to describe concepts that could easily be described by a very short computer program, because math notation (and therefore mathematical study itself) lacks an equivalent of the for loop. So instead, mathematicians think they’re describing something so fundamental that it’s ineffable—Integrals, man! Integrals! Either you grok it, or you don’t.
Actually, they do, since x and xs are bound variables. Now, variable binding in mathematics is more complicated than it needs to be, but “forall x ”, “exists x ”, “f(x) =”, “d / d x”, “int … d x”, “sum_( i = 0 .. k)” … are variable binding operators, which are quite comparable to the Haskell syntax binding x and xs in the definition of foldr.
Haskell also has support for free variables bound by a closure, where the scoping rules are not so strict and well-defined. But I would expect Haskell programmers to use more readable names for these.
Some reasons that mathematicians use compact variable names are discussed here.
I’m taking note of the latter and adding it to my list of “books to read when I have time and motivation for independent education.” The addition of Scheme to the application of mechanics does seem quite useful from what I can tell after a cursory look. And there’s a nice bit more mathematical rigor than I had the luxury of in my physics classes. Overall, it looks like this text takes an approach that I’ll like a lot, once I get to it.
For the record, I’m a physics and mathematics undergrad, graduating next May. My schools physics program recently decided to actually start making us apply that programming they had us learn; I might consider trying Scheme instead of C if I feel like it.
This is a good reference for the “clever, analytical” bias in math, but “programming language functions” are just as formulaic; they just lack the obfuscation of a thoroughly optimized closed-form solution: For instance, the “serial number of a day in the year” can be phrased as follows:
The case analysis in monthLen can be expressed as is, whereas the leapyear predicate is a matter of style: neither of Van Emden’s C translations match intuition closely, but the following is reasonably intuitive and mathematically clear:
In sum, there is no compelling reason for using C code here, except for it being easier to run on a computer: mathematical language can be just as expressive or more so.
Code has a few other advantages, though they aren’t actually being used in this case. You can type-check it, which does for some types of math what dimensional analysis does for physics. You can also bring it into automated theorem provers and verifiers, which is much harder for prose.