
{"id":27,"date":"2008-06-22T15:30:18","date_gmt":"2008-06-22T20:30:18","guid":{"rendered":"http:\/\/ikriv.com:8765\/blog\/?p=27"},"modified":"2008-06-22T15:30:18","modified_gmt":"2008-06-22T20:30:18","slug":"f-more-on-types-and-null","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=27","title":{"rendered":"F#: How to Make a Record Type Nullable"},"content":{"rendered":"<p>As I mentioned in the previous post, F# types (as opposed to classes) cannot be <code>null<\/code>. That is, you cannot explicitly make them null, but you can still end up with a <code>null<\/code> value. Here&#8217;s how:<\/p>\n<pre><code>1 type Foo =\n2 { x : int }\n3\n4 let varObj : Object = null\n5 <font color=\"red\">let varFoo1 : Foo = null<\/font> \/\/ this won't work\n6 let varFoo2 : Foo = varObj :?&gt; Foo \/\/ this will\n<\/code><\/pre>\n<p><!--more--><\/p>\n<p>Line 5 will simply not compile, stating that <code>null<\/code> is not a valid value for type <code>Foo<\/code>. Line 6 will compile. I expected to get a runtime exception when executing line 6, but it did not happen. The exception occurs only when we try to access <code>varFoo2.x<\/code>. E.g. I can pass <code>varFoo2<\/code> to a function without error. So, effectively <code>varFoo2<\/code> works as a <code>null<\/code> value of type <code>Foo<\/code>, which we were told cannot exist.<\/p>\n<p>So, if downcasts are involved, even record types can be nullable. This may be a nasty surprise for the developer, especially since there is no protection against this. There is no way to check whether a variable of type <code>Foo<\/code> is <code>null<\/code>: the compiler will tell you that it can never be <code>null<\/code> \ud83d\ude42<\/p>\n<p>Ending up with <code>null<\/code> values for record types is not completely unexpected, since F# record types are internally represented by .NET classes, which are nullable. To avoid nulls, F# compiler needs to closely guard all possible ways by which a variable of a record type may end up with a <code>null<\/code> value. This is one possible path they did not catch.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As I mentioned in the previous post, F# types (as opposed to classes) cannot be null. That is, you cannot explicitly make them null, but you can still end up <a href=\"https:\/\/ikriv.com\/blog\/?p=27\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[10],"tags":[9],"class_list":["entry","author-ikriv","has-more-link","post-27","post","type-post","status-publish","format-standard","category-fsharp","tag-fsharp"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/27","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=27"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/27\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=27"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=27"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=27"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}