{"id":130,"date":"2012-12-28T15:04:04","date_gmt":"2012-12-28T15:04:04","guid":{"rendered":"http:\/\/bryants.eu:7564\/blog\/?p=130"},"modified":"2012-12-28T15:43:39","modified_gmt":"2012-12-28T15:43:39","slug":"nullability","status":"publish","type":"post","link":"https:\/\/bryants.eu\/blog\/2012\/12\/nullability\/","title":{"rendered":"Nullability"},"content":{"rendered":"<p>Nullability is a feature that allows you to specify whether or not something can be null. This is useful because it allows the language to enforce that access to a field or method is via a non-null value. This should make NullPointerExceptions a thing of the past!<\/p>\n<p>In fact, the only place in plinth where you might get a run-time error because of a null value is when you cast from a nullable type to a not-null type.<\/p>\n<p>Let&#8217;s start by looking at some of the things we can and can&#8217;t do with nullable values (the <code>?:<\/code> and <code>?.<\/code> operators are based on those in languages like Groovy):<\/p>\n<pre>\/\/ casting between null and not-null values:\r\nFoo foo = new Foo();\r\n?Foo nullable = foo;\r\nFoo notNull = cast&lt;Foo&gt; nullable; \/\/ throws a run time error if nullable is null\r\n\r\n\/\/ accessing fields and methods:\r\nstdout::println(nullable.someText); \/\/ error: cannot access a field on a nullable object\r\nnullable.doSomething(); \/\/ error: cannot call a method on a nullable object\r\n\r\n\/\/ the null coalescing operator (giving a default value):\r\n?uint index = null;\r\nuint notNullIndex = index ?: 0;\r\n\r\n\/\/ the null traversal operator:\r\n\/\/ (the result is always null if the left-hand-side is null)\r\n?string str = null;\r\n?string subString = str?.substring(0, 2); \/\/ method call (the arguments are only evaluated if str is not null)\r\n?#[]ubyte bytes = str?.bytes; \/\/ field access\r\n?{string -&gt; boolean} equalsFunc = str?.equals; \/\/ method access<\/pre>\n<p>Before I implemented nullability in Plinth, every type was not-null, including custom type definitions. The main thing you need to consider with not-null fields is that they have no default value; this makes plinth&#8217;s default behaviour very different from most major object oriented languages.<\/p>\n<p>Because some fields have no default value, they must be initialised before the end of the constructor. In fact, they must be initialised before the newly allocated object could possibly be accessed from outside the constructor. This means that, until all of the fields of <code>this<\/code> have been given values (or have default ones like zero or null), the value of <code>this<\/code> cannot escape the constructor. In plinth, making sure of this amounts to stopping people from using <code>this<\/code> (except for things like\u00a0<code>this.field = value;<\/code>) and stopping people from calling non-static methods.<\/p>\n<p>So far this is all fine, but what happens when we have two (or more) classes which need not-null references to each other? This problem is difficult to solve, for a number of reasons. I&#8217;ll use the following as a very simple example:<\/p>\n<pre>class A\r\n{\r\n  B b;\r\n  this(B b) \/\/ &lt;-- constructor\r\n  {\r\n    this.b = b;\r\n  }\r\n}\r\nclass B\r\n{\r\n  A a;\r\n  this(A a)\r\n  {\r\n    this.a = a;\r\n  }\r\n}<\/pre>\n<p>Obviously, in this scenario, one of the constructors must always be run first. This seems like it makes it impossible to create either of them, but let&#8217;s suppose that we have a way of allocating an object without calling its constructor. When an object has just been allocated, it&#8217;s still &#8216;uninitialised&#8217; until its constructor has been run. Now, if we could pass an uninitialised object into another constructor, we might be able to do something like this:<\/p>\n<pre>uninitialised A allocA = alloc A;\r\nuninitialised B allocB = new B(allocA);\r\nA a = new (allocA) A(allocB); \/\/ creates an A inside allocA, like C++'s placement-new operators\r\nB b = allocB;<\/pre>\n<p>But now we have more problems. B&#8217;s constructor can&#8217;t let <code>this<\/code> escape until all of the fields are initialised, but now after it&#8217;s done <code>this.a = a;<\/code> it can do whatever it wants, including letting &#8216;this&#8217; escape and trying to access data inside a (which still hasn&#8217;t been initialised yet). We need to mark that the constructor can take certain uninitialised values, and then make sure that it can&#8217;t let &#8216;this&#8217; escape even after everything&#8217;s been initialised. We could do this with an &#8216;uninitialised&#8217; modifier:<\/p>\n<pre>class B\r\n{\r\n  A a;\r\n  uninitialised this(uninitialised A a)\r\n  {\r\n    this.a = a;\r\n  }\r\n}<\/pre>\n<p>Now, we know exactly what isn&#8217;t allowed to escape: &#8216;this&#8217; and &#8216;a&#8217; (we only allow uninitialised parameters in uninitialised constructors). Then, once we&#8217;ve created <code>allocB<\/code>, we know that it being initialised depends only on <code>allocA<\/code> being initialised, since it is the only uninitialised argument.<\/p>\n<p>Next, we call the constructor on <code>allocA<\/code>, to produce\u00a0<code>a<\/code>\u00a0(A&#8217;s constructor will have to be modified the same way as B&#8217;s). We now also know that <code>allocA<\/code> being initialised depends only on <code>allocB<\/code> being initialised. We know the dependency cycle! All that we need to do is find the solution which makes the most things initialised\u00a0(i.e. the\u00a0greatest fixpoint of these simultaneous equations). Then we will know that both of them are initialised, thus allowing the assignments to <code>a<\/code> and <code>b<\/code>.<\/p>\n<p>This scheme is based loosely on some discussions with and papers recommended to me by James Elford, in particular the Freedom Before Commitment paper[1]. However, it is not yet anywhere near implemented in plinth, for several reasons:<\/p>\n<ul>\n<li>I&#8217;ve just come up with it recently, and I have lots of other things before it on my to-do list (interfaces! properties! exceptions!).<\/li>\n<li>Processing the type system for uninitialised values would be extremely complicated, and would involve each type having a list of things which its initialisation state is conditional upon. I&#8217;d like to fill in the rest of the type system before adding this complexity.<\/li>\n<li>It can be easily added later. The only things which would not be backwards compatible with the current language are the keywords.<\/li>\n<li>There are workarounds which can be used in the mean time (see below)<\/li>\n<\/ul>\n<p>That said, this cyclic initialisation scheme is something I would very much like to implement eventually, once all of the problems with uninitialised variables have been well-thought-out.<\/p>\n<p>The slightly ugly workaround which can be used until this scheme is implemented is to have a nullable field and a property to access it. This will give a run-time error whenever a field is accessed on a not-properly-initialised object:<\/p>\n<pre>class A\r\n{\r\n  ?B realB;\r\n  property B b\r\n    getter { return cast&lt;B&gt;<b> realB; }\r\n    setter { realB = value; };\r\n\r\n  this()\r\n  {\r\n  }\r\n  void setB(B b)\r\n  {\r\n    \/\/ this method is only necessary if we make property's setter private\r\n    this.b = b; \/\/ calls property setter\r\n  }\r\n}<\/b><\/pre>\n<p>Next week&#8217;s post will talk about binary compatibility, and how objects in plinth are represented in LLVM bitcode.<\/p>\n<p>References:<br \/>\n[1]\u00a0<a href=\"http:\/\/scholar.google.com\/scholar?q=freedom+before+commitment\">Summers, Alexander J., and Peter M\u00fcller. &#8220;Freedom Before Commitment.&#8221; (2010).<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nullability is a feature that allows you to specify whether or not something can be null. This is useful because it allows the language to enforce that access to a field or method is via a non-null value. This should make NullPointerExceptions a thing of the past! In fact, the only place in plinth where [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/posts\/130"}],"collection":[{"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/comments?post=130"}],"version-history":[{"count":35,"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/posts\/130\/revisions"}],"predecessor-version":[{"id":166,"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/posts\/130\/revisions\/166"}],"wp:attachment":[{"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/media?parent=130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/categories?post=130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bryants.eu\/blog\/wp-json\/wp\/v2\/tags?post=130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}