*All animations courtesy of my Wireworld built in Svelte*

If you've spent any time programming, you may recognize the "big three" boolean operators: AND, OR, and NOT (often written `&&`

, `||`

, `!`

in many programming languages). Together these operators are functionally complete, meaning they can be used to build *any* boolean logic. Combined with some sort of memory, functionally complete operators can be used to build a turing complete system.

What if I told you we need only one operator to be functionally complete? That's right! All you need is NAND (short for Not AND; `!(x && y)`

). But don't trust me, let me show you.

# Proving NAND is all you need

## NAND is NOT

You've seen the animation of a NAND in a Wireworld above (NAND-imation anyone?). What would happen if instead of two inputs, we tied them both together as one input?

Notice how this new operator constantly outputs until an input is received and then it stops (aka NOT logic). In JavaScript, if we had a `nand(x, y)`

function, we could make `not()`

like this:

```
const not = (x) => nand(x, x);
```

Look at NAND's truth table where both inputs are the same:

X | Y | = | O |
---|---|---|---|

false | false | = | true |

true | true | = | false |

Looks a lot like NOT to me! **NAND is NOT.**

## NAND is AND

Look at NAND's full truth table compared to AND:

X | Y | = | NAND | AND |
---|---|---|---|---|

false | false | = | true | false |

false | true | = | true | false |

true | false | = | true | false |

true | true | = | false | true |

It's perfectly inverse (that is the definition of Not AND after all). If only we could NOT the output of our NAND, we would have AND... if you read the last section, that's exactly what we have! Just put the output of a NAND as both inputs to another NAND and viola! an AND appears:

Again to relate this to code it might look something like this:

```
const and = (x, y) => nand(nand(x, y), nand(x, y));
```

## NAND is OR

Perhaps the trickiest one yet. AND and NOT were fairly obvious looking at their truth tables. But OR?

X | Y | = | NAND | OR |
---|---|---|---|---|

false | false | = | true | false |

false | true | = | true | true |

true | false | = | true | true |

true | true | = | false | true |

OR is tantalizingly close to NAND. They both have three outputs of `true`

and only one case of `false`

. But the tables are backwards! What are we supposed to do with this? What if I showed you a table with the opposite inputs:

NOT X | NOT Y | = | OR |
---|---|---|---|

true | true | = | true |

true | false | = | true |

false | true | = | true |

false | false | = | false |

Does that pattern look familiar? If we NOT our inputs first (using the same NAND as NOT trick) and put those as the inputs to our NAND, we'll get an OR!

We'll finish out our code examples:

```
const or = (x, y) => nand(nand(x, x), nand(y, y));
```

*(We just did DeMorgan's Theorem a* very *cool trick for making boolean code more readable; but we'll talk more about that later)*

## NAND is all you need

If you accept that AND, OR, and NOT are functionally complete, since NAND can build each of those three things, NAND, all by itself, is functionally complete!

So yes, NAND *is* all you need... but please don't write all your booleans using only NANDs. This is for your edification and education.

# Why should I care?

## Problem Transformations Solve Problems

What is the difference between a Bubble Sort and a Quick Sort? They will both give an equally sorted output after all. The importance comes in performance. Because while they are *logically equivalent* they are not *operationally equivalent*; one of them will finish faster when a physical computer executes the sort.

Many, *many* things in the business of software development see drastic improvements from transforming the physical operations while keeping logical equivalence. The better we become at this skill, the better programmers we become. (One way to become better is seeing examples, like this).

## NAND Runs the World

It just so happens that in real-world computer chips NAND is one of the easiest things to build. If you've ever heard of 3D NAND, you now know what that NAND stands for. And when your code works the first time around, thank a NAND gate.

## It's Just Cool!

Who would have thought that just one operator can run the whole world?

## Top comments (7)

One question: why ?

Why not?

You say

`and?`

; I say`and not?`

😁You mention quick sort vs bubble sort, and importance of performance. Well can you please provide some tests where your 2 operations NAND is faster than 1 operation AND, faster than one operation OR.

You also mention DeMorgan's Theorem - "

a very cool trick for making boolean code more readable"Do you think this >>

`nand(nand(x, x), nand(y, y))`

make boolean code more readable ?I believe he is referring to boolean algebraic notation when he says it makes things more readable.

In propositional logic and Boolean algebra,

De Morgan's lawsare a pair of transformation rules that are both valid rules of inference. They are named after Augustus De Morgan, a 19th-century British mathematician. The rules allow the expression of conjunctions and disjunctions purely in terms of each other via negation.I think you're missing the point of the article Ceban. It wasn't meant to upset you.

View Code of ConductAnother useless post... edification and education - vicarious embarrassment

I can write an article about having all the code in one line, but the question (my question) is still valid: why ?

Or even better: you know when at the beginning you invert the false and the true, so later on the QA and debugging - your colleague will have a brain f..k, but again - why ?

P.S You don't have to answer, in any case it will be another excuse

Oh no, please keep commenting; it just keeps boosting my useless post's stats! How else can I maximize this vicarious embarrassment?...

## Dev.to Writing: Reactions

## Nathan Kallman ・ Sep 29 '20 ・ 1 min read

Some comments may only be visible to logged-in visitors. Sign in to view all comments.