https://mathiasbynens.be/notes/gmail-plain-text
yeah
PARDON MY FRENCH
"It's a surprisingly persistent gap given how long the industry has been thinking about it. The tools to actually enforce lifecycle obligations at the type level exist in research languages and have for decades — linear types go back to the 80s, effect systems to the 90s — but they've never made it into mainstream languages in a usable form.
Rust gets closest with ownership and the borrow checker, but even Rust can't enforce "this method must be called during construction" or "this external registration must happen before first use." You still end up with conventions, documentation, and runtime panics.
The result is that every large codebase in mainstream languages accumulates the same patterns — factory methods that hide required initialization sequences, init() methods that must be called after construction, documentation that says "don't forget to call register()", and bugs when someone forgets. It's just accepted as the cost of doing business.
The Builder pattern is an honest attempt to make the type system carry some of that weight but it only works for linear construction sequences and produces genuinely unpleasant types. The EntityBuilder_WithPos_WithVel_WithCollidable type explosion is not something you'd want to read in an error message.
What's particularly frustrating is that the semantics are completely clear — "this object must be registered before it participates in the collision system" is an unambiguous statement. The meaning is not subtle or complex. The type system just has no way to express it. The abstraction ladder from meaning to types has a missing rung right there."
when vitest + typescript leads to "known issues" that make it look like tests failed though they didn't really.
from my perspective, most ui and ux is horribly wrong.
like, why `npx tsc src/foo.ts` doesn't read the tsconfig.json file for the default settings? whatever!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!