Slashdot Mirror


Null References, the Billion Dollar Mistake

jonr writes "'I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. In recent years, a number of program analysers like PREfix and PREfast in Microsoft have been used to check references, and give warnings if there is a risk they may be non-null. More recent programming languages like Spec# have introduced declarations for non-null references. This is the solution, which I rejected in 1965.' This is an abstract from Tony Hoare Presentation on QCon. I'm raised on C-style programming languages, and have always used null pointers/references, but I am having trouble of grokking null-reference free language. Is there a good reading out there that explains this?"

82 of 612 comments (clear)

  1. null or not null, that is the question by alain94040 · · Score: 5, Interesting

    It's hard to imagine life without the null pointer! That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are.

    If there is one thing I'll complain about, it's the choice of the value 0. It's almost impossible to trace it. When we do hardware debug of chips, we prefer to use a much more visible value such as 0xdeadbeef for instance. Otherwise a bad pointer will bland too much with all the uninitialized values out there.

    In assembly, null has no particular meaning. If you dereference an address, you can do it in any range you like. It's just that 0 on most machines was not a good place to store anything, since it would typically be used to boot the OS or some other critical IO function that you don't want to mess up with. Thus null was born.

    1. Re:null or not null, that is the question by CTalkobt · · Score: 4, Insightful

      When debugging at the hardware level it's fairly common to fill uninitialized memory (or newly allocated in a debug version of the malloc libraries) with a value that will either cause the computer to execute a system level break ( eg: TRAP / BRK etc) or something fairly obvious such as ($BA).

      If you don't like the 0's, then replace your memory allocation library.

      --
      There's a gorilla from Manilla whose a fella that stinks of vanilla and has salmonella.
    2. Re:null or not null, that is the question by LiquidCoooled · · Score: 2, Informative

      its not the memory allocation library that is at fault.
      its the expectation of the app developer to instincively do

      if(!ptr){ ... }

      you have to change the fundimental way the compiler works and alter boolean logic to account for existing code which works like this to then accept 0xdeadbeef under some conditions and not others.

      --
      liqbase :: faster than paper
    3. Re:null or not null, that is the question by jeremyp · · Score: 3, Insightful

      That's all very well, but in a production environment when dereferencing a NULL pointer you'd probably rather have the program crash than carry on merrily with bad data. With a zero null value, you can easily arrange for this to happen by protecting the bottom page of memory from reads and writes. That way, even an assembly language program can't dereference a null pointer.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
    4. Re:null or not null, that is the question by larry+bagina · · Score: 2, Informative

      In assembly, 0 is much easier to check for.

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

    5. Re:null or not null, that is the question by fishbowl · · Score: 2, Interesting

      The C specification already requires the compiler to deal with that, and it's been the case since K&R. No matter what the implementation defines as NULL, comparing or assigning 0 in a pointer context always works.

      http://c-faq.com/null/ptrtest.html

      --
      -fb Everything not expressly forbidden is now mandatory.
    6. Re:null or not null, that is the question by Anonymous Coward · · Score: 2, Funny

      When we do hardware debug of chips, we prefer to use a much more visible value such as 0xdeadbeef for instance.

      I've recently seen that one of our developers is using 0xfeedface 0xb00bf00d, which is nice and inventive.

    7. Re:null or not null, that is the question by cant_get_a_good_nick · · Score: 3, Interesting

      RE: malloc pattern initializer

      what's a good one for x86 and AMD64 chips? While spelunking flags for valgrind, i remembered the thought process for 68k chips. Use an A-Line trap, unimplemented so execution would stop. Also, make it odd, so a dereference would trigger a bus error.

      What's the best values for x86 debugging?

    8. Re:null or not null, that is the question by marcansoft · · Score: 4, Informative

      Wrong. A NULL pointer is implementation-defined in C and !p would work just as well if the bit value of p were 0xdeadbeef for a NULL pointer. The compiler is responsible for that.

      0 is used because it's convenient for compilers and architectures, not for programmers. Programmers don't care, they never see the bit pattern of a NULL pointer unless they're doing things wrong (casting to integers) or working on lower level architecture-specific code. Most think they do, though. See the C-faq section on NULL pointers.

    9. Re:null or not null, that is the question by johny42 · · Score: 5, Funny

      That being said, the author is not really responsible for billions of dollars of mistakes, the programmers are.

      Who am I to argue with someone that is taking resposibility for my mistakes?

    10. Re:null or not null, that is the question by rickb928 · · Score: 2, Interesting

      The first time I saw an ethernet MAC address of 02DEADBEEF20 I went on a 20-minute snipe hunt through the switches.

      It was the /dev/net0 adapter in the standby member of a Sun cluster.

      A month later, I got the inevitable frantic voicemail from the telecom guy, asking what the '^&(*ing 02DEADBEEF20 address' was, and would I pay more attention to these things and secure our network, please and thank you. I told him it belonged to the Teleradiology project, not to worry. He accused me of being an imbecile, that wasn't a legitimate MAC address. I asked him why he hadn't brought this up in any of the weekly meetings for a month, since it was there all along. Hung up on me. I took some time to creat some interesting LAAs for the various minor servers we had, especially the Internet gateway/proxy, and the email server. He was not amused, but his boss was. And told me to stop annoying him. Something about a gun in the monkey cage, if I recall.

      I actually liked the created MAC addresses. Easier to trace. Mundane vendor-supplied MACs are just boring. Hopefully, though, other admins didn't start being creative. There are only so many clever permutations. Thank God for NAT and Token-Ring. Those were the days.

      --
      deleting the extra space after periods so i can stay relevant, yeah.
    11. Re:null or not null, that is the question by Thiez · · Score: 5, Insightful

      > Another behaviour by default that C got wrong is initialisation: by default your variables are not initialised so if you forget to initialise your variables your program may act randomly which is a pain to debug, the correct default would be to have all variables initialised by default but with the option to let variables non-initialised which can be useful as a performance optimisation.

      C did NOT get it 'wrong'. C just gives you a lot of rope to hang yourself with. You are free to write you own version of C that protects you from yourself (tweaking an open source C-compiler to initialise all variables by default (to what value?) should take you a few hours at most, and most of that time will go to finding the right source file to edit...), but I like it when C obliterates my foot every now and then. Alternatively you could write a program that goes through your code to look for situations where variables that may be uninitialised are used (I believe Java does this) and whines about it.

    12. Re:null or not null, that is the question by CecilPL · · Score: 2, Informative

      One exists and one doesn't. If you have a Foo&, you're guaranteed that it refers to an actual Foo object. You can't declare "Foo& foo;" without binding it to an instantiated object.

      Of course nothing stops you from have a reference bound to an object that's gone out of scope, but that's different than a "null reference", which doesn't exist.

    13. Re:null or not null, that is the question by Amazing+Quantum+Man · · Score: 3, Informative

      Undefined behaviour. A reference must refer to a valid object. Also, dereferencing the null pointer (ip) is undefined behaviour.

      --
      Fascism starts when the efficiency of the government becomes more important than the rights of the people.
    14. Re:null or not null, that is the question by Carewolf · · Score: 2, Interesting

      You have much to learn. Don't mix how the language is supposed to work and what is actually possible.

      P *p = 0;
      P &r = *p;

      References that are NULL are the worst kind.

    15. Re:null or not null, that is the question by clone53421 · · Score: 2, Interesting

      How about 0xCC (INT 3), which is typically used as a debug breakpoint? It will halt the execution (as long as you're running the code in a debugger, which is assumed), and it's a one-byte opcode which is good since that means if you somehow jump into unallocated space, you can't jump into the middle of the instruction.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    16. Re:null or not null, that is the question by clone53421 · · Score: 2, Interesting

      Well, jumping into memory filled with 0xBA would repeatedly execute the instruction 0xBABABA, or MOV DX,0xBABA. I'm thinking that's probably not what GP meant by $BA, but... well, that's all I came up with.

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    17. Re:null or not null, that is the question by belmolis · · Score: 2, Informative

      If that is true, the language compiled by the IBM POWER XLC compiler is not C. The C standard requires short-circuit evaluation of logical and.

    18. Re:null or not null, that is the question by jythie · · Score: 2, Informative

      While there might be a aesthetic difference in C++, functionally they are identical since a reference is just a pointer with some syntactical sugar to make it look like it isn't.

    19. Re:null or not null, that is the question by jvkjvk · · Score: 3, Insightful

      Mods are on crack.

      Of course there is more than a syntatic difference between a reference and a pointer in C++.

      For one, references CANNOT be null, while pointers are allowed to be null. I'd say that is an indictor of a pretty big semantic difference, wouldn't you?

      To say that * or & "fixes" the difference is handwaving around the fact that pointers and references are two different, yet related concepts (that is, they have more that a "purely syntatical" difference).

      To be pendatic, you can't even write a null reference in C++; the compiler will complain (more pendantic - although you can delete the underlying object sometimes, this does not make the reference null, merely dangling) so it is also nonsensical to talk about "null references" vis a vis "null pointers" per se, except in a most general way.

      Regards.

    20. Re:null or not null, that is the question by Toonol · · Score: 4, Funny

      MOV DX, BABA; GET UP N DANCE

    21. Re:null or not null, that is the question by geekgirlandrea · · Score: 4, Informative

      Actually, in C the null pointer constant is a distinct value from integer zero. The standard requires the following (see section 6.3.2.3 of ISO C99):

      • That the integer value 0, when cast to any pointer type, yield a null pointer
      • That a null pointer, when cast to any other pointer type, yield another null pointer
      • That any two null pointers will compare as equal, regardless of type

      As for constructions like if (!ptr), the standard requires that the if statement execute if its value is non-zero, and it would be entirely legal for the null pointer to have a non-zero in-memory representation, but convert to the integer zero. See, for example, the comp.lang.c FAQ.

    22. Re:null or not null, that is the question by Guy+Harris · · Score: 2, Informative

      I think Microsoft Visual C uses 0xCCCCCCCC.

      No, it represents a null pointer as an all-bits-zero value, as do almost all other C implementations.

      But then you have to code:

      No, you don't. In the C Programming Language, if p is a pointer, then !p, p != 0, and p != NULL mean the same thing, regardless of how null pointers are represented.

    23. Re:null or not null, that is the question by wiredlogic · · Score: 2, Informative

      NULL has always been implementation defined. The whole reason why the macro was put into ANSI C was to move people away from the practice of casting a 0 into a pointer as was done with K&R C. While rare today, there have been commercial computers that didn't use 0 for the null address. The comp.lang.c FAQ lists some of them.

      Stroustrup's unwillingness to implement a null keyword is the biggest single flaw in C++. It's pretty silly to pepper your code with magic 0's when the compiler could very well be changing them to something else if the target platform uses a different convention for nulls. It completely flies in the face of the type safety mechanism in C++ to have this sort of automatic conversion of a literal integer into something else that is decidedly *not* an integer.

      Considering all the cruft that has been bolted onto C++, it's really annoying that B.S. couldn't see the wisdom of having a "null" keyword (or "_Null" a la C99 "_Bool").

      --
      I am becoming gerund, destroyer of verbs.
    24. Re:null or not null, that is the question by JackStrife17 · · Score: 2, Insightful

      >I like it when C obliterates my foot every now and then.

      Once again reinforcing the stereotype that people who enjoy programming in C are masochists at heart.

    25. Re:null or not null, that is the question by 7+digits · · Score: 2, Informative

      > I'm sure it doesn't help things that Stroussoup made this explicit [att.com] in C++. So if your view is that C is a subset of C++, you'll get these trivia wrong. Unfortunately, C and C++ will penalize you for getting trivia questions wrong with great zeal.

      You are wrong on two counts: first, his name is Stroustrup. Second, in C++, like in C, the literal 0 in a pointer context will be turned into the NULL pointer by the compiler.

      void *p = (void*)0;

      p will be a NULL pointer

      int a = 0;
      void *p = (void *)a;

      p may not be a NULL pointer, as the 0 was not a literal in a pointer context.

      Hence,

      if (p)

      means:

      if (p==0)

      so, if p is a pointer type, it means:

      if (p==(void*)0)

      which means

      if (p is the NULL pointer)

      The NULL pointer can be represented internally by whatever bitpattern or trick that the compiler writer wants.

  2. 20 second explanation by AKAImBatman · · Score: 4, Interesting

    I am having trouble of grokking null-reference free language.

    If you're familiar with SQL, then a simple "MyColumn NOT NULL" definition should explain it. Basically, the value can never be set to a null value. Attempting to do so is an error condition itself.

    In fact, DB design is a pretty good analogy for the concept as databases often are forced to wrestle with this issue.

    Consider for a moment how you would design a database that has absolutely NO null references. Not a one. Zip, zero, nada. Obviously the best way of accomplishing such a database is to denormalize any value that might be null. So if Address2 is optional, you would want to split Address into its own table with a parent key pointing back to the user entry. If the user has an Address2 value, there will be a row. If the user does NOT have an Address2, the row will be missing. In that way, empty result sets take the place of null values.

    In terms of programming languages, there are a varity of ways to map such a concept. Collections are a 1:1 mapping to result sets that can work. If you don't have any values in your collection, then you know that you don't have a value. Very easy. Similarly, you can be sure that none of the values passed to a function or method will ever contain a null value. Cases where you might want to pass some of the values but not all can be handled either by method overloading (e.g. Java) or by allowing a variable number of parameters. (e.g. C)

    Some pieces of programming would become slightly more difficult. For example, 'if(hashmap.get("myvalue") != null)' would not be a valid construct. You'd need to perform a check like this: 'if(hashmap.exists("myvalue")'

    Of course, the latter is the "correct" check anyway, so the theory goes that the software will be more robust and reliable.

    1. Re:20 second explanation by Anonymous Coward · · Score: 3, Insightful

      doesn't NULL in SQL represent "unknown", which is something entirely different that a NULL reference, which in the context of programming languages is a discrete value?

    2. Re:20 second explanation by MattRog · · Score: 5, Informative

      "Obviously the best way of accomplishing such a database is to denormalize any value that might be null"

      That's normalizing -- the table in this example is de-normalized

      --

      Thanks,
      --
      Matt
    3. Re:20 second explanation by AKAImBatman · · Score: 4, Informative

      doesn't NULL in SQL represent "unknown", which is something entirely different that a NULL reference

      No. NULL in SQL represents an absence of data. Which is occasionally used to cover for unknown values. However, NULL is a piece of data that says there is an absence of data. Which is incorrect. Absence of data means that it doesn't exist. Therefore, nothing should exist in its place.

      Normalizing the database can create a situation where the NULL is unnecessary. Therefore, the concept is not needed by computer science. The problem is that real-world considerations often override the ivory tower of comp-sci. And one of those considerations was the fact that RDBMSes have traditionally been organized according to a fixed column model. The inflexibility of the model is driven by the on-disk data structures which are optimized for fast access. OODBMSes (which are really fancy RDBMSes with many "pure" relational features that work around the traditional weaknesses of RDBMSes) attempt to solve this issue by introducing concepts like table-less storage, columns that may or may not exist on a per-row basis, and a dynamic typing system that potentially allow for any data type to show up in particular column. (Note that columns are often handled more as key-value pairs than what we normally think of as columns. This does not undo the theoretical foundation of the Relational model, only results in a different view on it.)

    4. Re:20 second explanation by AKAImBatman · · Score: 4, Insightful

      Consider the situation of apples. If you have an apple, then something is in your possession. If you don't have an apple, what do you have? Do you have some sort of object that depicts your lack of an apple? Obviously not. Yet in the world of computers, we have this special piece of data that shows our lack of data. It's a bit like getting a certificate that you have no apples. The certificate accomplishes nothing except to fill a space that does not need to be filled.

    5. Re:20 second explanation by BigHungryJoe · · Score: 2, Interesting

      Ok, I'm far from an expert on SQL, but if NULL doesn't represent "unknown" in SQL, then why does

      select 1 from dual where 1 not in (2,3,NULL);

      return an empty set?

    6. Re:20 second explanation by AKAImBatman · · Score: 2, Informative

      That's a misunderstanding of the spec. NULL has no type, so evaluating NULL = 1 results in an unknown. That does not imply that NULL is an unknown value. I believe this reply on the PostgreSQL mailing list explained it best:

      0 <> NULL (Indeed nothing equals NULL, other then sometimes NULL itself)

      0 <> 1

      Therefore, the statement: 0 NOT IN (NULL, 1)
      Should always equate to false.

      Therefore No rows returned. Ever.

      It's a bit weird, but it makes sense when you actually follow the logic.

    7. Re:20 second explanation by AlecC · · Score: 2, Informative

      What NULL "means" is undefined. There are at least two possible meanings, and it is up to the database designer to define, for every column in which null is allowed. The two meanings obvious meanings are either "unknown" or "has not got". For a Date Of Birth column, it is obviously "unknown", because everybody has a DOB. But what does a null Date Of Death column mean? In a commercial context, it probably means that, so far as the database is concerned, the person is still alive. But in a historical database, it could mean that the DOD is really unknown, or that the person is alive. Likewise an Address3 line might interpret NULL as Address3 is "unknown" if Address1 is null and "has not got" if Address1 is non-null. Good database design will always specify this.

      --
      Consciousness is an illusion caused by an excess of self consciousness.
    8. Re:20 second explanation by jadavis · · Score: 4, Insightful

      It's a bit weird, but it makes sense when you actually follow the logic.

      Not really.

      The expression "0 <> 1" is true, but the poster you referenced also says "0 <> NULL", which is NOT true, it is NULL.

      Additionally, NULL is not always treated as false-like. For instance, if you added the constraint "CHECK (0 NOT IN (NULL, 1))", that would always succeed, as though it was "CHECK(true)".

      And if you think "it makes sense", consider this: ... WHERE x > 0 OR x <= 0
      If x is NULL, that statement will evaluate to NULL, and then be treated as false-like, and the row will not be returned. However, there is no possible value of x such that the statement will be false.

      I'm not a big fan of NULL, but I think the most obvious sign that it's a problem is that so many people think they understand it, when they do not.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
    9. Re:20 second explanation by pi_rules · · Score: 2, Informative

      It'll blow up in C# and Java.

    10. Re:20 second explanation by geekoid · · Score: 2, Informative

      You can disagree all you like, but read the spec. NULL is absences of data. Undefined data is still data, just not defined, since NULL isn't a type, it can't be any type data. IT was specifically created to show absence of data.

      Look it up.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    11. Re:20 second explanation by AKAImBatman · · Score: 3, Informative

      You need to have NULL to represent missing data, anything else is actual data.

      I don't think you understand the argument. Having the following is incorrect:

      ID|Name|State|Address|Address2
      5|Bob|MN|12 East St.|NULL

      THIS is correct:

      ID|Name|State
      5|Bob|MN
       
      ID|Parent|Address|Order
      22|5|12 East St.|1

      Note how there is no NULL value. In fact, NULL is antithetical to relational theory as all set values should have a value. Missing data should be normalized away.

      There are only people who can't intuitively understand 3VL.

      3 value logic has nothing to do with it. 3VL actually creates problems in this case. In fact, your very own snarky comment above is a perfect example of how things go wrong with 3VL:

      ID|Contestant|Prize
      2|AKAImBatman|NULL
       
      resultset = sql("select Prize from Contestants where Contestant = 'AKAImBatman');
       
      //Prints the stupid "NULL" answer
      while(resultset.next()) print("He leaves with " + resultset["prize"] + " the home game.");

      FAIL.

      Now look at this situation:

      ID|Contestant
      2|AKAImBatman
      3|geekoid
       
      Parent|Prize
      3|Remedial 6th Normal Form
       
      resultset = sql("select Prize from Prizes join Contestants on Contestants.ID = Prizes.Parent where Contestant = 'AKAImBatman'");
       
      //Correctly prints nothing
      while(resultset.next()) print("He leaves with " + resultset["prize"] + " the home game.");

    12. Re:20 second explanation by vux984 · · Score: 2, Informative

      Normalizing the database can create a situation where the NULL is unnecessary.

      Not reallly. Suppose I'm going to do a mail out to my customers... so I need a table of addresses

      select *
      from addresses inner join addressline2s on addresses.pkey = addressline2s.fkey

      And what happens? I'm now missing all the addresses that don't have a line 2. Well that's worthless.
      how about:

      select *
      from addresses left outer join addressline2s on addresses.pkey = addressline2s.fkey

      Yay, all my addresses. And I can cursor through them. ... except wait... I've got a bunch of nulls in the returned set. Even though my database doesn't contain any nulls, my simple query does...

      So what was the point of eliminating them from the database?

      Now in the real world, any amount of information might be missing, not just line 2. There are addresses without cities, without streets, Addresses in particular are difficult to model well. In fact the whole 'address line 1, line 2, line 3' thing is aready a cop-out because its too much effort to normalize addresses into separate fields. And when dealing with international addresses, it usually just simplest to give them a multiline text block and say, here, you fill it out the way you want...

      Russian addresses for example are supposed to be upside down. In Canada the postal code is supposed to be after the province, in Sweden its before the city (and there is no province...)... etc. So even if you've got the right fields, the order is wrong. You could spend a year just modeling street addresses.

    13. Re:20 second explanation by clone53421 · · Score: 2, Funny

      ...this: 'if(hashmap.exists("myvalue")'

      ...is the "correct" check anyway...

      Well, it'd be "correct" if it had the right number of parentheses, anyway! ;p

      --
      Alexander Peter Kristopeit bought his basement from his mommy for one dollar.
    14. Re:20 second explanation by thePowerOfGrayskull · · Score: 3, Insightful

      And if you think "it makes sense", consider this: ... WHERE x > 0 OR x <= 0 If x is NULL, that statement will evaluate to NULL, and then be treated as false-like, and the row will not be returned. However, there is no possible value of x such that the statement will be false.

      If x is NULL, the statement evaluates to false. This isn't "false-like"; NULL is the state of not having a value. Comparing a non-value to /any/ value of or range of values is logically false: X is neither LTE 0 nor is it GT 0; a non-value has no relation to the value 0.

      While you can use it to derive a true/false value, NULL is not a (in the RDBMS context) value at all. Would you say in mathematics "empty set" makes no logical sense?

    15. Re:20 second explanation by Estanislao+Mart�nez · · Score: 3, Informative

      Variant types (or, put more generally, algebraic data types) are indeed a general solution for this problem, that can be reused for countless others.

      The simplest example here is the way you define linked list types in a functional language like Haskell. In pseudo-code (yes, I know this might not be valid Haskell code):

      data List a = EmptyList | Node a (List a)

      This is a data type declaration that says that the type "List of a" is either the singleton EmptyList value, or a 'Node a' value, which contains (as struct fields, basically) an element of type a and a List of a. (In case it isn't clear, 'a' is a type parameter here; so a list of strings would be 'List String', a list of integers would be 'List Integer', and so on.)

      This works just as well to allow you to define generic nullable type constructors (which the standard Haskell library provides):

      data Maybe a = Nothing | Just a

      The type 'Maybe String' represents a value that might be either 'Nothing', or 'Just x' for some x of type String.

    16. Re:20 second explanation by Estanislao+Mart�nez · · Score: 2, Insightful

      See my post right above yours. Basically, one way of "abolishing null" is to replace it with more general variant type features that allow you to guarantee that nulls can only occur where your program declares they may. In that case, the answer to your question is simple: if your hash table's if of type Map, then the get operation's signature is something like this:

      nullable V get(K key)

      The idea behind this sort of solution is that the nulls problem isn't the existence of nulls, but rather, the fact that the language type system forces every type in your program to admit null in its domain. The solution is to distinguish between the type of a Foo and the type of "Foo or nothing."

    17. Re:20 second explanation by vux984 · · Score: 2, Interesting

      If you put the right thing in the right field, and always in the right field, and only in the right field (so help me God) you just need some kind of template per country, e.g for Belgium: boxnumber, street housenumber [newline] postcode city.

      You should be able to find them from the IPU, or deduce them by looking foor a company in the required country. Shouldn't take you a year, if you ignore all the Bongo-Bongo Land type places.

      Even before you get to bongo-bongo land.

      For Canada your base template might be:

      Mr. Randy Jones
      Widget Manufacturing Inc.
      #101 21 Cordova Street East
      Vancouver, BC, V3H 1T3
      Canada

      But then in comes:

      Mrs. Irene Smith
      General Delivery
      Small Creek, MB, R0E 0K0
      Canada

      "General Delivery", isn't a street or a company; it means drop it off at the post office, they don't bother with mail boxes for each person here. People just come in and ask the postmaster for their mail.) Used to be very common in small rural towns, still a reality in out-of-the-way enough places.

      or another type of rural address like:

      Alice Smith
      Box 22F RR4
      Somewhere, SK, S0N 0A0
      Canada

      Where instead of the street address of the recipient you are identifying a lockbox on a rural route somewhere.

      Then you've got institutional addresses like:

      Dr. Jon Driver
      Office of the Vice President
      3100 Strand Hall
      Simon Fraser University
      8888 University Drive
      Burnaby, BC, V5A 1S6
      Canada

      which needs a bunch of space for all kinds of internal routing information.

      And we haven't gotten out of Canada yet.

      Its not so much that you can't keep adding fields and templates to accomodate these, its that every time you build a system and roll it out, users will shortly bump into an address that doesn't fit... and then they cram the information into the 'wrong fields'. And you might as well have just given them a few blank lines to fill.

      Its also a royal hassle because the address entry form in your application becomes increasingly complicated to use, and the order the system needs to know information, is usually opposite from the way people like giving it.

      Giving them multiple lines to just write what they need is simpler, and doesn't cause problems on the corner cases. I usually use a hybrid for systems used in Canada: a few generic 'address lines' and then city/province/postalcode fields. And I think even there we've run into a couple addresses that don't have cities. Although things have gotten better... the post office in their efforts to automate things have been arbitrarily assigning street addresses to things that don't really have them. (Simon Fraser University, didn't used to have a 'proper' street address, it was just "Simon Fraser University, Burnaby, BC". They added a street address "8888 University Drive" primarily to accomodate computer systems that kept choking on there not being a street address.

      But even today, you might send a message to:

      Dr. John Smith
      Faculty of Arts and Sciences
      University Hall
      Cambridge, MA, 02138
      USA

      with no street number.

    18. Re:20 second explanation by jadavis · · Score: 2, Interesting

      "try it in a CHECK constraint, and it will never fail"

      While I have the standard open, here's a reference to back up my claim above:

      A constraint is satisfied if and only if the applicable <search condition> included in its descriptor evaluates to True or Unknown.

          -- SQL 2008 Part 2: Foundation (SQL/Foundation) section 4.17.2

      And I also tried it in PostgreSQL, which generally has respect for the standard.

      So, a constraint does, indeed, treat NULL as TRUE-like.

      --
      Social scientists are inspired by theories; scientists are humbled by facts.
  3. There was a bigger mistake: by teknopurge · · Score: 2, Insightful

    Null-terminated strings. The bane of modern computing.

    1. Re:There was a bigger mistake: by RetroGeek · · Score: 3, Informative

      A null terminated String is a misnomer. It is actually an array of chars which uses a special character to signify its upper boundary. So that a second variable is not needed to hold the upper boundary. Zero was chosen by K&R.

      In some languages, a String is an object, and the object holds the upper boundary, so a terminator flag is not required.

      --

      - - - - - - - - - - -
      I am a programmer. I am paid to produce syntax not grammar. Deal with it.
    2. Re:There was a bigger mistake: by Rik+Sweeney · · Score: 5, Insightful

      Null-terminated strings. The bane of modern computing.

      Yeah! Let's abolish them, life would be much simplerasdjkaRGfl$!jaekrbFt6634i2u23Q0CCA;DMF ASDJFERR

    3. Re:There was a bigger mistake: by Anonymous Coward · · Score: 4, Funny

      I agree.ï½ï½ï½ï½ï½ï½ï½cï½ï½A
      5ï½)ï½"ï½ï½ï½lï½3åï½ï½ï½SLï½4ï½54Vï½iï½ï½ï½D.O%N|ï½ï½ï½Tï½2nï½ì'iï½ï½ï½;ï½
                                                        ï½,ï½ï½(85ï½Iï½{ï½ï½ï½ï½)ï½Oï½Æ¼ï½%Cï½iwï½ï½ï½ï½ï½ï½I!,.ï½Õ'ï½ï½ï½ï½!ï½òfsQï½ï½zï½ï½Gï½ï½ï½aï½zï½-@ï½ yï½Ë+ï½ï½ï½Xï½ï½ï½ï½"ï½cï½âï½ï½ï½ï½ï½ï½ï½ï½ï½ï½dï½nbÕoeï½ï½ï½ï½lï½ï½ï½ï½ï½;hmï½ï½

    4. Re:There was a bigger mistake: by Panaflex · · Score: 4, Informative

      Which comes from Pascal - which has always had the length at the beginning. Hence why pascal strings always had limits.

      --
      I said no... but I missed and it came out yes.
    5. Re:There was a bigger mistake: by Anonymous Coward · · Score: 2, Informative

      false*. in fact, you have to call c_str() to obtain a null terminated string.
      what happen inside is opaque, and most probably std::string constructed with a grain of salt are the pascal kind (a memory allocation and a separate character counter)

      *depending on your std implementor.

    6. Re:There was a bigger mistake: by Anonymous Coward · · Score: 5, Funny

      Just allocate the same amount of memory for everythi

  4. Wouldn't help by corporate+zombie · · Score: 5, Insightful

    Fine. No null references. So I create the same thing by having a reference to some unique structure (probably named Null) and I still *fail to check for it*.

    Null references don't kill programs. Programmers do.

        -CZ

    1. Re:Wouldn't help by nuttycom · · Score: 4, Interesting

      If you use a sane class for references that could possibly be null (like Option (aka Maybe in haskell) then your compiler will *force* you to handle the null case.

      This is where null went wrong, at least in statically typed languages: it's a hole in the type system that errors fall through into your program. When coding in Java, I make an explicit point to never return null from a method; if I have a situation where no reasonable return value might exist, I use the Option class from functionaljava.org and thus force the client to handle the possibility of the method not returning sensible data. Since Option obeys the monad laws, it's easy to chain together multiple things that might fail (with the bind or flatMap operations.)

  5. Algebraic data types by Sneftel · · Score: 4, Informative

    The concept of "no null references" would be very limiting in a language without algebraic datatypes. You can think of null references as a sort of teeny limited braindead algebraic data type, actually. I get the feeling that much of the incredulity here stems from the posters not being familiar with languages that support them. If this describes you, check out Haskell and OCaML! They're the sort of languages that make you a better programmer no matter what language you're using.

    --
    The opinions stated herein do not necessarily represent those of anybody at all. Deal with it.
  6. Re:Null is just a value by Sneftel · · Score: 2, Insightful

    Actually, if you were defining a "null" value, you'd make it a Top-type, meaning it would be a subclass of all other types. Otherwise you couldn't set an arbitrary reference to point to null, because null would be insufficiently derived.

    --
    The opinions stated herein do not necessarily represent those of anybody at all. Deal with it.
  7. The mistake was actually not having a standard by Nicolas+MONNET · · Score: 4, Insightful

    for Pascal type strings in C. The fact that null-terminated strings existed wasn't the problem, they make some sense in some respects, such as when you want to pass text of arbitrary length. But the real problem, the real bug was not having a standard way of doing real strings in C. Everybody had to do it himself, poorly. Had there been a standard, no matter how poor, it would have been a starting point to do something better if needed, and would have been better anyway for many uses than C strings. It would have avoided MANY vulnerabilities from common software.

    1. Re:The mistake was actually not having a standard by Vanders · · Score: 3, Interesting

      The problem with Pascal strings is that it's easy for a short-sighted implementer to paint themselves into a corner. It's all very well and good to say "The first two bytes in a string are used to indicate the length of the string" but then what do you do a decade from now when a 16bit string is laughably small? The benefit of NUL terminated strings is that there length is only limited by the memory available to you and yet are forward and backward compatible by decades.

  8. Pass by reference by hobbit · · Score: 4, Informative

    I'm raised on C-style programming languages, and have always used null pointers/references, but I am having trouble of grokking null-reference free language.

    Take a look at C++, in which you can declare methods to be "pass by reference" rather than "pass by pointer". Although the former is actually really just passing a pointer too, the semantics of the construct make it impossible to pass NULL.

    --
    "Wise men talk because they have something to say; fools, because they have to say something" - Plato
    1. Re:Pass by reference by johannesg · · Score: 2, Informative

      ... the semantics of the construct make it impossible to pass NULL.

      void bar (int &intref)
      {
          intref++;
      }

      void foo ()
      {
          int *intptr = NULL;

          bar (*intptr);
      } // learn something new every day!

    2. Re:Pass by reference by Chris_Jefferson · · Score: 3, Informative

      According to the C++ standard, as soon as you dereference NULL, you are off into the nasty old land of undefined behaviour, and all kinds of horrible things can occur to you.

      --
      Combination - fun iPhone puzzling
  9. An was an even Bigger mistake: by Wargames · · Score: 5, Funny

    Zero. The bane of all. It was the gateway math to all modern problems. It would be so much simpler with just countables. Surely the current crisis, measured in trillions would look so much better without all those zeros.
    Whoever it was who invented zero should take responsibility for all the worlds problems, ex nehilo.

    --
    -- Each tock of the Planck clock is a new world and here we are still life. --
    1. Re:An was an even Bigger mistake: by AKAImBatman · · Score: 2, Informative

      Null predates zero in the western world. The Romans had no number for zero, but they did represent the concept of nothing with the word 'nulla'. Thus if I had IIII denarii and spent all IIII, I would have nulla remaining. i.e. "nothing".

      As an aside, the numbering is correct. The subtractive form of IV for four is a more modern construct that was not in common use during the Roman empire.

      If you're still hell-bent on finding who defined zero as a legitimate numerical value, you'd need to look to 9th century India. Their mathematics had evolved far enough to where they stopped asking the philosophical question of "is nothing a number?" and simply used it to get math completed.

    2. Re:An was an even Bigger mistake: by jc42 · · Score: 2, Insightful

      Ki>Zero. The bane of all. It was the gateway math to all modern problems. It would be so much simpler with just countables. ... Whoever it was who invented zero should take responsibility for all the worlds problems, ex nehilo.

      Heh. I'm glad someone managed to bring up what should be obvious to anyone competent in basic math. While reading the posts here, I kept thinking "Yeah, and you have the same sort of problems if you allow your numbers to include zero." But I figured that the folks making the silly arguments probably wouldn't understand that sort of verbal irony, so I just let it pass.

      I can easily imagine variants of most of the arguments here being used thousands of years ago against the individuals in India and Central America that started casually using that weird "0" symbol in their calculations. "What's the need for something that doesn't represent anything?" "I only need to count things that exist; there's no reason to count things that don't exist." And on and on.

      This whole discussion does sorta put a limit to any claims of technical competency on the part of the "tech nerd" population of /.

      (And to I need an extra . at the end of that sentence? That oughta be good for a long discussion, as well as the question of whether or not the final ')' in this sentence balances the initial '('. ;-)

      --
      Those who do study history are doomed to stand helplessly by while everyone else repeats it.
    3. Re:An was an even Bigger mistake: by Estanislao+Mart�nez · · Score: 2, Interesting

      Zero. The bane of all. It was the gateway math to all modern problems. It would be so much simpler with just countables. Surely the current crisis, measured in trillions would look so much better without all those zeros.

      Yeah, I know this is a joke, but I've still got to point out the following: a positional numbering system doesn't actually need a zero digit. Throw out zero, and use instead a digit 'X', whose value is ten. Then you get:

      1, 2, ..., 9, X, 11, 12, ..., 19, 1X, 21, ..., 98, 99, 9X, X1, X2, ..., X9, XX, 111, ...

      8X = 8 * X + X (ninety)

      X2 = X * X + 2 (one hundred two)

  10. Bad analogy. by morgan_greywolf · · Score: 2, Funny

    Could you try a better analogy. I think we might all understand a car analogy better...

  11. Null as a concept by JustNiz · · Score: 5, Interesting

    Stroustrup's "C++ Programming Language" book introduces a concept called "resource acquisition is initialisation" that was eye-opening enough to me that it forever changed the way I think about code, and also seems relevant to your point.

    The basic idea is that an object is always meant to represent something tangible. As an example, consider the design of file object that abstracts file I/O operations. As a developer, I've come across this one several times, it is normal that such objects have open and close methods, however that makes the design of the object in contradiction with Stroustrup's concept because open/close provided as methods rather than only called in the constructor/destructor means the object may be in existence yet be in a state where it is not associated with an open file. You basically have to grok that having a file object around that doesn't directly map to an open file just adds overhead to the system and is basically bad OO design in that in some sense that object is meaningless.

    Apply the same concept to a reference and you have your answer. If a reference is pointing at nothing, then what is its purpose? The only thing a NULL reference is good for is when the software design ascribes a special meaning to the value NULL. Instead of just meaning address location 0, it gets subverted to mean "variable unassigned" or the "tail node of list" or somesuch. Ascribing multiple meanings to a variable value (especially pointers/references that are only ever meant to hold memory addresses) is one example of bad programming practice known as programming by side-effect which most people agree should be avoided.

    Another point is that in most OO lanugages, references have an extra benefit of being more strongly typed than pointers, menaing that reference is guaranteed to only ever be pointing at an instantiated object of its specific type. That guarantee also gets broken when a reference can be NULL.

  12. Lying to the language - the real problem. by Animats · · Score: 3, Insightful

    A useful way to think about troubles in language design is to ask the question "When do you have to lie to the language?" Most of the major languages have some situations in which you have to lie to the language, and that's usually a cause of bugs.

    The classic example is C's "array = pointer" ambiguity. Consider

    int read(int fd, char* buf, size_t len);

    Think hard about "char* buf". That's not a pointer to a character. It's a pass of an array by reference. The programmer had to lie to the language because the language doesn't have a way to talk about what the programmer needed to say. That should have been

    int read(int fd, byte& buf[len], size_t len);

    Now the interface is correctly defined. The caller is passing an array of known size by reference. Notice also the distinction between "byte" and "char". C and C++ lack a "byte" type, one that indicates binary data with no interpretation attached to it. Python used to be that way too, but the problem was eventually fixed; Python 3K has "unicode", "str" (ASCII text only, 0..127, no "upper code pages"), and "bytes" (uninterpreted binary data). C and C++ are still stuck with a 1970s approach to the problem.

    The problem with NULL is related. Some functions accept NULL pointers, some don't, and many languages don't have syntax for the distinction. C doesn't; C++ has references, but due to backwards compatibility problems with C, they're not well handled. ("this", for example, should have been a reference; Strostrup admits he botched that one.) C++ supposedly disallows null references (as opposed to null pointers), but doesn't check. C++ ought to raise an exception when a null pointer is converted to a reference.

    SQL does this right. A field may or may not allow NULL, and you have to specify.

    Look for holes like this in language design. Where are you unable to say what you really meant? Those are language design faults and sources of bugs.

  13. maybe type by j1m+5n0w · · Score: 4, Informative

    Maybe types are wonderful. I first thought they were inconvenient, since you have to pattern match against them any time you want to extract the value, but then I realized that that was something I ought to be doing anyways, and the advantages of never accidentally dereferencing a null pointer vastly outweigh a little extra typing. And then, more recently, I figured out how to use the maybe monad to string together a bunch of things that might fail without having to manually pattern match every time.

  14. "core constants" were around at least by 1960s by Ungrounded+Lightning · · Score: 2, Interesting

    The first OS I encountered was tape-based. And it prefilled user memory with a "core constant".

    This was a subroutine jump to an abort routine which printed the return location - which in turn told you where you had improperly jumped to and dumped all your registers, followed by the memory itself if that was authorized. (That was all the info that was left by the time the OS got control.)

    The walls of the computing center contained posters giving this value as it would appear if printed as various types of values (integer, floating point, complex, ...).

    Another machine I dealt with back then was a typesetting device using a Data General Nova and the company's homebrew OS (designed by Mark Weiser of Xerox Parc fame, based on work by Djikstra and Riddle). It had a debugger entry that could be reached by a one-word instruction which we would insert as breakpoints and also use to fill unused memory. The hex form of this was "0c0f". When the machine hit a breakpoint we said it had "coughed".

    --
    Bantam Dominique roosters crow a four-note song. Once you've heard it as "Happy BIRTHday" you can't NOT hear it that way
  15. Too pervasive by shutdown+-p+now · · Score: 2, Informative

    The problem with NULL/null/None as implemented in C++/Java/C#/Python/whatever is that it's pervasive - it always "adds itself" to the list of valid values of any reference type (= pointer type in C++, = any type in Python), in all contexts. At the same time, it isn't truly a valid value, because you can't do with it what you can normally do with any other value of the type. It's actually a lot like signalling NaN for object references, and is an equally bad idea for the same reasons.

    How to handle that? Why, with explicit "nullability markers", and languages which track nullability propagation, and require to check for null everywhere you try to perform an operation that won't work for a null value whenever you have a value that can potentially be null. In FP languages, this is naturally done with ADTs; for example:

    (* Standard library *)
      type 'a option = None | Some of 'a;;
     
      (* User code *)
      let foo (xo : int option) =
        match xo with
        | Some x -> ...
        | None -> ...

    Note that OCaml compiler, in the example above, won't let you omit the "None" branch. You have to handle that (well, you can just pass on the "int option" value, but only to another function that is declared as taking one, and not just "int"). Also note how the other branch is guaranteed to get some specific, "non-null" int value for x.

    These enforced checks prevent silent null propagation, which is the bane of Java, C#, and other languages in the same league. All too often some code somewhere gets a null value where it shouldn't, stores it somewhere without checking for null, and then another piece of code down the line extracts that value (which is not supposed to be null!), passes it around to methods (which pass it to more methods, etc), and eventually crashes with a NullReferenceException - good luck trying to track down the original point of error!

  16. Haskell's null-free behavior by ijones · · Score: 2, Informative

    I can illustrate the concept of a null-free language with examples from Haskell.

    With Haskell types, you can specify all the valid values of a particular bounded type (the same is true for non-bounded types, but its more obvious for bounded ones):

    data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

    Something of type "Day" cannot be NULL. It must be one of the days of the week. It's impossible to construct a value of a "Day" type without "assigning" it one of these values.

    But then what if you want to handle a case where it might be none of these? There's another type for that called "Maybe", and you can wrap "Day" (or any type) in "Maybe" to indicate that it might be none of these. So "Just Monday" is a value simultaneously indicating non-null, and providing the Day value. "Nothing" indicates NULL or "none of the above".

    For instance, if you write a function which gives the next day of the week, given a day of the week, it should input Day and output Day. It doesn't make sense for either its input or its output to be NULL. That is, it should have type "Day -> Day".

    But if you want to handle for instance, a case of user input or parsing, where they might not give a valid day, then you should use the type "Maybe Day" or something similar.

    Values of "Nothing" in Haskell roughly correspond to NULL except that the type system differentiates cases where something might be NULL and cases where something promises not to be NULL.

    This turns out to be a useful distinction :)

    peace,

        isaac

  17. no such requirement at the assembly level by r00t · · Score: 2, Insightful

    The compiler can do anything it damn well pleases, as long as the end result acts like it should.

    The compiler certainly can dereference the pointer. It can also throw in a call to sin(42), a write to some memory containing the current line of code, and a system call to check for pending debugger stuff.

    None of this would make the high-level view of things be anything other than the required short-circuit evaluation of the given code.

    1. Re:no such requirement at the assembly level by thethibs · · Score: 3, Insightful

      You are confusing C with...well, I'm not sure what...Haskell, maybe? In many cases with C, the sequence of events is as important as the end result. C code can have side-effects.

      C is not an expression evaluator, it's a control language; A && B is an instruction to copy A and if it is non-zero, replace the copy with B, in that order. A++ says copy A and then increment it.

      Most of the people on slashdot can tell you why that's important and a few of them have; there are more than a few scenarios where not getting the sequence right would have undesirable effects even if the returned value was correct. Look up memory-mapped I/O.

      --
      I'm a Programmer. That's one level above Software Engineer and one level below Engineer.
    2. Re:no such requirement at the assembly level by russotto · · Score: 2, Informative

      You are confusing C with...well, I'm not sure what...Haskell, maybe? In many cases with C, the sequence of events is as important as the end result. C code can have side-effects.

      The optimizer wouldn't do it unless there were no side effects to the right hand side of the short circuit operator.
      So

      if (foo && (*foo == CONSTANT))
      and
      if (!foo || (*foo == CONSTANT))

      would be optimized in this way
      but

      if (foo && baz(*foo))

      would not (since function baz could have side effects).

      It doesn't matter what was at location 0; the test for null was still evaluated, but condition code arithmetic rather than branches were used to handle it.

    3. Re:no such requirement at the assembly level by iluvcapra · · Score: 2, Insightful

      Volatile keyword often works, since this hint the compiler to always get/set the value on core instead of trying to keep it on a register where other threads couldn't see it, but by the standard, "What constitutes an access to an object that has volatile-qualified type is implementation-defined." ( 3.5.3) and that's not guaranteed.

      --
      Don't blame me, I voted for Baltar.
  18. that constant is known to the compiler by r00t · · Score: 2, Informative

    The compiler depends on the OS to set up certain things, including the memory at address 0.

    If I remember right, *(int)0==0 on this system.

    It's totally legit. The C standard says nothing about how the assembly code behaves, or even that there is any assembly code. (C can be an interpreted language)

  19. Re:A pointer may be a reference. by Abcd1234 · · Score: 2, Insightful

    But a reference is not necessarily a pointer.

    In the context of this article, it sure as hell is. The entire point is that the concept of "NULL" can be dangerous. And pointers and references both support this concept, and are thus dangerous for the exact same reasons.

  20. how it works by r00t · · Score: 2, Insightful

    We do "if (foo && *foo == CONSTANT)" like so...

    The programmer wants to access *foo, unless it is NULL. We will thus do so. Additionally, we know that *NULL will not fault (on the AIX operating system) and that it will give us a zero. Thus, we can access *foo in any case.

    The code becomes:

    tmp=*foo; if(foo && tmp==CONSTANT)

    The C standard only places requirements on an abstract machine. Underneath it all, the code could be getting executed by a bunch of monks who chisel computations into blocks of granite. It doesn't matter if one of the monks takes a bathroom break or whatever. The C standard doesn't care.

  21. Re:Trouble is that even if you remove NULL-refs by Laxitive · · Score: 2, Informative

    We're not talking about not having null references at all. Nullable references are in fact very useful in many situations, as you point out.

    The problem is that in many languages, it is not possible to describe a non-nullable type. I.e. a type that guarantees that the value it annotates is not null.

    This is useful because the vast majority of actual code doesn't really deal with 'null' references, and in fact will break if 'null' references are passed in. Right now, there are two ways to ensure your code is safe:

    1. make assertion-type checks everywhere. This is a pain in the ass to write and maintain compared to providing a non-nullable type. It's also slow to throw in unnecessary null checks everywhere during runtime.

    2. don't check aggressively, but ensure in an ad-hoc way that all not-null preconditions are met. Basically, you just make sure to never call the relevant methods with null values. This has the problem that you have to keep track of EVERY SINGLE PLACE a null may be introduced and eventually find its way into the method. This may be easy in simple applications, but can become very tedious in large applications.

    Providing a non-nullable type constructor saves all of those things. The compiler can ensure that a NULL never makes it into a variable marked not-null. You don't have to care about it. You can split your code up into the sections that are "pure" and sections that are "impure", and keep all your null-sanity-checking in the (what should be a relatively small) 'impure code', which calls into the pure code, with the compiler ensuring the calls are all valid.

    No work, just a simple type annotation. That's the potential.

    -Laxitive

  22. Its about Types by Destrius · · Score: 2, Insightful

    I think the main issue here is that when you're developing a type system, you generally want the types to classify objects into certain categories that tell you things about them. So if I define some kind of a reference type, what I am saying is that an object of that type is a kind of a pointer to something.

    So now, if I allow null references, then my reference type is really saying that "objects of this type are pointers to either something or nothing". That's all well and fine, but it makes the type less precise, in that it conveys less information about the object it is categorizing.

    As it turns out, this lack of information is quite important because one of the most common things you have to check when you're given a possibly-null reference is whether or not it is null. You need to insert "if (ptr == NULL)" all over the place. Thus reference types which allow null references ultimately give me less expressive power.

    Most of the time null references are created because either an error condition must be reported (e.g. malloc fails), or it is unclear at some point in time whether or not an object exists. Error conditions can be better signalled using exception handling. As for cases where you're not sure if the object exists or not, then one possibility is to use an option type like in Standard ML:

    datatype 'a option = SOME of 'a | NONE

    This is a polymorphic type that says that either the object exists or it doesn't, and you can find out what the situation is by using a "case" statement on the datatype constructors:

    case foo of
        SOME(x) ==> ... [do something with x] ...
    | NONE ==> ... [the object doesn't exist] ...

    Thus by combining a reference type without nulls with an option type, you can create "reference option" types, which have all the flexibility of "with-null" reference types.

    But the cool thing is, you only ever need to check the "null-ness" of the object only once; once you do the check, you're handed a reference object which is guaranteed to be non-null. Thus you can easily partition your code into parts that will do the non-null check and those that assume all references handed to it are valid.

    This is why a good type system can make programming so much cleaner and easier :)

  23. Two strings in a bar by this+great+guy · · Score: 2, Funny

    These two strings walk into a bar and sit down.
    The bartender says, So whatll it be?
    The first string says, I think Ill have a beer quag fulk boorg jdk^CjfdLk jk3s d#f67howe%^U r89nvy~~owmc63^Dz x.xvcu
    Please excuse my friend, the second string says, He isnt null-terminated.