For example, you may be interested in her recent talk on effect systems in Haskell at ZuriHac 2020,[1] based on the eff library she mainly contributes to.[2]
[1]: https://www.youtube.com/watch?v=0jI-AlWEwYI
[2]: https://github.com/hasura/eff
> he's asking you to read the article more carefully
she
The author appears to be claiming that this is somehow distinct from (and qualitatively weaker than) "type safety", without any justification for that claim.
"To some readers, these pitfalls may seem obvious, but safety holes of this sort are remarkably common in practice. ... Proper use of this technique demands caution and care:
* All invariants must be made clear to maintainers of the trusted module...
* Every change to the trusted module must be carefully audited to ensure it does not somehow weaken the desired invariants.
* Discipline is needed to resist the temptation to add unsafe trapdoors that allow compromising the invariants if used incorrectly.
* Periodic refactoring may be needed to ensure the trusted surface area remains small...
In contrast, datatypes that are correct by construction suffer none of these problems."
To get more specific:
* Safety holes of this sort are remarkably uncommon in practice, in my experience.
* Modules should be small and easily understood. If maintaining a module's invariants becomes too complex then you can, and should, recursively apply the same techniques within the module, breaking it up into smaller modules. This is good development practice anyway, as is periodic refactoring. So these cautions are a lot less costly than they sound; in fact the cost may well be zero.
* You need to resist the temptation to add unsafe trapdoors in any other approach as well; this simply isn't a disadvantage that's in any way specific to using newtypes.
In fact, in some cases, it's useful to retain (redundant or invalid) state that's discarded in "correct by construction" data structures. For example, saving application configuration as Option<int> is easier for the application to read correctly (int value, bool present). However when a user is editing an Option<T> through a GUI (checkbox, number) pair, then unchecking the checkbox will set the value to None and discard the last entered value, which is a poor user experience in my view.
I admit that I might be missing something fundamental to this discussion.
"newtypes can provide a sort of safety, just a weaker one. The primary safety benefit of newtypes is derived from abstraction boundaries. If a newtype’s constructor is not exported, it becomes opaque to other modules. The module that defines the newtype—its “home module”—can take advantage of this to create a trust boundary where internal invariants are enforced by restricting clients to a safe API."
From an outside perspective, you seem to be arguing the same things the author has already stated in the article, which is why he's asking you to read the article more carefully.