Esistono molte risposte eccellenti che coprono gli sfortunati sintomi di   null   , quindi mi piacerebbe presentare un argomento alternativo:  Null è un difetto nel sistema dei tipi.  
 Lo scopo di un sistema di tipi è di garantire che i diversi componenti di un programma "si adattino" correttamente; un programma ben tipizzato non può "uscire dai binari" in un comportamento indefinito. 
 Considera un ipotetico dialetto di Java, o qualunque sia il tuo linguaggio tipizzato staticamente preferito, in cui puoi assegnare la stringa   "Hello, world!"    a qualsiasi variabile di qualsiasi tipo: 
Foo foo1 = new Foo();  // Legal
Foo foo2 = "Hello, world!"; // Also legal
Foo foo3 = "Bonjour!"; // Not legal - only "Hello, world!" is allowed
 E puoi controllare le variabili in questo modo: 
if (foo1 != "Hello, world!") {
    bar(foo1);
} else {
    baz();
}
 Non c'è nulla di impossibile in questo: qualcuno potrebbe progettare un linguaggio del genere se lo volesse. Il valore speciale non deve essere   "Hello, world!"    - potrebbe essere stato il numero 42, la tupla   (1, 4, 9)    o, diciamo,   null   . Ma perché lo faresti? Una variabile di tipo   Foo    dovrebbe contenere solo   Foo    s - questo è l'intero punto del sistema di tipi!    null    non è un   Foo    non più di   "Hello, world!"   . Peggio ancora,   null    non è un valore di  qualsiasi tipo  e non c'è niente che tu possa fare con questo! 
 Il programmatore non può mai essere sicuro che una variabile detenga effettivamente una   Foo   , e nemmeno il programma; per evitare comportamenti indefiniti, deve controllare le variabili per   "Hello, world!"    prima di utilizzarle come   Foo    s. Tieni presente che eseguire il controllo stringa nello snippet precedente non fa propagare il fatto che foo1 è in realtà un   Foo    -   bar    probabilmente avrà anche il proprio controllo, solo per sicurezza. 
 Confrontalo con il tipo   Maybe    /   Option    con la corrispondenza del modello: 
case maybeFoo of
 |  Just foo => bar(foo)
 |  Nothing => baz()
 All'interno della clausola   Just foo   , sia tu che il programma siete sicuri che la nostra variabile   Maybe Foo    contenga veramente un valore   Foo    - tale informazione è propagata lungo la catena di chiamate e   bar    non ha bisogno fare qualsiasi controllo Poiché   Maybe Foo    è un tipo distinto da   Foo   , sei costretto a gestire la possibilità che possa contenere   Nothing   , quindi non puoi mai farlo alla cieca di un   NullPointerException   . Puoi ragionare sul tuo programma molto più facilmente e il compilatore può omettere i controlli nulli sapendo che tutte le variabili di tipo   Foo    contengono effettivamente   Foo    s. Tutti vincono.