Oops, there is a bug! Or at least, Knuth must be leaving something out about how parentheses in the original expression are handled. The example expression he gives in the paper, (X + Y) + W/Z, does have a pair of parentheses, and the scheme works fine on that example. But the parentheses there are in a place that doesn’t actually impact the result – the result would be the same if you wrote X + Y + W/Z.

But Joomy Korkut on twitter pointed out that this scheme can change evaluation order when the original parentheses actually matter: (a+b)*c gets rewritten to ((((a)))+(((b)))*((c))) which is not equivalent!

I’m curious whether there’s a fix for this case while staying in the spirit of quick-and-dirty text substitution. Will think about it a bit and update the post.

Edit: There is in fact a straightforward fix: add even more parentheses! To ensure the original parenthesized expressions continue to “contain” all their original contents without anything escaping, add another replacement rule: replace each ‘(’ in the input with ‘((((’, and each ‘)’ with ‘))))’ (similar to the ‘(((’ and ‘)))’ added around the entire expression). Post updated.

This rocks, I hate it so much, I need to tell everyone about this. Thanks!

Oops, there is a bug! Or at least, Knuth must be leaving something out about how parentheses in the original expression are handled. The example expression he gives in the paper,

(X + Y) + W/Z, does have a pair of parentheses, and the scheme works fine on that example. But the parentheses there are in a place that doesn’t actually impact the result – the result would be the same if you wroteX + Y + W/Z.But Joomy Korkut on twitter pointed out that this scheme can change evaluation order when the original parentheses actually matter:

(a+b)*cgets rewritten to((((a)))+(((b)))*((c)))which is not equivalent!I’m curious whether there’s a fix for this case while staying in the spirit of quick-and-dirty text substitution. Will think about it a bit and update the post.

Edit: There is in fact a straightforward fix: add even more parentheses! To ensure the original parenthesized expressions continue to “contain” all their original contents without anything escaping, add another replacement rule: replace each ‘(’ in the input with ‘((((’, and each ‘)’ with ‘))))’ (similar to the ‘(((’ and ‘)))’ added around the entire expression). Post updated.

This calls for writing a compiler in Perl :-)

Woa