2 Funktionen im Detail
Sie sind sicher nichtüberrascht zu hören, dass funktionale Programmierung in F#, wie auch in anderen Sprachen, die ganz oder teilweise der funktionalen Idee verhaftet sind, auf modularen Funktionen basiert. Manche solche Funktionen schreiben Sie selbst, andere sind Bestandteil der F#-Laufzeitumgebung oder sogar des .NET Frameworks.
Jenseits der„einfachen“ Deklaration und Implementierung von Funktionen sind Techniken notwendig, um den Aspekt der Modularisierung zu realisieren. Wenn Funktionen als Bausteine dienen sollen, muss es möglich und sogar einfach sein, sie zusammenzufügen, aus ihnen neue Funktionen zu bauen. Die dazu dienlichen Techniken werden gern unter der Bezeichnung Function Construction zusammengefasst.
Dieses Kapitel deckt beide Bereiche ab. Sie werden sehen, welche detaillierten Fähigkeiten F# zur Deklaration und Implementierung von Funktionen bietet und wie diese mit Techniken der Function Construction zu größeren Elementen zusammengebaut werden können.
2.1 Deklarationen
Im ersten Kapitel haben Sie bereits gesehen, wie Sie in F# Funktionen deklarieren können. Hier ist noch einmal die einfache Funktionadd, die bereits als Beispiel gezeigt wurde:
let add x y = x + y
Listing 2.1: Die einfache Funktion„add“
Sie haben auch gesehen, dass die Funktionsimplementierung umgebrochen undüber mehrere Zeilen gestreckt werden kann, wobei die Einrückung die Struktur der Funktion repräsentiert. Etwa so:
let add x y =
x + y
Listing 2.2:„add“, deklariert mit Umbruch
Wie andere moderne Programmiersprachen bietet F# die Möglichkeit, Funktionen auch anonym, also namenlos, zu erzeugen. C# etwa bietet hierzu zwei unterschiedliche Syntaxvarianten, die anonymen Funktionen und die Lambda-Ausdrücke. Letztere sind in den meisten anderen Sprachen, besonders denen aus der funktionalen Sprachwelt, der„normale“ Mechanismus zur Erzeugung von anonymen Funktionen. F# ist hier keine Ausnahme: mit dem Schlüsselwortfun (kurz für Function, nicht alsÜbersetzung von Spaß zu verstehen) erzeugen Sie einen Lambda-Ausdruck:
let add' = fun x y -> x + y
Listing 2.3:„add’“, als Lambdaausdruck implementiert
Die Syntaxadd', gesprochen add Strich, die hier verwendet wird, um eine Variante der Funktionadd zu erzeugen, haben Sie schon zuvor gesehen. Mit dem Schlüsselwortfun wird die Erzeugung eines Lambdaausdrucks eingeleitet. Eine Parameterliste für den Ausdruck folgt dem Schlüsselwort, und auf der rechten Seite des Operators->, gesprochen goes to, findet sich die Implementierung, derBody, des Ausdrucks.
Hinweis: Sicherlich haben Sie bemerkt, dass die Funktion, die hier in Form des Lambdaausdrucks deklariert wird, in dem Wertadd‘ abgelegt und somit gewissermaßen mit einem Namen versehen wird. Man könnte also darüber streiten, ob in diesem Fall von einer anonymen Funktion die Rede sein darf ? schließlich steht die Funktion unter dem Namenadd‘ zum Aufruf zur Verfügung. Allerdings nennt man oft auch in dieser Situation die Funktion anonym, da kein Name dafür innerhalb der syntaktischen Sprachelemente der Deklaration festgelegt wurde. Die Zuweisung an den Wertadd‘ geschieht hier nur, damit ein vollständiges, gültiges Statement im Sinne von F# daraus wird. Praktisch werden Lambdaausdrücke oft auch ohne Zuweisung erzeugt, wie Sie weiter unten sehen werden.
Offensichtlich ist der syntaktische Unterschied zwischen einer„normalen“ Funktionsdeklaration und der eines Lambdaausdrucks in F# nicht groß. Tatsächlich sind auch die Ergebnisse beider Techniken kaum zu unterschei