{"id":1872,"date":"2012-08-20T10:15:26","date_gmt":"2012-08-20T14:15:26","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/?p=1872"},"modified":"2012-08-20T10:15:26","modified_gmt":"2012-08-20T14:15:26","slug":"nulls","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2012\/08\/20\/nulls\/","title":{"rendered":"Nulls"},"content":{"rendered":"<p> So, my post on monads apparently set of a bit of a firestorm over my comments about avoiding null pointer exceptions. To show you what I mean, here&#8217;s a <a href=\"http:\/\/beust.com\/weblog\/2012\/08\/19\/a-note-on-null-pointers\/\">link<\/a> to one of the more polite and reasonable posts.<\/p>\n<p> Ok. So. Let me expand a bit.<\/p>\n<p> The reason that I think it\u2019s so great that I don\u2019t get NPEs when I use an option with something like Option isn\u2019t because it makes me a super-programmer who&#8217;s better than the lowly slime who deal with NPEs. It&#8217;s because it changes how that I write code, in a way that helps me avoid making mistakes &#8211; mistakes that I make because I&#8217;m just a fallible idiot of a human.<\/p>\n<p> There are two fundamental things about an option type, like what we have in Scala, that make a huge difference.<\/p>\n<p> First, it <em>narrows<\/em> the field of errors. When I&#8217;m programming in Java, any call that returns a pointer could return a null. The language makes no distinction between a function\/expression that could return a null, and one that can&#8217;t. That means that when I get an NPE, the source of that null pointer could be <em>anything<\/em> in the dynamic slice leading to the error. With an option type, I&#8217;ve got two kinds of functions: functions that <em>always<\/em> return a non-null value, and functions that sometimes return a non-null value, and sometimes return a None. That&#8217;s incredibly valuable.<\/p>\n<p> Second, it forces me to explicitly deal with the None case. In Java, programmers constantly build code without null checks, because they <em>know<\/em> that a function won&#8217;t return null. And then it does, and ker-splat. With an option type, I have no choice: I have to explicitly deal with the potential error case. Sure, I can forcibly code around it &#8211; in Scala, I can use Option.get, which will turn into an error analagous to an NPE. But it forces me to make that choice, and make it <em>explicitly<\/em>.<\/p>\n<p> Even if I&#8217;m going the stupid, brute-force route and assuming that I know, without fail, that a function is going to return a non-null value&#8230; Consider an example:<\/p>\n<pre>\n  <em> Java: <\/em>:\n  T g = f.doSomething()\n  g.doSomethingElse()\n\n  <em> Scala:<\/em>\n  val g: Option[T] = f.doSomething()\n  g.get.doSomethingElse()\n<\/pre>\n<p> The scala case has to <em>explicitly<\/em> deal with the fact that it&#8217;s dealing with a potentially empty value, and using a statement that asserts the non-emptiness.<\/p>\n<p> But in reality, if you&#8217;re a decent programmer, you <em>never<\/em> use <code>.get<\/code> to directly access an option. (The only exception is in cases where you call the <code>.get<\/code> in a context dominated by a non-empty test; but even then, it&#8217;s best to not, to avoid errors when the surrounding code is modified.)   In real code, you pretty much always explicitly de-option a value using a function like <code>getOrElse<\/code>:<\/p>\n<pre>\nval f: User = getUser(\"markcc\").getOrElse(new User(\"markcc\"))\n<\/pre>\n<p> As I hope it has become plain, the point of avoiding NPEs through option-like type structures isn&#8217;t that somehow it makes the entire category of unexpected result value disappear. It&#8217;s that it changes the way that you code to distinguish where those errors can occur, and to force you to deal with them.<\/p>\n<p> I think that ultimately, things like this are really just manifestations of the good-old static vs dynamic type wars. Type errors in a dynamically typed language are really just unexpected value errors. Strong typing doesn&#8217;t stop you from making those errors. It just takes a bunch of common cases of those errors, and converts them from a run-time error to a compile-time error. Whether you want them to be run-time or compile-time depends on the project your working on, on your development team, and on your personal preferences.<\/p>\n<p> I find in practice that I get <em>many<\/em> fewer errors by being forced to explicitly declare when a value might be null\/None, and by being required to explicitly deal with the null\/None case when it might occur. I&#8217;ve spent much less time debugging that kind of error in my year at foursquare than in the 15 years of professional development that I did before. That&#8217;s not because I magically became a better programmer a year ago when I joined foursquare. It&#8217;s because I&#8217;m using a better tool that helps me avoid mistakes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, my post on monads apparently set of a bit of a firestorm over my comments about avoiding null pointer exceptions. To show you what I mean, here&#8217;s a link to one of the more polite and reasonable posts. Ok. So. Let me expand a bit. The reason that I think it\u2019s so great that [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[54],"tags":[],"class_list":["post-1872","post","type-post","status-publish","format-standard","hentry","category-programming"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/s4lzZS-nulls","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/1872","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=1872"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/1872\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=1872"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=1872"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=1872"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}