Disagree. Given the current popularity of dynamic languages and the fact that many people don't understand the value of ADT, newtype pattern, C-like enum even in static languages, I'd argue booleans & primitives are way overused.

I think a lot of people misunderstand KISS, believing everything should be primitives or surface-level simplicity. Instead, I interpret "simple" not something like golang's surface-level readability, but infosec's "principle of least privilege". Pick the option that minimizes possible state and capture the requirement logic, rather than primitives just because they're "simple" or "familiar".

Even then, sometimes it's fine to violate it. In this case, (nullable) date time might be more preferable than boolean for future-proofing purposes. It's trivial to optimize space by mapping date time to boolean, while it's a total pain to migrate from boolean to date time.

Also, doesn't "... a weird hack that wastes space" contradict "Avoid premature optimization"?

> booleans & primitives are way overused.

> I think a lot of people misunderstand KISS

I agree, people do misunderstand simplicity.

> Pick the option that minimizes possible state and capture the requirement logic

Which is what booleans do when the requirement is two states.

> Also, doesn't "... a weird hack that wastes space" contradict "Avoid premature optimization"?

No, because including the timestamp "just in case" is the premature optimization.