19 comments

[ 3.0 ms ] story [ 47.5 ms ] thread
The "Parse, don't validate" paper is classic IMHO.

I disagree with "Don't put logic in tests", with the example provided being a problem with using strings where a URI type is needed instead. Perhaps the source of my disagreement is I hold that test code is production code due to test suite failure(s) during an automated build stops desired deployment.

Still, each are definitely worth delving into and determining applicability for oneself.

The Grug Brained Developer is one that always sticks in my head, but didn't make the list (to be fair, maybe more because I already agreed than because it transformed my thinking).

https://grugbrain.dev/

    “Choose Boring Technology” by Dan McKinley (2015)

    This is an odd essay to include in this list because I’ve never actually read it.

    People have quoted this essay to me, and once I understood the idea, it felt so intuitive that I didn’t need to read it.
This is such a strange thing to include and obviously a lie as he goes on to describe the essay in detail.
I just read "I've locked myself out of my digital life"[1] and it explains a concern that I have and sometimes struggle to explain.

> In the boring analogue world - I am pretty sure that I'd be able to convince a human that I am who I say I am. And, thus, get access to my accounts. I may have to go to court to force a company to give me access back, but it is possible.

> But when things are secured by an unassailable algorithm - I am out of luck. No amount of pleading will let me without the correct credentials. The company which provides my password manager simply doesn't have access to my passwords. There is no-one to convince. Code is law.

Everyone should understand this problem before they advocate to remove the in-person version of a process. The article's example sounds unlikely at first, but the same consequences can happen with any natural disaster or a robbery.

[1] https://shkspr.mobi/blog/2022/06/ive-locked-myself-out-of-my...

> Test code doesn’t have its own test code, so the only way to verify correctness is by inspection.

This is about as incorrect as it gets.

The only way to verify correctness is to change the production code in a way that should cause the test to fail, then watch it fail. In TDD this is done by writing the test before you write the code that would make it pass, then watch it fail. Only then are you allowed to write the code that makes it pass.

Otherwise you have no proof the test can EVER fail - which means no proof it adds value to your codebase.

Thanks for reading!

>This is about as incorrect as it gets.

>The only way to verify correctness is to change the production code in a way that should cause the test to fail, then watch it fail. In TDD this is done by writing the test before you write the code that would make it pass, then watch it fail. Only then are you allowed to write the code that makes it pass.

>Otherwise you have no proof the test can EVER fail - which means no proof it adds value to your codebase.

I agree that changing the production code to cause a failure can be helpful, but I think it's an overstatement to call it "the only way to verify correctness." When I optimize for simplicity, I rarely encounter tests that pass in situations I didn't expect.

Also, forcing tests to fail doesn't really scale. You can do it initially as you write a new function, but once you commit your changes, whatever you've learned from the exercise evaporates. If you change the function or any of its dependencies, presumably you're not going to repeat the exercise of forcing each assert to fail one-by-one. According to what you're saying, that means that there's no longer proof that the test can fail.

Concerning Fred Brooks "No Silver Bullet", I disagree on this conclusion:

> Modern AI has thrown a wrench into Brooks’ theory, as it actually does reduce essential complexity. You can hand AI an incomplete or contradictory specification, and the AI will fill in the gaps by cribbing from similar specifications.

The essential part is still not adequately covered by Generative AI, and probably never will be. Here is my detailed write-up about it: https://smartmic.bearblog.dev/no-ai-silver-bullet/

Perhaps a bit more of an unorthodox blog post, but Gilad Bracha's Ban on Imports really changed the way I think about module systems: https://gbracha.blogspot.com/2009/06/ban-on-imports.html

He talks about how imports and exports are global state, and that they have all the issues that global state brings. It's made me appreciate dependency injection a lot more.

(comment deleted)