> The argument for disallowing nulls is much stronger than the argument for demanding a compiler-enforced non-empty string. I definitely support the ability to declare variables, including strings, as non-nullable. An empty string is simply analogous to the number 0. It doesn't really overlap in meaning with null. It's true it would be useful to occasionally disallow the number 0, but only very occasionally. The obvious example is division, but having a representation of +/- infinity alleviates some cases.
Well, of course you should be able to declare something non-null. What do I look like, someone who likes Java? :p My point wasn't that I WANT to use null instead of an empty collection/string, it was that our languages give us multiple mechanisms by which we can pass in "nothing" for strings/collections, but they give us zero ways to ask for a non-empty string/collection. That's super frustrating! Yes, of course "null" and "empty set" are technically and semantically different. But they're close enough that you could actually deal with having only non-empty strings + nulls and be able to mostly express what you want. That's not the case if I actually want a non-empty string in many of today's languages. Not if I want it to be usable with other APIs and the standard libraries, that is.
> Paraphrasing: "I've written the same kind of method over and over throughout my career and have been unable to (or made no attempt to) abstract it away." I love strong type systems, but it doesn't sound like the type system is your problem here. The problem is that you're constantly re-implementing the same business logic.
Eh, no. I haven't worked in the same language or on the same project for my whole career. So, yeah, I've noticed that I'm pretty much always either defining a bunch of boilerplate types up front or I regret not doing it when a 0 hits the database because someone wasn't careful with their math or had an off-by-one error.
Maybe I should publish a book a la Gang of Four and call it "Static Type Patterns". ;)
So, yeah. Believe it or not, I HAVE implemented stuff like PositiveInt and NonEmptyString a bunch of times in a bunch of languages. And it's better than not having it, but it still sucks because in several of those languages, it means that I have all kinds of noise converting to and from, e.g., the native string type. And that's because most of the above languages have no concept of "newtypes" and have no intention of letting programmers define or refine "primitives".
It's not really about "business logic". It's about "I know how to describe the shape of this data, but my statically typed language won't let me."