Hacker News new | past | comments | ask | show | jobs | submit login

This is the first time I'm reading pseudocode of an algorithm before it is explained what the algorithm is supposed to do.



I'd like if this were the norm. I found the pseudocode much more readable than the mathematical description of what it was supposed to do.

I'm (obviously) biased as a programmer rather than a mathematician but sometimes I think the study of mathematics would benefit tremendously from the same kind of "readability is more important than conciseness" thinking we have in software development.

Here's my proposal for a "contributing style" for mathematics:

Don't use short cryptic variable names like "wt". Do use informative full variable names like "weight" and "step".

Don't use a subscript for something like "step": it's just tiny and hard to read, especially once you start doing math in it. You have a series and you want to talk about the nth element? Use programming like array indexing, "weight[step]". It has the added benefit of being writable in pure ASCII without a math formula editor.

Don't omit your binary operators, e.g. "wt(1 + G)". Write it out: "weight[step] * (1 + reward)". You only write your formula once, but it will be read many times. Saving 1 character is not a win in total, especially not when it creates an ambiguous reading (are you using the function wt on 1 + G or are you multiplying? No way to know without resolving wt which can involve backtracking in the text for your reader.) Optimise for reading, not for writing.

Don't use sigma for sums. Again readability trumps terseness. Instead of "S" with a little "t from 1 to T" and a formula like "Rt/B" on the right, just write it out: "sum(R[t] / B for t in range(1, T))".

Actually it would be neat if there existed a Chrome or Safari extension that converted math notation to pseudo-Python. It wouldn't be able to assign sensible variable names automatically but at least it'd save me so much time and leaning in to stare at tiny subscripts.

I might be exceptionally lazy but sometimes when I read a math paper and the dense piles of tiny script formulas begin to pile up my eyes just glaze over even that in theory I understand every component. It's just so much effort to mentally parse it. Like reading sample code in assembly. If readability was improved I'm certain me and others like me would finish reading many more papers and we'd all get a little smarter.


Problem is you can't efficiently do everything math needs to do if you write out everything like that. Notation is designed for the efficiency of reasoning after you've fully absorbed the ideas being expressed.


Right. You could define functions. The function itself is stated in a readable form yet it is concise when later called upon. And just like you desire, this gives the reader a chance to first absorb the idea being expressed by the function (in clear pseudo-code), without making your expressions later overly verbose.

The counterargument might be "but then it's harder to break it down again into components when doing algebra". But that's no different from substituting in identities as needed. Substitute in the function body whenever you need to. As long as you don't need to, don't and you both have concise writing and reduced cognitive overhead. Each time the user sees a function they have previously mentally absorbed and understood they don't need to re-read it in detail to confirm it's still the same idea.


> And just like you desire, this gives the reader a chance to first absorb the idea being expressed by the function (in clear pseudo-code), without making your expressions later overly verbose.

