5 ms·
The more experienced a developer I become, the more strongly (and negatively) I feel about nils and nulls and their ilk. I have sympathy for C.A.R.Hoare who in
by inopinatus 9y ago
The more experienced a developer I become, the more strongly (and negatively) I feel about nils and nulls and their ilk. I have sympathy for C.A.R.Hoare who in 2009 apologised for the apparent invention of null references in ALGOL W (1965), calling them a "billion-dollar mistake". I've come to regard them as a data singularity, and when I design data structures and interfaces today I am deliberately avoiding/outlawing them; all my relational fields are NOT NULL and I choose either meaningful defaults, or EAV or equivalents instead; in method parameters I would rather something not exist than for it to accept a null reference or value. And I believe that the resulting code is more modular, more easily refactored and more reusable a result, errors are better handled, and the resulting data structures and calling arguments more easily interpreted, more readily queried and destructured, and are (so far) proving generally better fitted to real-world domains.
- taeric 9y agoFunny, I'm the opposite. The more experienced I've become, the more I've found that nil-punning is ultimately what I actually wanted. And I'm all for the idea that relational fields should be NOT NULL. I also fear that this doesn't really work for backwards compatible thinking. If I serialized some data down to disk before a field existed, I don't expect it to be there when I check it later. You can be tempted to think it should just be the zero value of the type you are using. Or you can add some extra boilerplate around accessing. I think either works. Just make sure you aren't getting carried away. And, try to do anything that cares about the absence or presence of something at a layer from where you get that something. Don't punt the decision down your codebase. (That is, Optionals are great at the layer, don't pass them as parameters to inner code, though. Obviously, YMMV. And, quite frankly, probably will go further than mine.)
- nerdponx 9y agoI'm all for the idea that relational fields should be NOT NULL What if the data is actually missing? How else do you record that information?
- zupa-hu 9y agoYou use the default empty value, and have an extra field for missingness. Than you have real type safety.
- TheDong 9y agoReal type safety is sum types. If I need to express something that is present or missing, I should use a Maybe monad. Having an extra field for "missingness" is less safe because the type system won't enforce that it is either missing or set, you could have it set to a value but marked as missing which is still ambiguous.
- sorkin2 9y agoThat's a "cure" worse than the disease.
- taeric 9y agoIf missing data is a valid value, pick a valid way to encode it. Null might work, but realize you could have to reason for the value. Actually missing, or just not collected it recorded. I concede there may be no difference in those meanings.
- cousin_it 9y agoAgree completely. Google removed "required" fields from proto3 because they cause problems for compatibility and version skew. And even in proto2, which had "required" fields, people quickly learned to avoid them. Anything that goes on the disk or wire should have only "optional" and "repeated" fields (as a bonus, "optional" is encoded the same as "repeated" with zero or one values).
- clusmore 9y agoMy problem with null is that it doesn't nest. For example, if I do a DB search for a particular column of a particular row and get null, does that mean the row doesn't exist, or it does but the column is empty? With optionals, you can distinguished between this with e.g. `Nothing` vs `Just Nothing`.
- abtinf 9y agoCan't that be determined by looking at the row count? A row count of zero means it doesn't exist. A row count of 1 with a null in the selected column means the row exists the column is null. I avoid the word "empty" when referring to anything SQL related, as it is ambiguous in three value logic.
- mjevans 9y agoSQL syntax, at least what I'm familiar with offhand, makes you explicitly say things such as WHERE (a.cola = b.colb OR a.cola IS NULL OR b.colb IS NULL) or similar syntax but with distinct variations for joining 'left' and 'right' tables on an expression (which, BTW, can be noticeably slower than the WHERE version, depending on which database you're using).
- marcus_holmes 9y agoI think they're referring to outer-joined tables. SELECT a.id, b.name FROM a LEFT JOIN b ON a.id = b.id If you get a NULL in the name field, you don't know if that's because there's no record in b for that id, or if there is a record in b for that id but it has a NULL name value. Sometimes that difference will be important.
- sorkin2 9y agoWhile admittedly this could be seen as a mistake in SQL, you can differentiate by looking at whether b.id is NULL or not.
- marcus_holmes 9y ago
- tjholowaychuk 9y agoNOT NULL bugs me too, but not so much because nulls are possible, more so that I think it should be inverted since that's the common case (at least for me).
- knocte 9y agoRight! It should have been called NULLABLE and default to false.