Weniger Softwarefehler durch Klarheit – null ist Vergangenheit in F#

Die null ist leider die Quelle vieler Laufzeitfehler.

Die null-en befüllen die Code-Basis und machen sie weniger gut lesbar und wartbar.

Ein typisches Codefragment in C#:

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
// C#
if (x != null) 
{
    return UseALanguageWithoutNull( x );
}
else
{
    return null;
}

Wie es ohne null aussieht

1: 
2: 
// F#
UseALanguageWithoutNull x

Null vs. Option.None?

Wir wissen dass in F# alle Werte initialisiert sind und niemals mit null. Mit der Ausnahme, dass von einer .Net Komponente die nicht in F# geschrieben ist, ein Rückgabewert oder ein Out Parameter als null daherkommt.

Was ist nun, wenn man den Zustand von nicht vorhanden in F# abbilden will?

Dazu dient der Option Type. Dieser kann None oder Some 'T sein. Wobei ‘T ein beliebiger Type sein kann, also z.B. ein int, ein String oder ein Array.

Jetzt könnte man ja sagen es ist genau das selbe?

1: 
2: 
null    vs.     None
obj     vs.     Some 'T

Die Unterschiede sind:

  • Es ist nicht umständlicher einen Wert in einen Option type zu packen. Auch wenn es im ersten Augenblick so aussehen mag. Der Nutzen überwiegt!
  • Der Type ‘T von Some ist bekannt, und auch von None, also welcher Type der keinen Wert hat. Dies ermöglicht die exakte statische Type Überprüfung durch den Compiler, was zu sicherem Code führt. Es wird also nicht zur Laufzeit implizit ge-castet.
  • Elimination der Mehrfachbedeutung von null. Wie oben schon erwähnt: Bedeutet null nun, nicht initialisiert oder nicht zugewiesen oder nicht vorhanden oder kein Ergebnis oder Fehler ? Da jede Variable auch null sein kann, muss der Programmierer immer mitdenken, was für Zustände die Variable haben könnte und was diese im Kontext nun bedeutet. Vergisst er es oder missinterpretiert er es, hilft ihm der Compiler nicht, erst zur Laufzeit unter bestimmten Bedingungen (Zustände, Daten) kann es dann zu null-Exceptions kommen. Im Gegensatz dazu, mit dem Option Type ist es absolut klar und der Compiler weiss es auch und hilft!
union case Option.None: Option<'T>
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj
union case Option.Some: Value: 'T -> Option<'T>

2014 das Jahr der Software Fehler und Sicherheitslecks?

Das Jahr 2014 beginnt mit der Aufdeckung der schlimmsten GOTO Fehlern in Betriebssystemen.

25. Februar : goto fail : Apple iOS, OS X :  SSL-Sicherheitsleck

Diese Lücke besteht angeblich seit 2012.
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail;
Quellen: apple-mac-update-go-fail-ssl-bug , new-ios-flaw , gotofail.com

4. März : goto cleanup : Linux : “GnuTLS bug”

Diese Lücke besteht angeblich seit 2005 ! corrected return codes - Gitorious_2014-03-05_15-18-32 Expertenmeinungen dazu:
It looks pretty terrible. — Matt Green, Johns Hopkins University professor cryptography
has a lot of side effects. — Kenneth White, principal security engineer
Quellen: Sicherheitsluecke-GnuTLS , critical-crypto-bug-linux

Wie lange werden wir noch mit Software Fehlern leben müssen?

Es sind massive Sicherheitsrisiken! Software steckt in vielen Geräten. Anwender und Hersteller sind betroffen. Die von genervten Anwendern, die eine andere Software oder Geräte vorziehen, bis zu Daten-, Geld- und Imageverlust reichen können. Man denke auch an Bereiche der Personensicherheit und Medizintechnik, wo es auch um Menschenleben gehen kann! Wie lange werden wir auch noch mit einer anderen Fehlerquelle der NULL Ausnahmen (Null Pointer Exception, Null Reference Exception) leben müssen?
“I call it my billion-dollar mistake. It was the invention of the null reference in 1965.” — Tony Hoare
Diese Problematik betrifft nahezu alle heute noch verwendeten älteren Programmiersprachen wie z.B. C, C++, Java, VB.Net, C# ! Der Grund ist der Stammbaum, also die Abstammung der Programmiersprachen und deren weitergegebenen Konzepte. Quellen: Null PointerZeiger

Was können wir dagegen tun?

Wie kann man die Software Qualität in seinen Wurzeln verbessern? Indem man für die Softwareentwicklung eine Programmiersprache anwendet, die weder GOTO noch NULL benötigt, die kapitalen Fehler nicht zulässt und dabei den Entwickler aktiv und wachsam unterstützt, so z.B. die immer populärer werdende Programmiersprache F#, die hier auf Functional Software .NET das Thema ist.   Nebenbei bemerkt, wer eine TLS Implementation in F# betrachten will, kann dies hier tun “miTLS A verified reference TLS implementation” und es ist auf den Tag genau ein Jahr her, hier gibt es den F# Quellcode: “5 March 2013 Our paper on TLS security has been accepted at the IEEE Symposium on Security & Privacy. A draft technical report of this work is available from the download page.”. Siehe auch F7: Refinement Types for F#