<story><title>What Is Null? (2010)</title><url>http://wiki.c2.com/?WhatIsNull</url></story><parent_chain><item><author>WalterBright</author><text>&amp;gt; Rust skips nulls &amp;amp; statically disallows use of variables before initialization&lt;p&gt;That doesn&amp;#x27;t mean you won&amp;#x27;t need a &amp;quot;not a valid object&amp;quot; for a type. That&amp;#x27;s why there all these Optional and Maybe constructions - you&amp;#x27;re still checking for it.</text></item><item><author>__s</author><text>What? I don&amp;#x27;t get why you&amp;#x27;re saying &amp;quot;you have to&amp;quot;. Besides, with null you don&amp;#x27;t necessarily get a segfault, in C you get undefined behavior&lt;p&gt;Rust skips nulls &amp;amp; statically disallows use of variables before initialization</text></item><item><author>WalterBright</author><text>If you don&amp;#x27;t have a null, then you have to set aside some value for the type as the default value. With null, you get a seg fault if you try and use it.&lt;p&gt;Without a null, you&amp;#x27;ll need to create a special default value which performs the same function - giving an error if you try to use it.&lt;p&gt;Floating point values have NaN for this, UTF-8 code units have 0xFF. The D programming language uses NaN and 0xFF to default initialize these types. NaN is good because it is &amp;quot;sticky&amp;quot;, meaning if a result is computed that depended on a NaN, the result is NaN as well.&lt;p&gt;Some people complain about this, wanting floats to be 0.0 default initialized. But then it would be nearly impossible to tell if an unintended 0.0 crept into the calculation.&lt;p&gt;&amp;gt; More like &amp;quot;String and null&amp;quot;&lt;p&gt;Null&amp;#x27;s replacement, Maybe and Optional, still have the extra check.</text></item><item><author>_hardwaregeek</author><text>Non nullability is probably one of the most important concepts I&amp;#x27;ve learned. People can talk your ear off about macros or about borrow checking or whatever cool feature is in their favorite languages. But non nullability isn&amp;#x27;t a feature as much as the removal of a terrible one: types being automatically unifiable with null.&lt;p&gt;What does that mean? Well basically that every single (reference) type in most languages comes with an implicit &amp;quot;and null&amp;quot;. String in Java? More like &amp;quot;String and null&amp;quot;. Car object? Actually it&amp;#x27;s &amp;quot;Car and null&amp;quot;.&lt;p&gt;Why is this a bad thing? Well null is a very specific type with a very specific meaning, but because it&amp;#x27;s automatically included with every type, people end up using it for a bunch of situations where a different type or value would work. Let&amp;#x27;s take a simple parser. A naive implementation, upon reaching the end of the string, might just return null. After all, nothing has been found. But that&amp;#x27;s not a null value, that&amp;#x27;s an EndOfString value! The moment you pass that value out of the context of the function, you need to remember that null means EndOfString. Or maybe the string you&amp;#x27;re passing in is a null value in the first place. It&amp;#x27;d be tempting to return out null, right? Except you&amp;#x27;ve now lost information on whether the string itself was null, or if something happened in the parse function that caused it to return null.&lt;p&gt;That isn&amp;#x27;t to say null is wholly evil. There&amp;#x27;s certainly uses for null. But it&amp;#x27;s often way better to contain its use with Option or Maybe, essentially wrappers that detail &amp;quot;hey, this value could be null&amp;quot;. These wrappers are &lt;i&gt;&lt;/i&gt;not&lt;i&gt;&lt;/i&gt; unifiable with regular values, which forces you to think about where values can and cannot be null.&lt;p&gt;I totally understand if language designers want to omit features that they deem unnecessary or overcomplicated. I get it if you want a language sans generics or sans macros. But I don&amp;#x27;t understand keeping a feature that has caused far too much pain and encouraged far too many bad practices.</text></item></parent_chain><comment><author>dbaupp</author><text>In my experience, Option&amp;#x2F;Optional&amp;#x2F;Maybe of a type T comes up a lot less than the type T itself. That is, needing &amp;quot;not a valid object&amp;quot; is a rarer than only requiring objects that are always valid.&lt;p&gt;Those construction exactly exist so that you have to check for it. They force the programmer to think about the &amp;quot;maybe invalid&amp;quot; state, whereas built-in-null doesn&amp;#x27;t prompt this (and, indeed, since might-be-null is the rare state, people often just assume they&amp;#x27;re working with a valid instance of the type and don&amp;#x27;t handle null at all).</text></comment>
<story><title>What Is Null? (2010)</title><url>http://wiki.c2.com/?WhatIsNull</url></story><parent_chain><item><author>WalterBright</author><text>&amp;gt; Rust skips nulls &amp;amp; statically disallows use of variables before initialization&lt;p&gt;That doesn&amp;#x27;t mean you won&amp;#x27;t need a &amp;quot;not a valid object&amp;quot; for a type. That&amp;#x27;s why there all these Optional and Maybe constructions - you&amp;#x27;re still checking for it.</text></item><item><author>__s</author><text>What? I don&amp;#x27;t get why you&amp;#x27;re saying &amp;quot;you have to&amp;quot;. Besides, with null you don&amp;#x27;t necessarily get a segfault, in C you get undefined behavior&lt;p&gt;Rust skips nulls &amp;amp; statically disallows use of variables before initialization</text></item><item><author>WalterBright</author><text>If you don&amp;#x27;t have a null, then you have to set aside some value for the type as the default value. With null, you get a seg fault if you try and use it.&lt;p&gt;Without a null, you&amp;#x27;ll need to create a special default value which performs the same function - giving an error if you try to use it.&lt;p&gt;Floating point values have NaN for this, UTF-8 code units have 0xFF. The D programming language uses NaN and 0xFF to default initialize these types. NaN is good because it is &amp;quot;sticky&amp;quot;, meaning if a result is computed that depended on a NaN, the result is NaN as well.&lt;p&gt;Some people complain about this, wanting floats to be 0.0 default initialized. But then it would be nearly impossible to tell if an unintended 0.0 crept into the calculation.&lt;p&gt;&amp;gt; More like &amp;quot;String and null&amp;quot;&lt;p&gt;Null&amp;#x27;s replacement, Maybe and Optional, still have the extra check.</text></item><item><author>_hardwaregeek</author><text>Non nullability is probably one of the most important concepts I&amp;#x27;ve learned. People can talk your ear off about macros or about borrow checking or whatever cool feature is in their favorite languages. But non nullability isn&amp;#x27;t a feature as much as the removal of a terrible one: types being automatically unifiable with null.&lt;p&gt;What does that mean? Well basically that every single (reference) type in most languages comes with an implicit &amp;quot;and null&amp;quot;. String in Java? More like &amp;quot;String and null&amp;quot;. Car object? Actually it&amp;#x27;s &amp;quot;Car and null&amp;quot;.&lt;p&gt;Why is this a bad thing? Well null is a very specific type with a very specific meaning, but because it&amp;#x27;s automatically included with every type, people end up using it for a bunch of situations where a different type or value would work. Let&amp;#x27;s take a simple parser. A naive implementation, upon reaching the end of the string, might just return null. After all, nothing has been found. But that&amp;#x27;s not a null value, that&amp;#x27;s an EndOfString value! The moment you pass that value out of the context of the function, you need to remember that null means EndOfString. Or maybe the string you&amp;#x27;re passing in is a null value in the first place. It&amp;#x27;d be tempting to return out null, right? Except you&amp;#x27;ve now lost information on whether the string itself was null, or if something happened in the parse function that caused it to return null.&lt;p&gt;That isn&amp;#x27;t to say null is wholly evil. There&amp;#x27;s certainly uses for null. But it&amp;#x27;s often way better to contain its use with Option or Maybe, essentially wrappers that detail &amp;quot;hey, this value could be null&amp;quot;. These wrappers are &lt;i&gt;&lt;/i&gt;not&lt;i&gt;&lt;/i&gt; unifiable with regular values, which forces you to think about where values can and cannot be null.&lt;p&gt;I totally understand if language designers want to omit features that they deem unnecessary or overcomplicated. I get it if you want a language sans generics or sans macros. But I don&amp;#x27;t understand keeping a feature that has caused far too much pain and encouraged far too many bad practices.</text></item></parent_chain><comment><author>antonvs</author><text>&amp;gt; That doesn&amp;#x27;t mean you won&amp;#x27;t need a &amp;quot;not a valid object&amp;quot; for a type.&lt;p&gt;This confuses two different concepts, and that confusion is precisely the problem with &amp;quot;null&amp;quot;.&lt;p&gt;Most &lt;i&gt;types&lt;/i&gt; neither need, nor have, a &amp;quot;not a valid object&amp;quot; value. The &amp;quot;not a valid object&amp;quot; value is typically disjoint from the type.&lt;p&gt;Null can&amp;#x27;t be used instead of some other type, as though it were that type. Instead, you have to perform a comparison to decide whether you&amp;#x27;re dealing with null, or a value of the expected type.&lt;p&gt;The problem with null, in languages that have it, is the inability to statically prove that terms cannot be null.&lt;p&gt;This means null is a pervasive possibility that almost always has to be checked for, which is an unnecessary source of bugs. Strictly speaking, you always have to check for null, except in those cases where you can prove (informally, since the compiler doesn&amp;#x27;t help with this) that you already did that.&lt;p&gt;&amp;gt; That&amp;#x27;s why there all these Optional and Maybe constructions - you&amp;#x27;re still checking for it.&lt;p&gt;The point is that option types allow you to choose whether you want to allow non-values at a particular term. If you don&amp;#x27;t - e.g. if a function returns a value not wrapped in an option type - then you&amp;#x27;re statically guaranteed to be able to use that value without having to check for null.&lt;p&gt;The only place where you need option types are where you&amp;#x27;re explicitly allowing for an optional value. And in that case, the option type helps because it statically disallows you from treating the value as though it were an instance of the underlying type.&lt;p&gt;So while it might seem like &amp;quot;you&amp;#x27;re still checking for it,&amp;quot; there&amp;#x27;s an important difference in the context of that check - the compiler will give you an error if you try to use the value without unwrapping the option.</text></comment>