My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement | getting started with cfrails
Something's been bothering me lately. It's nothing, really. ?, ?, null, nil, or whatever you want to call it. I think we've got it backwards in many cases. Many languages like to throw errors when you try to use nothing as if it were something else - even if it's nothing fancy.

I think a better default behavior would be to do nothing - at most log an error somewhere, or allow us a setting - just stop acting as if the world came to an end because I *gasp* tried to use null as if it were a normal value.

In fact, just because it's nothing, doesn't mean it can't be something. It is something - a concept at the minimum. And there's nothing stopping us from having an object that represents the concept of nothing.

Exceptions should be thrown when something exceptional happens. Maybe encountering a null value was at some time, exceptional. But in today's world of databases, form fields, and integrated disparate systems, you don't know where your data is at or where it's coming from - and encountering null is the rule, not the exception.

Expecting me to write paranoid code and add a check for null to avoid every branch of code where it might occur is ludicrous. There's no reason some sensible default behavior can't be chosen for null, and if I really need something exceptional to happen, I can check for it.

Really, aren't you sick of writing code like this:

string default = "";
if(form["field"] != null and boolFromDBSaysSetIt != null
  and boolFromDBSaysSetIt)
    default = form["field"];

when you could be writing code like this:

if(boolFromDBSaysSetIt)
    default = form["field"];

I think this is especially horrid for conditional checks. When I write if(someCase) it's really just shorthand for if(someCase eq true). So why, when someCase is null or not a boolean should it cause an error? It's not true, so move on - don't throw an error.

Someone tell me I'm wrong. It feels like I should be wrong. But it feels worse to have the default path always be the one of most resistance.

What do you think?

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!


Comments
Leave a comment

I completely disagree with this. NULL is meant to be an exceptional value, that's the reason it exists. That is it's default behavior.

I would argue that if you are finding it a problem, then the databases you're dealing with, or the code that acquires the data should be modified to handle the problem. NULL isn't a data value, it's an exception to data, so why should it be stored in a database? DBs can refuse null values, so if your column is marked not null, you have a reasonable assumption that you don't have to check it.

I don't think the problem is so much that null causes defensive code, I think the problem is that people have become desensitized to null values. They are exceptional, they do indicate problems (such as uninitialized values) and shouldn't be used for every day occurances.

The default case for your conditional, you answer your own question. If someCase is NOT A BOOLEAN, how can it be evaluated in a boolean expression? That would then raise the question, why can't I use "if (Blah)". Which would beg the question, how does Blah translate to true/false? Equally, how does null translate to true/false?


Consider if you had something like this (C++):
class Cat {
operator bool () const { return false; }
}
...
if (!someCat) {...

Is there a cat? or is there not a cat?

So.. can you imagine how insane debugging code like that could be when a null value slips through and null defaulted to false or true?

I want null exceptions, they make tracking down bugs easier. :)

Posted by Glitch on Apr 09, 2008 at 04:45 PM UTC - 5 hrs

Oh, and for my example above in C++..

C++ considers NULL to be 0. In C++/CLI nullptr gets the same treatment. So, converting the example above (since boolean operator would need dereferencing in C++ due to using pointers not references) to C++/CLI gives the functionality you're kind of suggesting.

Cat ^someCat = nullptr;
if (!someCat) // evaluates to true
someCat = gcnew Cat();
if (!someCat) // evaluates to true.

So, in reality.. null still needs to be accounted for.

Posted by Glitch on Apr 09, 2008 at 04:59 PM UTC - 5 hrs

You can use null most places in SQL where you'd use non-null values, but it almost always does something subtly weird. It's not equal to false, or zero, or an empty string, and it's not even equal to null. This makes sense to me, but I'm not sure that in a 3GL I'd prefer it to just dealing with exceptions. I definitely don't want nulls to start pretending they aren't nulls unless I explicitly ask them to.

On another level, if you have an object the null object pattern is a great way to deal with this - you can independently define null semantics for each class hierarchy. It's just a sad fact that nearly all our OO languages go all procedural on us at some point, beyond which we're back to writing != null.

Posted by Jaime Metcher on Apr 09, 2008 at 09:44 PM UTC - 5 hrs

> I want null exceptions, they make tracking down bugs easier.

I considered that - which is why I mentioned the bit about having a setting somewhere.

Re: null evaluating as false in boolean expressions, it can certainly happen - Both Javascript and Ruby (that I know of off the top of my head) consider null to be false.

In C and C++, as you mention null is 0 - and 0 evaluates to false IIRC.

I guess what I really want is for Java and C# (and ColdFusion, specifically for booleans) to have a different concept of NULL than they do. In CF, there is no null really - if you try to access a hash with a key that doesn't exist, it does throw an error. But if you get null from the DB it's just a blank string. This is irritating when you want to decide what to do based on a column that could be null.

But it's retarded in .NET, for example, if an Active Directory object does not have a value for a field, it's null. So, for every field before I do anything with it, I actually have to check to see if exists in that particular AD object.

I just think nulls are so common, that maybe they need a new construct or they should have thought about using null a bit harder depending on what is going on.

Jaime - I see what you're getting at- I wouldn't like that either. So, maybe I really want something else - but I'm having trouble finding words for it. I hope I can eventually do better than what I tried above. =)

The truth is there are cases where I care *a lot* about if an object is null, and there are cases where I don't care. Because of how prolific nulls are in everything, there spots I don't care far outnumber those where I do.

Posted by Sammy Larbi on Apr 10, 2008 at 04:19 PM UTC - 5 hrs

It kind of seems most of your dislikes are steming from the APIs and technologies external to the actual languages.

For instance, Active Directory. The reason most properties return null is because many of the default schema properties are MayContain properties. Which mean the object doesn't have to have those properties. So, if the object doesn't have the property, it only makes sense to return null (like any other property that isn't on the object). MustContain properties will always return the value they've been initialized with (and the object can't be created without initializing MustContain properties).

Likewise, a good database API (i hesitate to say like ADO.NET), provides wrapper objects like DataRow which contain methods to test for null columns. Even perl's db library returns undef for null columns.

I personally don't think any of these are the fault of the language. Unless the language specifically does something wrong (like evaluating null to ""), I don't see any reason to change the language for the faults of the APIs.

One thing to look at though, if the .NET libraries are truley frustrating, is extension methods for C# 3.0. You can write an extension method for say, Object that allows you to IsNull any object (even null references, since it is a compiler trick and not a real instance method). You could even implement a new method for specific classes to provide you with the default values you wanted.

Posted by Glitch on Apr 10, 2008 at 05:17 PM UTC - 5 hrs

Leave a comment

Leave this field empty
Your Name
Email (not displayed, more info?)
Website

Comment:

Subcribe to this comment thread
Remember my details
Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (21)
AI/Machine Learning (12)
C++ (4)
cfrails (22)
ColdFusion (80)
Customer Relations (15)
DRY (18)
DSLs (11)
Future Tech (4)
Games (5)
Groovy/Grails (7)
IDEs (8)
Java (41)
JavaScript (2)
Lisp (1)
Mac OS (1)
Miscellany (59)
OOAD (34)
Programming (97)
Programming Quotables (5)
Rails (18)
Ruby (50)
Save Your Job (40)
scriptaGulous (4)
Software Development Process (22)
TDD (39)
TDDing xorblog (6)
Tools (3)
Web Development (2)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit

Reading List
InfoQ - Agile, Ruby, & more
Ray Camden - Cf Jedi Master
Ron Jeffries' XP Mag
Peter Bell's Application Generation
Others coming...

RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner