Hillel on Tests
First read Hillel’s Some tests are stronger than others:
An integration test crossing modules A and B will imply some unit tests in A and some unit tests on B. If an integration test can decompose into a set of unit tests, it must be stronger than any individual test in that set. Similarly, an end to end test can be decomposed into integration tests.
And also:
If you already know there’s an error, a weaker test can be more useful than a stronger test, because it localizes where the bug is more.
Time
lim delta t -> 0 of immutable infrastructure propagation = mutable infrastructure lim delta t -> 0 of scaling up/down = perfect utilization lim delta t -> 0 of information propagation = ?
Self-serving Bias
Wikipedia has this to say about self-serving bias:
A self-serving bias is any cognitive or perceptual process that is distorted by the need to maintain and enhance self-esteem, or the tendency to perceive oneself in an overly favorable manner.
In recent days, I have had multiple people tell me that I blame myself too much. This I believe is a misunderstanding. I take failures much more seriously not to beat myself down but to be able to “play the next hand” (as I think of it) better.
Hubris
It occurred to me yesterday that an antidote for hubris is taking failures more seriously than successes. That thought itself implies a certain amount hubris: antidote no less! But I still think it is directionally true: excuses are just too damn easy to find (“the easiest thing to find in an excuse” - you can quote me on that) and not soberly assessing our failures leads to complacency and inflated sense of self-worth.
Stewardship
Recently, I have been thinking a lot about the Principal–agent problem. I honestly wish this was called the “stewardship problem” because I feel that it denotes better the ethical aspect of the issues.
Among other things, I have been asking myself what is the timeline that a steward should assume? And I think that, in the lack of other information, a steward must assume an infinite timeline of care for and exploitation of the systems/resources/whatever.
Your API is my database
(date unknown but notes from years ago and then written somewhere between 2022-12-07 and 2023-03-06)
When evaluating a vendor one of the core requirements that I have is that the entire state on the vendor’s side can be accessed and modifierd through an API. Vendors are eager to say “yes, absolutely, our entire UI is built on top of our API” (which sometimes, unbeknownst to them, serves as a counter argument: some UIs are that terrible).
Errors and Idempotency and Errors and Idempotency
(date unknown but somewhere between 2022-12-07 and 2023-03-06)
Should idempotent operations sometimes be treated as errors? History suggests that it should.
Systems that treat idempotent operations as errors:
File systems where deleting a file results in an error. API servers that return 404 on deleting an entity that doesn’t exist. INSERT operations in SQL databases even when the row matches the already existing row. Double freeing heap memory in C/C++. Double deleting an object in C++ (a different case from freeing memory: when an object is deleted, a destructor has to run) Systems that do not treat idempotent operations as errors:
The Coddling of the Programming Mind
I was following a course on full-stack Svelte that uses knex for queries. The author, who is kind and wants to help the audience, suggests using knex-stringcase to convert database column names from snake_case to camelCase. This, according to the author, will make the code “a little bit more understandable for JavaScript developers”. This is deeply misguided:
You are calling the exact same thing with two different names: You have to use one spelling whenever you are near SQL (e.
90 Percent Perspiration
The famous quote goes:
Success is 10 percent inspiration and 90 percent perspiration.
I’m going to paraphrase it as:
Software development is 10 percent programming and 90 percent perspiration.
Consider the cost of a single if that introduces some new feature (e.g. a new flag):
Write the if and the new branch. Write the comment on the reasoning (right?) Possibly add a metric to know how often the new branch it’s used.
Connascence of Execution
Per connascence.io:
Connascence of execution is when the order of execution of multiple components is important.
In connascence of value one of the dynamic solution I proposed was:
a Kubernetes service that subscribes to etcd and that on received changes redeploys a set of all the other Kubernetes services that depend on the updated values
But such a service, as specified in the post, doesn’t solve the dependancy of order of redeploys.