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 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 calls for writing a compiler in Perl :-)
Woa