Mittwoch, 24. Februar 2010

Cassidy Marie shipped


Beta


Release Candidate


Cassidy Marie shipped

Die glücklichen und schlaflosen Eltern
Marika und Benjamin Gopp

Freitag, 12. Februar 2010

F#: Units of Measure

Mit dem diese Woche erschienenen Release Candidate von VS2010, hat sich auch was bei F# getan. Wie Don Syme in seinem Blog schreibt, ist der F# Compiler auf Version 2.0 heraufgesetzt worden. Das bedeutet F# ist ausgereift um es produktiv einzusetzen (Obwohl viele es bereits mit früheren Version eingesetzt haben). Zeit sich also endlich ernsthaft mit F# und seinen genialen Features zu beschäftigen!

Ein Feature über das ich heute schreiben möchte sind Units of Measure oder zu Deutsch Maßeinheiten. Bei diesem Feature geht es um das Problem bei der Verwendung von unterschiedlichen Maßeinheiten im Code. Wie der Unfall des NASA Mars Climate Orbiter 1999 zeigt, kommt es auch heute noch zu Fehlern auf Grund der Verwendung von unterschiedlichen Maßeinheiten. Mittlerweile wird auch in der USA in Wissenschaft und Technik das Metrische System verwendet. Ein Zulieferer hatte jedoch in Pfund und Fuß gerechnet, was letztlich dazu führte, dass die Mars Sonde verglühte.

Dieses Feature hat also einen relativ ernsten Hintergrund. Damit solche Fehler sich nicht in Produktivcode einschleichen verwendet F# eine erweiterte statische Codeanalyse. Maßeinheiten werden dabei mit Attributen annotiert und bei Ihrer Verwendung vom Compiler auf Korrektheit geprüft. Dabei wird jedoch nicht nur geprüft ob der entsprechende Typ korrekt ist, sondern auch ob die Funktion in dem man diesen Typ verwendet, mathematisch korrekt ist. Durch die intelligente Typinferenz in F# können sogar abgeleitete Maßeinheiten ermittelt werden.

Nun wie funktioniert das? In C# könnte man eine gewisse Art der Typsicherheit hinbekommen, indem man für Maßeinheit einen eigenen Typen erstellt. Somit würde der Compiler beim Verwenden des Types dessen Typsicherheit garantieren. Was jedoch nicht möglich ist, dass auch auf die Einhaltung der mathematischen Regeln geprüft wird. Dies könnte man vielleicht zur Laufzeit realisieren in dem man für Maßeinheiten entsprechende Rules definiert. Letzlich würde aber eine Prüfung zur Laufzeit nicht den Absturz einer 100.000 km entfernten Sonde verhindern können. Die Prüfung muss also viel früher, also zur Compilezeit erfolgen.

Noch ein Hinweis: Units of Measure können nur mit Gleitkommazahlen verwendet werden! Dies liegt daran, dass man nicht nur dumme Maßeinheiten verwenden kann, sondern auch physikalische Größen wie Beschleunigung etc. Dies würde nicht mit Integers oder anderen Typen funktionieren. (Tatsächlich kann man aber Units of Measure mit Komplexen Zahlen oder Vektoren verwenden)

Ein Beispiel:

Man definiert zunächst die Maßeinheiten die man verwenden will als Typen. Diese Typen attributiert man mit[<Measure>]. (So sehen Attribute in F# aus. Eine Misschung aus C# und VB Attribute)

[<Measure>] type kg

[<Measure>] type s

[<Measure>] type m


 

Nun können wir Formeln schreiben. Wir wollen wissen, mit welcher Geschwindigkeit wir auf der Erde aufkommen, wenn wir aus einer bestimmten Höhe springen. Zunächst definieren wir die Höhe als Gleitkommazahl und auf welche Maßeinheit sich diese bezieht.

let höhe = 2.0<m>


 

Nun definieren wir die Gravitation. Diese ist eine Beschleunigungskraft: also Gravitationskonstate mal Meter pro Sekunde im Quadrat

let gravitation = 9.81<m/s^2>


 

Wir können nun ausrechnen wie groß die Geschwindigkeit ist, mit der man auf der Erde auftrifft.

let geschwindigkeit = sqrt (2.0 * gravitation * höhe)


 

F# Interactive sagt uns, dass die Geschwindigkeit in Metern pro Sekunde berechnet wird.

val geschwindigkeit : float<m/s> = 14.00714104


 

Demnach schlgt man mit 14 Metern pro Sekunde bei einem Sprung aus 2 Metern Höhe auf der Erde auf. Gut zu wissen!

Im F# Power Pack sind weitere Standardmaßeinheinten definiert, so dass man nicht jedes mal alle Naturgesetze herunterbeten muss. Auf der anderen Seite stellt sich die Frage, wann man dieses Feature wirklich brauch. Hier zeigt sich wieder das F# eine super Ergänzung zu bestehenden C# Code ist, jedoch keinesfalls den Anspruch erhebt C# in seiner Gesamtheit abzulösen. Bisher sind noch keine Überlegungen gemacht worden, Units of Measure auch nach C# zu portieren oder sogar in die CLR. Man wird mit der Zeit sehen müssen, ob dieses und andere Feature auch nach C# portiert werden, oder ob es dann keinen Grund mehr geben würde F# zu verwenden. Das wäre außerst schade!

Viel Spaß beim Ausprobieren mit F#

Benjamin