<?xml version="1.0" encoding="windows-1252"?>
<node id="1019806" title="&quot;undef&quot; is not NULL and what to do about it" created="2013-02-20 11:31:57" updated="2013-02-20 11:31:57">
<type id="120">
perlmeditation</type>
<author id="17000">
Ovid</author>
<data>
<field name="doctext">
&lt;h1&gt;What's wrong with undef?&lt;/h1&gt;

&lt;p&gt;Currently &lt;tt&gt;undef&lt;/tt&gt; has three different coercions: false, zero, or the empty
string. Sometimes those are correct, but not always. Further, by design, it
doesn't always emit warnings:&lt;/p&gt;

&lt;code&gt;
$ perl -Mstrict -Mwarnings -E 'my $foo; say ++$foo'
1
$ perl -Mstrict -Mwarnings -E 'my $foo; say $foo + 1'
Use of uninitialized value $foo in addition (+) at -e line 1.
1
&lt;/code&gt;

&lt;p&gt;And because it has no precise definition, &lt;tt&gt;undef&lt;/tt&gt; might mean any of a number
of things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The value's not applicable&lt;/li&gt;
&lt;li&gt;It's not known&lt;/li&gt;
&lt;li&gt;It's not available&lt;/li&gt;
&lt;li&gt;It's restricted&lt;/li&gt;
&lt;li&gt;Something else?&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;In other words, the behavior of &lt;tt&gt;undef&lt;/tt&gt; is overloaded, its meaning is
ambiguous and you are not guaranteed to have warnings if you use it
incorrectly.&lt;/p&gt;

&lt;p&gt;Now think about SQL's &lt;tt&gt;NULL&lt;/tt&gt; value. It's problematic, but no alternative has taken hold for simple reason: its meaning is clear and its behavior is unambiguous. It states quite clearly that 'if I don't have a value, I will treat that value as "unknown" via a set of well-defined rules'.&lt;/p&gt;

&lt;p&gt;So, between the ambiguity of Perl's "undef" and the clarity of SQL's NULL, it's probably not surprising that some code could use the latter instead of the former. In fact, I will go further as to assert that the code is often clearer if you do that. Case in point:&lt;/p&gt;

&lt;code&gt;
foreach my $employee (@employees) {
    if ( $employee-&gt;salary &lt; $threshold ) {
        increase_salary( $employee, 3_000 );
    }
}
&lt;/code&gt;

&lt;p&gt;I'm sure plenty of you see the bug: what if the employee doesn't have a salary? I've already outlined several reasons above for why the salary might be undefined, not all of which mean "this employee has no salary".  So if salary is undefined, you will probably get a warning and you'll have a bug. If threshold is undefined you'll get a warning but you won't have a bug. Fun, eh? So you might rewrite the code like this:&lt;/p&gt;

&lt;code&gt;
if ( defined $threshold ) {
    foreach my $employee (@employees) {
        my $salary = $employee-&gt;salary;
        next unless defined $salary;
        if ( $salary &lt; $threshold ) {
            increase_salary( $employee, 3_000 );
        }
    }
}
&lt;/code&gt;

&lt;p&gt;Now that's starting to get ugly. Wouldn't it be if we had simple, clear NULL semantics instead? Now you can, with [dist://Unknown::Variables]. &lt;a href="http://blogs.perl.org/users/ovid/2013/02/three-value-logic-in-perl.html"&gt;I explain this idea at length at blogs.perl.org&lt;/a&gt;, but it works like this: instead of using "undef", you use "unknown".&lt;/p&gt;

&lt;code&gt;
use Unknown::Variables;

my $value   = unknown;
my @array   = ( 1, 2, 3, $value, 4, 5 );
my @less    = grep { $_ &lt; 4 } @array;   # assigns (1,2,3)
my @greater = grep { $_ &gt; 3 } @array;   # assigns (4,5)
&lt;/code&gt;

&lt;p&gt;There's a lot more to this module than meets the eye, but the idea is that the &lt;tt&gt;unknown&lt;/tt&gt; keyword (well, it acts like a keyword), unlike &lt;tt&gt;undef&lt;/tt&gt;, has clear, well-defined semantics and and predictable behavior.&lt;/p&gt;

&lt;p&gt;In the employee salary example above, if an unknown salary returns &lt;tt&gt;unknown&lt;/tt&gt; instead of &lt;tt&gt;undef&lt;/tt&gt;, our code goes back to the original:

&lt;code&gt;
foreach my $employee (@employees) {
    if ( $employee-&gt;salary &lt; $threshold ) {
        increase_salary( $employee, 3_000 );
    }
}
&lt;/code&gt;

&lt;p&gt;Further, you won't generate any warnings because warnings are there to warn you when you're doing something bad. In this case, &lt;tt&gt;unknown&lt;/tt&gt; values are &lt;em&gt;designed&lt;/em&gt; to be compared an behave appropriately. And as you can see, our code above becomes much simpler. When used appropriately, unknown values can let your code focus on the problem rather than work around fiddly bits of the language. Any place that you find yourself assigning undef in your code, see what would happen if you put an unknown value there instead.&lt;/p&gt;

&lt;p&gt;Feedback welcome. &lt;a href="http://search.cpan.org/dist/Unknown-Values/"&gt;Download the code from the CPAN&lt;/a&gt; or, if you want to hack on the code, &lt;a href="https://github.com/Ovid/unknown"&gt;clone it on github&lt;/a&gt;.&lt;/p&gt;

&lt;!-- Node text goes above. Div tags should contain sig only --&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-17000"&gt;
&lt;p&gt;Cheers,&lt;br /&gt;
&lt;a href="/index.pl?node=Ovid&amp;lastnode_id=1072"&gt;Ovid&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href="http://www.overseas-exile.com/"&gt;Live and work anywhere in the world&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;&lt;a href="http://www.perlfoundation.org/perl6"&gt;The official Perl 6 wiki&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</field>
</data>
</node>
