Emptiness: null
There is no value — and that is a value too. The main source of silent mistakes in mlog
null is not zero, not an error and not an empty string. It is the answer “there is no
value”: you asked, and there is nothing to say.
It needs a lesson of its own because everybody runs into it constantly while it behaves
invisibly: a program with null in it does not crash and does not complain, it just computes
the wrong thing.
Where it comes from
Section titled “Where it comes from”| Case | Example |
|---|---|
| a variable was never written to | a typo in a name, someone else’s name |
sensor on a block that is not there |
the link was demolished and the program still asks |
sensor on a property that does not apply |
liquid in a vault, @totalItems on a block type |
getlink past the number of links |
you walked further than there are |
@unit before ubind and after the unit dies |
the unit was shot down mid-job |
| reading memory past the end of a cell | address 64 in a cell that holds 64 values |
| a calculation with no answer | division by zero, root of a negative, log of zero |
The last row surprises people most often: mlog has neither infinity nor NaN. Everything the
maths could not compute becomes emptiness.
In arithmetic it is a zero
Section titled “In arithmetic it is a zero”Press “step” six times. null in a numeric context is zero, any other object is one:
equal same unset 0gives 1;add sum unset 1gives 1;add itemPlusOne @copper 1gives 2 — copper as an object is a one;strictEqual strict unset 0gives 0, and that is the important one.
Only a strict comparison tells emptiness from zero
Section titled “Only a strict comparison tells emptiness from zero”Ordinary equal and notEqual look at the number, and the number of emptiness is zero.
A strict comparison also looks at the kind of the value, which is why only it sees the
difference.
In references and in the program’s text it is called strictEqual, and the block labels it
with the sign === — that is what to look for in the list. The game does not translate signs,
so === stays === in any language.
| You need | With what |
|---|---|
| to store the answer in a variable | op strictEqual empty answer null |
| to branch away | jump strictEqual to the “no data” branch |
| to pick one of two values | select with the same condition |
Why it bites
Section titled “Why it bites”The usual check for “the block has run out of copper” is two blocks: sensor asks the vault
for @copper, jump compares the answer with zero.
Hence the rule: check for null before you check for zero. The order of lines is:
sensor— ask the vault for@copper;op strictEqual— compare the answer withnull;jump— if the comparison gave a one, go to “no block”;- and only now compare with zero.
Two extra blocks at the top are the price of a program that tells “ran out” from “broke”. They are worth putting everywhere data arrives from outside: from links, from units, from memory.
Unofficial fan project, not affiliated with Anuke. Mindustry sprites, fonts and translations © Anuke, used under GPL-3.0; Fira Code under OFL-1.1. Site code is GPL-3.0.