Funktionale Entwicklung...

Für alle die sich nicht nur als Anwender sehen ;-)

Moderator: Moderation

Funktionale Entwicklung...

Beitragvon Darklord Extropy » 21.05.2010, 17:24

...hab gerade F# in Arbeit:

http://cs.hubfs.net/forums/default.aspx

Bislang gabs ja nur funktionale Sprachen, die kaum Infrastruktur hatten (OCaml, Haskell - alles halt eher für verspielte Informatikstudenten) - da aber nun auch ein ernsthafter Softwareanbieter (Microsoft) für eine wirklich brauchbare und entwicklerfreundliche Plattform (.NET) eine funktionale Sprache im Angebot hat, wird es wirklich interessant.

Ich versuche ja seit Jahren schon, einen eher funktional orientierten Stil auch in C# zu pflegen (das ist meine Haus- und Hofsprache) und hoffe, daß man bei Microsoft den Weg, den man mit der Einführung des Lambda - Operators und (damit schon verbunden) LINQ eingeschlagen hat, auch weitergehen wird.

Mein eigenes Framework (das eh schon mehr in Richtung DSL geht, da ich sehr viele Extension - Methods habe - bei Microsoft hat man ja leider vergessen, Multiple Inheritance in die CLI aufzunehmen) bekommt gerade eine Erweiterung um in F# implementierte, funktionale Erweiterungen.

Sehr interessante Sache, kann ich nur empfehlen!

Vor allem wird die eigene Codequalität besser, da man in funktionalen Sprache diverse "Verbrechen", die einem imperative / objektorientierte Sprache leider durchgehen lassen (z.B. Seiteneffekte in Funktionen!), nicht begehen kann.

Egal.

Ich hab ein schönes Beispiel mitgebracht (eh einen Klassiker), um schnell zu demonstrieren, was man unter funktionaler Entwicklung versteht:

Zuerst mal die einfache Aufgabe, die Zahlen von 1 - 10 zu generieren und zu quadrieren. Ich teile das in F# in sehr kleine Funktionen auf, natürlich könnte man das auch kürzer schreiben, aber der Reiz liegt darin, die Dinger auch einzeln zu verstehen.

In C# schreibt man das ja so, das wäre der gute Ansatz, der ja durchaus funktioniert:

Code: Alles auswählen
static void Main(string[] args)
{
    List<int> numbers = new List<int>();
    List<int> squares = new List<int>();
    for (int i = 1; i <= 10; i++)
    {
        numbers.Add(i);
        squares.Add(i * i);
    }
}


Dagegen spricht ja nix, das ist ja ein recht sauberer Weg (ich zeig nacher aber einen anderen, der noch sauberer ist und meinen eigentlichen Stil reflektiert).

Die Lösung in wohlgeformten F# (ich hab schon Grauslichkeiten im Internet gesehen, wo Leute halt einfach die paar leider vorhandenen imperativen Konstrukte so lange gewürgt haben, bis am Ende erst wieder eine Art "VB 6.0 - Kurs für Anfänger" herauskam, davon nehme ich natürlich Abstand) sieht so aus:

Code: Alles auswählen
let numbers = [1..10]

let sqr x = x * x

let sqrNumbers numbers =
    List.map sqr numbers


Test (im interaktiven Fenster):

Code: Alles auswählen
> numbers;;
val it : seq<int> = seq [1; 2; 3; 4; ...]
> sqrNumbers numbers;;
val it : seq<int> = seq [1; 4; 9; 16; ...]


Sehr schön - ABER! :-D

Selbstverständlich kann man ja auch was für C# mitnehmen. Zum Beispiel finde ich gut, daß Sequenzen (in C#: IEnumerable) erst aufgelöst werden, wenn die Werte abgerufen werden (die Dinger sind "lazy"). Das bedeutet z.B., daß kein Speicher reserviert wird und daß man auch "unendliche" Sequenzen definieren kann (z.B. wäre folgendes möglich damit - so als kleines Intermezzo, bevor ich die Highend - C# - Lösung für die Quadrierungsaufgabe präsentiere):

Code: Alles auswählen
let rec everlasting x : int seq =
    seq
        {
            yield x
            yield! everlasting (x + 1)
        }


...würde eine unendliche Sequenz von Integer - Zahlen zurückgeben, ab dem definierbaren Startwert. Funktioniert, durch die "on demand" - Berechnung, übrigens einwandfrei.

Kann man im interaktiven Fenster sofort testen:

Code: Alles auswählen
> everlasting 1;;
val it : seq<int> = seq [1; 2; 3; 4; ...]


Anmerkung hier:

Da ich kaum etwas so sehr hasse wie Java (nur Javascript finde ich mit diesem extrem unwartbaren Duck - Typing - Wahnsinn noch schlimmer), vermeide ich auch diese ekelhaft Unart mit der dort üblichen Klammersetzung, auch wenn das in F# eigentlich auch im Java - Unstil gemacht werden würde. So hat halt jeder seine Macken. :-D

So, jetzt aber zurück zum Eingangsbeispiel. Funktionale Programmierung ist was Feines und man sollte ja nicht stehen bleiben auf dem imperativen VB 6.0 - Niveau. Und somit sieht die wirklich schöne Lösung in C# dann so aus:

Code: Alles auswählen
private static IEnumerable<int> CreateIntegerRange(int from, int to, int step = 1)
{
    for (int i = from; i <= to; i += step)
    {
        yield return i;
    }
}

static void Main(string[] args)
{
    IEnumerable<int> squares =
        CreateIntegerRange(1, 10).Select(i => i * i);
}


Voila, alles wird gut! :-)
Born against Christ.
Benutzeravatar
Darklord Extropy
Involviert
 
Beiträge: 360
Registriert: 28.04.2008, 20:53

Zurück zu Software-Entwicklung, Programming & Web

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron