I often think about this quote from TAPL. This framing of “safety” changed how I design systems.
> Informally, though, safe languages can be defined as ones that make it impossible to shoot yourself in the foot while programming.
> Refining this intuition a little, we could say that a safe language _is one that protects its own abstractions_.
> Safety refers to the language's ability to guarantee the integrity of these abstractions and of higher-level abstractions introduced by the programmer using the definitional facilities of the language. For example, a language may provide arrays, with access and update operations, as an abstraction of the underlying memory. A programmer using this language then expects that an array can be changed only by using the update operation on it explicitly—and not, for example, by writing past the end of some other data structure.