This is already the case in math, just with a combination of English and algebraic notation and pictures, whatever is best to convey the idea. Either way, it seems orthogonal to your complaints about notation. I'm saying that pseudocode (as I think you mean it, pythonesque) is not nearly expressive enough to convey the ideas that mathematical notation conveys. It really does help reduce cognitive overload to distinguish two parameters, say one depending on time and one depending on position, by putting one in a subscript. (And that's still at the base of the ladder of abstraction) Sigma notation is one particularly helpful example, far more compact and easier to analyze than a for/while loop. (And, for what it's worth, list comprehensions come from mathematical set-builder notation)

I'm not saying math is perfect, but having spent a lot of time doing both math and software, I like to think I understand the reasons for the pitfalls of both fields relatively well.


Math notations allow for many transformations and operations on the expressions that pseudocode and most programming languages simply don't permit, or render as clearly.

Even within programming languages, consider the matlab notation for summation versus the (prototypical) algol-esque language notation:

  sum(vec)
vs Python's (naive approach)

  sum = 0
  for val in vec:
    sum += val
or in C

  sum = 0
  for(int i = 0; i < vec_length; i++)
    sum += vec[i];
Where vec_length has to be independently passed around since C's arrays don't have a notion of length.

The first is a clear expression of the fact of what is happening (like sigma in typical math notation), but the second and third are only clear due to being 3-lines long each. A more complex kernel or stepping function and the reasonability of these expressions disappears. Even those in Python-land have recognized the flaws in the naive approach and developed numpy and other solutions that allow for a closer semantic connection between the language (python) and the desired expression (mathematics).

See http://wiki.c2.com/?ArraySumInManyProgrammingLanguages for even more examples from numerous programming languages. Few of these lend themselves (as the expressions grow in complexity) to the manipulability and reasonability [0] of mathematical notation.

Languages of all sorts allow for different tradeoffs of expressibility, conciseness, manipulability, ease of acquisition, and other features. Mathematics has, predominantly, chosen conciseness and manipulability over ease of acquisition. But it would be nearly impossible to write a computer algebra system that took a textual version of math expressed in python and conducted the sort of automated manipulation and analysis that can be done to textualized forms of mathematical expressions.

[0] Reasonability: Here I do not mean that python is more or less reasonable than math in the typical sense. I mean in the ability to consume the information expressed in either form and then reason about it. A page (or pages) of code needed to express the computations on geographic datasets here at work, versus the 20 lines of math we have on the whiteboard.


I'm not sure I follow.

sum(vec) is exactly how I'd write it in Python (or pseudo-Python for that matter). It does what you think it does (provided the operation of addition is defined for vectors). I did mention using "sum" instead of "sigma" (combined with a list comprehension) in my OP, did you miss that or are you making a point I don't understand?

I recognise what you say about mathematics favouring conciseness. I feel that's what I'm addressing: mathematics have sacrificed readability in favour of conciseness to an extreme and could benefit from some decompression. It is possible to write extremely concise code but I feel most programmers today agree that's actually not a good thing to do. It's often better to write something a little longer to improve readability than to save those characters.

And like you write, every language, and we can consider mathematical notation to be a language in this context, has tradeoffs. But it's not a zero sum game. You can make an overall better language than another language. And what I like to imagine here is that perhaps mathematical notation is not the most evolved form of logical expression we have today. It's certainly not as formalised or field tested as the big programming languages.


I think you have to ask why mathematicians make that tradeoff. I argue it's for a good reason: the long-term efficiency gains for a working mathematician are higher than if they spelled everything out all the time. I'm using a made-up but illustrative example. Imagine reading

inducedHomology(fundamentalGroup(OnePointCompactification(Projectivization(RealAffineSpace(dimensions=2)))))

as just one object in a formula involving many such objects (like a long exact sequence which can contain 10 or more, each with a set of functions mapping between them!). You would get lost.

Then you say "okay, we'll come up with some nice alias for Projectivization(RealAffineSpace(dimensions=2)) and just call it RP(2)". Then it's still too long so you shorten inducedHomology to a prefix "" (not unheard of for programmers, cf pointers). Then you are left with "fundamentalGroup(OnePointCompactification(RP(2))", it's still long, and you realize that you just reinvented the standard math notation, which is like H^*(pi_1(RP^2)) with a line over RP^2, and you realize that while the shortened syntax is parseable by an interpreter, it's not actually any clearer.

You don't start to see the limitations of "let's just use python pseudocode for everything" until you actually try to use it for everything. When you realize that most math isn't done with a text editor (how would you do, say, geometry or topology?), you realize that the vim/emacs tricks programmers use don't apply. This is especially true because there are far more math concepts that need distinguishing than ASCII allows for. Think about how much code is required to translate trivial business rules into code. Math is orders of magnitude more complicated. It's just not worth the time.

Mathematicians also have one benefit pseudocode would destroy: the ability to point to something and declare a new semantic meaning. This is the heart of what it means to be mathematical notation, and software does everything it can to resist that.


Maybe you are right and there is some subset of mathematics so complex and lengthy that it becomes incomprehensible without a concise shorthand. I don't know enough about high level mathematics to refute that. I do know that the original article we are commenting on is not an example of that.

I do think by switching to code we don't need to lose the ability to declare new semantic meanings. But instead of inventing new ways to draw things, we can rely on our existing language. We define new functions. That's the beauty of having a standardised flexible language.

You write that mathematicians like to declare new notation. I think that's actually a liability. Like another commenter pointed out in this thread, mathematical notation is sufficiently freeform that there are different "dialects" in different fields of mathematics and it's not trivial to understand one even if you know the other. There is no formal definition, no formal grammar.

At the same time I just don't know if "H^ * (pi_1(RP^2)) with a line over RP^2" is actually better than inducedHomology(fundamentalGroup(OnePointCompactification(Projectivization(RealAffineSpace(dimensions=2))))) nor that it's desirable to want to compress it down to 6 small symbols. Obviously if you are going to use such a formula a lot, just like in programming, you'd "refactor" it into a parameterised function. Now you have reduced the cognitive overhead of understanding every use of this formula going forward. As a reader, you understand that function once and when you see it again you don't have to reparse it or scan for differences from previous similar incantations. DRY applies to mathematics too.

Expressing the math in code, to me, means to express it with a small library of primitives, unambiguously and formally. (Regular mathematical notation is ambiguous, like the multiplication example I mentioned, for example, and can define new primitives as it goes along.)

Now combine that formal code expression with best practices for programming like sensible variable naming, DRY and so on and I really feel there should be some kind of tangible advantage. (That's before we even start to think about the possibility of unit testing parts of a greater work. Have there ever been instances of someone writing a physics paper and having a calculation error somewhere deep inside?)

At the risk of paraphrasing you badly, you write that you just don't think it's worth the time to express all the varied mathematical concepts in code because the math is too complicated. I feel the opposite. Because it's complicated, it'd be good to take the time to express it plainly.


You only found the pseudocode readable because you know Python and don't know maths notation. It's not unreasonable to have to learn maths notation in order to read maths papers and blogs.

You aren't exceptionally lazy. You are normally lazy, and additionally not used to reading maths notation.


So I'm not a mathemetician, certainly not anymore.

But for a while I did read a lot of this stuff, and wrote things like it.

Aaand... to some extent you get used to it. But it really is simply a worse syntax. It's not just habit.

For one thing, there does not exist such a thing as "mathematical notation". There are a bunch of different, semi-overlapping conventions. You can't trivially read something someone wrote if the math was for another field. In fact, I'm pretty sure the variance is even larger than for most (seriously used) computer languages. It's easier for a pythonista to grok C++ templates than it is to read physics-inspired math with a modal-logic background.

This is particularly true when it comes to conventional symbols; there just aren't enough, or perhaps it's history, but there are different symbols for the same concept, and different concepts for the same symbol. Another pet peeve is subscripts - are those formally meaningless tags to distinguish variations the author talks about? are they arguments of some other class (think type arguments vs. value arguments)? Are they something elses? It's quite common for articles to use various forms, and sometimes even on the same symbols; for an example (albeit with superscripts) you probably know: X^T as a transpose, but X^2 as a power.

Then there are things like context sensitivity. It's not uncommon for some notation not to be self-contained in the sense that an expression depends on some variable, but that that variable is never specified in the expression itself. It's taken for granted you know which those are, and that can get quite tricky. It's the mutable global state of programming.

Mathematics could definitely benefit from a more disciplined and rigorous approach when it comes to notation, at least, IMNSHO.


I agree and this was my first thought too. Yet I feel like I do know the mathematical notation. I know what each "thing" does and yet the whole feels needlessly dense.

I definitely agree that once you are "used" to reading the notation it will be faster. That said, just because it's possible to get faster at it, does that mean it's the best possible notation for the job?

In creating programming languages and using them for tens of thousands of man hours per day we have envisioned and tested a multitude of different ways to express logical ideas, formulas and algorithms.

By contrast, how many kinds of mathematical notation has humankind tried and actively used?

If the latter number is substantially higher than the former, how can we be so certain that academic mathematical notation is the best, most clear way to express algorithms and formulas?

I would wager that the amount of logic expressed in programming languages vastly exceeds the amount of logic expressed in mathematical notation, every day. More logic is both written and read in the field of programming, so the medium we express the logic in is more rapidly iterated on.

Again, I'm not a mathematician. I'm a programmer and so of course my opinion about what is easy to read and write is subjective and biased. Yet even thinking about it objectively in terms of "what did we work harder on refining", I think there's some food for thought here. Wouldn't the rapidly iterated and widely used form seen in programming languages be more finely honed and at a higher stage of evolution in terms of understandability and writability?


Then again, I feel you can kind of infer what will happen when the algorithm runs, just by looking at said pseudocode




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: