{"id":1341,"date":"2013-04-03T17:43:38","date_gmt":"2013-04-03T17:43:38","guid":{"rendered":"http:\/\/www.navision-blog.de\/blog\/?p=1341"},"modified":"2013-04-05T12:12:56","modified_gmt":"2013-04-05T12:12:56","slug":"a-tale-of-nulls","status":"publish","type":"post","link":"http:\/\/www.navision-blog.de\/blog\/2013\/04\/03\/a-tale-of-nulls\/","title":{"rendered":"A tale of nulls &#8211; part I"},"content":{"rendered":"<p>Triggered by a short tweet by <a href=\"http:\/\/tomasp.net\/\">Tomas Petricek<\/a> and a <a href=\"http:\/\/blogs.msdn.com\/b\/dsyme\/archive\/2013\/03\/25\/quote-of-the-week-quot-what-can-c-do-that-f-cannot-quot.aspx\">blog post by Don Syme<\/a> I had a couple of conservations about null as a value, Null as a type (<a href=\"http:\/\/www.scala-lang.org\/api\/current\/index.html#scala.Nothing\">Nothing<\/a> in Scala), the null object pattern and the Maybe monad (or Option type in F#). I decided to share my opinion on this topic in order to help others to make their own opinion.<\/p>\n<h4>Part I &#8211; Null as a value<\/h4>\n<p>Unfortunately most programming languages have some kind of null pointer. We are now even at a point where some people claim that <a href=\"http:\/\/www.infoq.com\/presentations\/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare\">Tony Hoare\u2019s famous billion dollar mistake<\/a> costs actually a billion dollar per year.<\/p>\n<p>But before we start to think about solutions to the null pointer problem let us first see where null values might come in handy.<\/p>\n<h5>Uninitialized values<\/h5>\n<p>In a statement oriented language like C# it is sometimes not that easy to represent uninitialized state.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/forki\/5292337.js\"><\/script><script src=\"https:\/\/gist.github.com\/forki\/5292355.js\"><\/script>As you can see we forgot to initialize <em>peter<\/em> in the missing &quot;else-branch&quot; which might lead to a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.nullreferenceexception.aspx\">NullReferenceException<\/a>. There are a couple of things we can do to prevent this from happening. First of all we should omit the explicit initialization with null:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5292396.js\"><\/script>  <\/p>\n<p>In this case the C# compiler throws an error telling us &quot;Use of unassigned local variable &#8216;peter&#8217;&quot;. <\/p>\n<p>In <a href=\"http:\/\/en.wikipedia.org\/wiki\/Expression-oriented_programming_language\">expression oriented languages<\/a> like F# the problem doesn\u2019t exist. We usually write initializations like this: <\/p>\n<p><a href=\"http:\/\/www.navision-blog.de\/images\/A-tale-of-nulls_D914\/image_4.png\"><img loading=\"lazy\" style=\"background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/www.navision-blog.de\/images\/A-tale-of-nulls_D914\/image_thumb_4.png\" width=\"475\" height=\"177\" \/><\/a><\/p>\n<p>There is no way to forget the else branch since the types don\u2019t match.<\/p>\n<h5>Unknown values<\/h5>\n<p>Consider a search function which tries to find a Person in a list:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5293579.js\"><\/script>  <\/p>\n<p>Unknown values are probably the most common cause for the introduction of nulls and in contrast to uninitialized values they have much more global effects.<\/p>\n<h4>Solutions to unknown values<\/h4>\n<h5>1. Using explicit exceptions<\/h5>\n<p>One easy solution to get rid of the nulls is to make the exception explicit:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5317336.js\"><\/script>  <\/p>\n<p>One benefit here is that we have a concrete exception which is telling us what went wrong. Unfortunately nothing forces us to handle this exception in the calling method. This means the program can still crash. Another problem is that if we use try\/catch as a control flow statement (i.e. use it very very often) then we might <a href=\"http:\/\/yoda.arachsys.com\/csharp\/exceptions.html\">slow down our program<\/a>. <\/p>\n<p>And there is still a philosophical question: is it really an exception if we don\u2019t have a person in our repository?<\/p>\n<h5>2. Using out parameters and returning bools<\/h5>\n<p>If we want to make the result of our search a little more explicit we can also introduce a boolean return value:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5303372.js\"><\/script>  <\/p>\n<p>This is a pattern which is actually used everywhere in the .NET framework, so it must be good right?! <\/p>\n<p>Just a simple question here: What did we gain exactly? If we forget to check for nulls why would we remember to check the bool?<\/p>\n<p>There is another interesting observation here. Due to the introduction of <em>out<\/em> parameters we also introduce the uninitialized value problem in every calling method, which is bizarre.<\/p>\n<h5>3. Null object pattern<\/h5>\n<blockquote>\n<p>\u201cIn object-oriented computer programming, a <b>Null Object<\/b> is an object with defined neutral (&quot;null&quot;) behavior. The Null Object design pattern describes the uses of such objects and their behavior (or lack thereof).\u201d<\/p>\n<p align=\"right\"><a href=\"http:\/\/en.wikipedia.org\/wiki\/Null_Object_pattern\">Wikipedia<\/a><\/p>\n<\/blockquote>\n<p>So obviously this makes only sense in a context where objects have observable behavior. So let\u2019s add some behavior to our Person class:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5302766.js\"><\/p>\n<p>Now we can use this in the search method:<\/p>\n<p><\/script><script src=\"https:\/\/gist.github.com\/forki\/5303014.js\"><\/script>  <\/p>\n<p>Let&#8217;s look at this solution for a moment. <\/p>\n<ul>\n<li>Pro: Implementation of missing behavior is trivial <\/li>\n<li>Pro: We don\u2019t introduce null values \u2013&gt; we won\u2019t get NullReferenceExceptions <\/li>\n<li>Pro: The name of the class carries information about the reason for the null value <\/li>\n<li>Cons: In order to to get rid of the Person(string name, int age) constructor in the null-object we had to introduce an interface <\/li>\n<li>Cons: In order to use the interface we had to modify the Person class. This might be a real problem if we don\u2019t have access to the source. We would need some kind of ad-hoc polymorphism like Haskell\u2019s type classes, Scala\u2019s Traits or Clojure\u2019s Protocols (read more about the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Expression_problem\">expression problem<\/a>) <\/li>\n<li>Cons: Everything we want to do with Persons has to be part of the IPerson interface or we have to fall back to explicit runtime type tests, because there is no way to get to the data:\n<p><a href=\"http:\/\/www.navision-blog.de\/images\/A-tale-of-nulls_D914\/image_3.png\"><img loading=\"lazy\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/www.navision-blog.de\/images\/A-tale-of-nulls_D914\/image_thumb_3.png\" width=\"318\" height=\"171\" \/><\/a> <\/li>\n<li>Cons: Without ad-hoc polymorphism the Person class is getting more and more complex over time since we are adding all the behavior to it. Compare it with our starting point where it was a simple data representation. We totally lost that. <\/li>\n<li>Cons: Errors\/bugs might appear as normal program execution. [see Fowler, Martin (1999). Refactoring pp. 261] <\/li>\n<\/ul>\n<p>Don\u2019t use this approach it\u2019s really not a good solution.<\/p>\n<h5>4. The Option type (a.k.a. Maybe monad)<\/h5>\n<p>The option type is a way to push the idea from 2. \u201creturning bools\u201d into the type system. There are lots of tutorials about the option type on the web, but for now it\u2019s enough to know that it is something which is based on the following idea:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5310057.js\"><\/script>  <\/p>\n<p>In order to allow pattern matching in C# we introduce a small helper:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5318030.js\"><\/script>  <\/p>\n<p>With this idea we can get rid of all null values in the program, we don\u2019t have to introduce an IPerson interface, the null case is type checked and the best thing is it\u2019s really easy to create functions like IsOlderThan12:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5310181.js\"><\/script>  <\/p>\n<p>Please don\u2019t implement the option type yourself. Even in C# it\u2019s much easier to just reference FSharp.Core.dll and use <a href=\"https:\/\/github.com\/fsharp\/fsharpx\">FSharpx<\/a> (read <a href=\"http:\/\/bugsquash.blogspot.de\/2011\/10\/10-reasons-to-use-f-runtime-in-your-c.html\">10 reasons to use the F# runtime in your C# app<\/a>).<\/p>\n<p>Of course this is only the tip of the iceberg. If you <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/dd233245.aspx\">read more about the option type<\/a> you will see that its monadic behavior allows all kinds of awesome applications (e.g. LINQ, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee353802.aspx\">folds<\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee340461.aspx\">map<\/a>, \u2026).<\/p>\n<h5>5. The Either type<\/h5>\n<p>One of the benefits of the null object pattern above was that it allows to encode the reason for the missing value. In some cases we need the same thing for the maybe monad. So let&#8217;s try to capture the reason in the None case:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5310681.js\"><\/script>  <\/p>\n<p>Now we can use this in the TryFindPerson method:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5310754.js\"><\/script>  <\/p>\n<p>As with the option type please don&#8217;t rewrite this stuff yourself. There is a Choice type in F# which helps to capture this idea and <a href=\"http:\/\/bugsquash.blogspot.de\/2011\/08\/validating-with-applicative-functors.html\">Mauricio<\/a> has a couple of blog posts which explain how to use it from C# (of course FSharpx is helping here again).<\/p>\n<h5>6. The (singleton) list monad<\/h5>\n<p>The option type captures the idea that we can either have one value or nothing. We can do the same thing with List&lt;T&gt;:<\/p>\n<p> <script src=\"https:\/\/gist.github.com\/forki\/5310995.js\"><\/script><script src=\"https:\/\/gist.github.com\/forki\/5311011.js\"><\/script>  <\/p>\n<p>Of course this uses only a small subset of the power of IEnumerable&lt;T&gt; but I wanted to show the similarity to the maybe monad. You can read more about the \u201c<a href=\"http:\/\/bugsquash.blogspot.de\/2011\/10\/poor-man-option-type-in-c.html\">poor man\u2019s option type<\/a>\u201d on Mauricio\u2019s blog.<\/p>\n<h4>Conclusion<\/h4>\n<p>We saw a couple of very different solutions to get rid of null values. Normally I&#8217;d only use the option type or the either type (if I need to carry the reason). In some very rare situations (e.g. C# only projects) I would also use singleton lists.<\/p>\n<p>I wouldn\u2019t use the other solutions. They are potentially dangerous, especially if your project gets bigger.<\/p>\n<p>I would be happy to read your opinions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Triggered by a short tweet by Tomas Petricek and a blog post by Don Syme I had a couple of conservations about null as a value, Null as a type (Nothing in Scala), the null object pattern and the Maybe monad (or Option type in F#). I decided to share my opinion on this topic [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[448,8],"tags":[81,664,629],"_links":{"self":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/1341"}],"collection":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=1341"}],"version-history":[{"count":10,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/1341\/revisions"}],"predecessor-version":[{"id":1352,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/posts\/1341\/revisions\/1352"}],"wp:attachment":[{"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=1341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=1341"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.navision-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=1341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}