I think the author missed the real point of literate programming - or I may be interpreting literate programming totally wrong.
In my opinion literate programming is really about optimizing for 'read/understand workflow' and not the 'execute workflow'. But I don't blame him, programming change quite a lot in the last 10 years.
Especially in the past a lot of people thought things like fast inverse square root[0] were the pinnacle of programming. Because they made something possible that was previously impossible. And culturally being 'clever' was generally used as a compliment. I think a good example would be ESR[1], a really smart individual who always enjoyed to push things to the limit and that would frequently involve quite a lot o hacking(in the original sense).
But as complexity grows we started to understand we should not rely too much in clever solutions because its hard and expensive to find someone that is smart. And even when you do, its nice to allow people to take some vacations every so often without creating disruptions in your company.
In this context I think literate programming is more about making software anyone can understand and change than it is about having a nicely typeset manual. When literate programming was proposed reading source-code created by someone else wasn't as easy as it is today. If you wanted to understand how something worked your best bet would be the manual provided by the author, today with modern LSPs you are generally one shortcut away from the actual source-code.
With that said, my personal interpretation is that literate programming is about writing code that doesn't need documentation (I think 'self-documenting code' has a bad reputation, but that is another problem). For a extremely contrived example you could look at the difference between 'x << 1', 'pow(x, 2)' and 'square(x)'. All three options should give you the same result. And even knowing that the first would probably always be faster I think 'square(x)' is generally the best option. Sure, I'm leaving performance on the table but if my instrumentation is reasonably good it shouldn't be too hard to find this line when we really do need this extra performance and then I change back and leave a comment explaining why we had to change to this less clear code.
In the end code should mostly be about intent. Just by reading the code I should be able to understand the business need that required this code to be created. DDD has this idea of unified language, that I think is pretty relevant here. In the DDD book there is a quite nice example about modelling a system that handles shipment contracts and needs to work with the concept of overbooking. The naive approach would be having something like "if (alreadyBookedCargo + cargoSize) > maxAllowedSize { return 'cannot book new cargo" } ' but if you change to something like "if !policyAllowed('overbooking', alreadyBookedCargo, cargoSize) { return 'cannot book new cargo' } " the code becomes easier to reason about.
Most people don't do this because this process is essentially 'just' naming things, and we all know how hard it is.
As the author of OP, I just want to say thanks for the comment. I don't disagree with any of it. I was experimenting with incendiary headlines 10 years ago when I wrote it, but perhaps a less incendiary headline is that others misinterpret Knuth by emphasizing typesetting over sequencing and structuring an exposition.
In my opinion literate programming is really about optimizing for 'read/understand workflow' and not the 'execute workflow'. But I don't blame him, programming change quite a lot in the last 10 years.
Especially in the past a lot of people thought things like fast inverse square root[0] were the pinnacle of programming. Because they made something possible that was previously impossible. And culturally being 'clever' was generally used as a compliment. I think a good example would be ESR[1], a really smart individual who always enjoyed to push things to the limit and that would frequently involve quite a lot o hacking(in the original sense).
But as complexity grows we started to understand we should not rely too much in clever solutions because its hard and expensive to find someone that is smart. And even when you do, its nice to allow people to take some vacations every so often without creating disruptions in your company.
In this context I think literate programming is more about making software anyone can understand and change than it is about having a nicely typeset manual. When literate programming was proposed reading source-code created by someone else wasn't as easy as it is today. If you wanted to understand how something worked your best bet would be the manual provided by the author, today with modern LSPs you are generally one shortcut away from the actual source-code.
With that said, my personal interpretation is that literate programming is about writing code that doesn't need documentation (I think 'self-documenting code' has a bad reputation, but that is another problem). For a extremely contrived example you could look at the difference between 'x << 1', 'pow(x, 2)' and 'square(x)'. All three options should give you the same result. And even knowing that the first would probably always be faster I think 'square(x)' is generally the best option. Sure, I'm leaving performance on the table but if my instrumentation is reasonably good it shouldn't be too hard to find this line when we really do need this extra performance and then I change back and leave a comment explaining why we had to change to this less clear code.
In the end code should mostly be about intent. Just by reading the code I should be able to understand the business need that required this code to be created. DDD has this idea of unified language, that I think is pretty relevant here. In the DDD book there is a quite nice example about modelling a system that handles shipment contracts and needs to work with the concept of overbooking. The naive approach would be having something like "if (alreadyBookedCargo + cargoSize) > maxAllowedSize { return 'cannot book new cargo" } ' but if you change to something like "if !policyAllowed('overbooking', alreadyBookedCargo, cargoSize) { return 'cannot book new cargo' } " the code becomes easier to reason about.
Most people don't do this because this process is essentially 'just' naming things, and we all know how hard it is.
[0] - https://en.wikipedia.org/wiki/Fast_inverse_square_root [1] - https://en.wikipedia.org/wiki/Eric_S._Raymond