Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active December 18, 2021 18:13
Show Gist options
  • Save CMCDragonkai/4ce7eec18ebbf8967f16 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/4ce7eec18ebbf8967f16 to your computer and use it in GitHub Desktop.
Three valued logic, and what `null` and `Nothing` actually means in SQL and Programming Languages

Three Valued Logic Pattern in Programming

WIP

In programming 3 valued logic and associated effects seems to occur in 2 different situations.

The first in normal programming occurs when you have to deal with True or False or Null. In many situations in imperative programming I find myself needing to check if a flag exists and is true, or if a flag exists and is false, or the flag doesn't exist at all in which case means its null. This is a 3 valued logic, because depending whether the flag is true, or false, or null, different things may occur. An example is displaying an HTML fragment on an HTML form. The flag is a submission parameter. On the first load of the page, the flag is non-existent. Once the form is submitted, the flag now exists, and is set to true or false.

Another parameter could be a form submission parameter. One could either set it to true, or set it to false, not set it at all. If one did not set it at all, that's the null value. If one sets it to true, this could mean overriding some property in the database, while setting to false also does it same thing, but if it is not set at all, then nothing happens and no value is overridden in the database.

Another common usage of null is in database systems. Where null represents the lack of a value. Because of the open world assumption. Thing's that we do not know, we don't know. The database is concious that is ignorant.

There's a misconception here: The problem is that what is an Integer type in SQL, is often really Maybe Integer (<-- this is the misconception). But this is actually a debate. Because the presence of Null can never be eliminated, and within 3 valued logic Null == Null does not equal True, because Null is not a value, and indeterminacy cannot be compared to be equivalent to indeterminacy. However in Haskell Nothing == Nothing is True, because Nothing is actually a value. The discussion is here: http://c2.com/cgi/wiki?NullVersusNone

In the presence of Nulls, it complicates things by making there be 3 valued logic. But it's pretty much implicit, in that programs don't explicitly state this, nor do we do terminal or coverage checking to make sure our functiosn are total and can deal with the nulls in our values. In JavaScript it gets even more complicated as there's no just T/F/null, but also undefined and NaN. This becomes many valued logic, and gets very buggy.

Also this debate exists here:

What we can say is that in Functional and Typed languages inspired from Functional and strong type systems have:

Nothing/None in the Option/Maybe Type = Null Pointer - Usable in 2 valued logic Null Value/Indeterminate/Unknown - Needs 3 valued logic

Javascript's undefined? Who knows. I reckon JavaScript's undefined is equivalent to SQL's Null Value.

Many valued logic becomes useful with probabilistic logic and fuzzy logic. And there are further applications of this.

What should do from this?

Well in a database system, if you want 3 valued logic, in the sense of True or False or Unknown. Keep using the standard Null.

If you want 2 valued logic where one can compare between Nothing and Something and within Something. Don't use Null value. Use a Maybe type of you don't have Maybe types, create one (it could just be a matter of 0 1 2), and if you can't do that, use Null pointers.

In most closed world programming, you generally want to use 2 valued logic. Because the absence of an initialised variable (as in null in most imperative langauges), is not interdeterminant nor is it unknown. It is literally nothing. This allows you intuitively compare Nothing == Nothing. The presence of null value is equivalent to having every type being an implicit Maybe. SQL is not every type being an implicit maybe, because its null is better called unknown/indeterminant when it uses 3 valued logic.

Also note that in imperative programming languages that are not SQL, their null is actually Nothing. It's still 2 value logic. Not 3 value logic of indeterminate.

Only in special cases or trying to model real life systems do you actually have Null meaning Interderminate or Unknown. And at that point it might be better to investigate probabilistic databases or fuzzy logic instead of using 3 valued logic.

Note that there are different kinds of 3 valued logic. The SQL one is based on Kleene and Priest logics.

Now that ChrisDate wants Null to be removed from RelationalDatabases, so that the incongruence and confusion brought in by ThreeValuedLogic is eliminated, the developers, accustomed to use Null to represent Nothing, resist to the idea asking: How am I going to represent the fact that a Person is not married? I use to do that by marking the MarriageDate? as a nullable Date. Now what? I need to split the table into 2 tables just to represent the fact that the MarriageDate? is not mandatory? That of course seems like the obvious, elegant (if extremely cumbersome answer). But the practical developer refuses to get into that trouble, it is just too much effort, it is simple easier to continue using Null. But... what about Nothing? why not just simply add "Nothing" as a possible value for to the Date domain? That way it is possible to say that the Person has no MarriageDate?, and still stay inside the realm of TwoValuedLogic.

It is interesting that in most cases, most languages are designed to be fully deterministic and work on a closed world assumption. This makes sense, the design of null value in imperative languages is a big mistake. It adds implicit Maybes on every value. The design of Maybe type is the correct way to do it. It allows us to still be in a closed world and dictate Nothing as a value. And it stays within the simple 2 value logic world. However it is also true that we still need to model Null as unknown/indeterminate as the real world has unknown and indeterminate. In such cases, it should be explicit that we are using 3 valued logic. In the end, the design of programming languages should have both explicit Nothing (avoiding null values) and also explicit 3 valued logic when its needed.

2 things to move ahead.

In SQL, how do we avoid 3 valued logic, but still allow indeterminacy?

In programming languages, how do we allow explicit 3 valued logic? Think of Haskell (as it has already solved the implicit Maybe problem by having an explicit Maybe)

Great example of how NULLs confuse people, what do you want to mean by using null here? That there is no cancellation date for Fooz Ball? or that you do not know the cancellation date for Fooz Ball? It cannot mean both (because if it does, then you would have to explain me how to distinguish them... Can you? ;-)

Here's the standard:

None - Is the None value. It represents "I know that there is none of this." Unknown - Is the 3 valued logic value. It represents "I do not know what the value for this is."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment