Funktionale Programmierung mit Haskell



  • Lisp wurde als eine Grundlagentechnologie (neben anderen z.B. C) bei
    amazon massiv eingesetzt.

    Nun beinhaltet Lisp funktionale Elemente, so wie auch Java, C# und VB.net.
    Das allein reicht mir aber noch nicht aus um von funktionale Programmierung zu
    sprechen.

    da sie [Microsoft] die Moeglichkeiten der Funktionalen Programmierung im
    Bereich der parallelen Datenverarbeitung nicht erkannten.

    Das ist falsch. Microsoft forscht schon lange im Bereich funProg. Außerdem
    beschäftigt Microsoft viele der führenden Köpfe die hinter der funProg. stehen.
    Sicherlich hat Microsoft irgendwo nicht aufgepasst, mit funProg. hat dies aber
    nichts zu tun.

    Um auf u_ser-l's Frage zu kommen. Dadurch das Haskell streng und statisch getypt
    ist, sowie ein sehr mächtiges Typensystem besitzt ist es unmöglich einen
    Typfehler zur Laufzeit zu bekommen. So gibt es z.B. keine NullpointerExceptions.
    Das klingt vielleicht noch nicht so spektakulär, allerdings lassen sich die
    meisten Fehler auf Typfehler zurückführen. (Und so philosophisch würde ich sogar
    sagen, dass jeder Fehler irgendwo ein Typfehler ist, aber das ist etwas anderes :))

    Ein weiterer Vorteil ist die Beweisbarkeit von Programmen. Es ist in einem
    funProg. möglich zu beweisen, dass es richtig ist. Dies führt z.B. dazu, dass man
    das Testen seiner Software größtenteils automatisieren kann (siehe QuickCheck).

    Und zuletzt gibt es in einem funProg. keinen Kontrollfluss, was bedeutet, die
    Reihenfolge in der dein Programm berechnet wird, legt der Compiler selber fest.
    Diese Tatsache ermöglicht es, dein Programm automatisch auf mehreren Kernen
    gleichzeitig berechnen zu lassen, was in imperativen Sprachen schlichtweg
    unmöglich ist.



  • frosch03 schrieb:

    Lisp wurde als eine Grundlagentechnologie (neben anderen z.B. C) bei
    amazon massiv eingesetzt.

    Nun beinhaltet Lisp funktionale Elemente, so wie auch Java, C# und VB.net.
    Das allein reicht mir aber noch nicht aus um von funktionale Programmierung zu
    sprechen.

    Diese Aussage zeigt mir, dass du noch nie richtig mit Lisp programmiert hast.

    edit: Vielleicht hab ich deine Aussage auch falsch aufgefasst. Es klang für mich, als würdest du Lisp mit Java, C# und VB.net in einen Topf werfen, was grundlegende Sprach-Features angeht. Und das stimmt einfach nicht: Lisp ist die "programmierbare Programmiersprache" schlechthin, da können die anderen genannten Sprachen nicht mithalten.

    Lisp ist sicher nicht im reinen Sinne funktional, es gibt immerhin überall Seiteneffekte. Der Punkt ist aber, dass Funktionen in Lisp auch nur Werte sind ("first-class values"). Das gibt es z.B. in Java so nicht. Dadurch (und durch Lisp-Makros, die außer von Namen her nichts mit C-Makros zu tun haben) unterscheidet sich Lisp so deutlich von Java, C# und VB.net, dass es IMHO schwer ist, diese in einen Topf zu werfen, nur weil alle diese Sprachen Seiteneffekte an beliebiger Stelle unterstützen.



  • u_ser-l schrieb:

    Was kann man denn mit funktionaler Prog.rung machen, das man mit blockstrukturierter oder OO-Programmierung nicht auch machen kann? Das sind nur verschiedene Notationen für dieselbe Menge berechenbarer Funktionen, nämlich Turing-berechenbare Funktionen.

    Es geht nicht um das "Was", sondern um das "Wie". Und gerade was Parallelisierung und Stabilität angeht, da hat die funktionale Programmierung so einiges zu bieten, was bei den "klassischen" Programmiersprachen nur schwer zu bekommen ist.



  • Diese Aussage zeigt mir, dass du noch nie richtig mit Lisp programmiert hast.

    Was heißt schon Lisp programmiert. Lisp stellt ja mehr eine Sprachfamilie dar.
    Ich hab mich mehrere Jahre mit dylan [1] beschäftigt. Allerdings kann ich dir
    auch kurz ziegen, was ich meine.

    (setf *x* 42.1)
    

    Hier definier ich eine Variable und weise dieser einen Wert zu. Das Konzept einer
    Variable existiert in der funktionalen Programmierung allerdings nicht. Daher
    meine Aussage, dass Lisp funktionale Elemente enthält.

    [1] http://de.wikipedia.org/wiki/Dylan_(Programmiersprache)

    --- edit ---
    Ok, auf deinen Edit hin kann ich dir nur voll zustimmen 🙂



  • frosch03 schrieb:

    Allerdings kann ich dir
    auch kurz ziegen, was ich meine.

    (setf *x* 42.1)
    

    Hier definier ich eine Variable und weise dieser einen Wert zu. Das Konzept einer
    Variable existiert in der funktionalen Programmierung allerdings nicht. Daher
    eine Aussage, dass Lisp funktionale Elemente enthält.

    Ich habe meinem Beitrag oben noch zwei Absätze hinzugefügt, wahrscheinlich gerade als du deine Antwort geschrieben hast.

    Ich möchte nicht sagen, dass Lisp im reinen Sinne "funktional" ist; wobei die Definition, wo "funktional" beginnt und wo es aufhört, im Grunde etwas schwammig ist. Man könnte auch sagen, dass eine Sprache, die Funktionen als first-class objects hat, "funktional" ist. Und genau das ist eine Eigenschaft, die Lisp von Sprachen wie Java, C# und VB.net unterscheidet.

    edit: Ich hätte meinen Beitrag nicht mehr so spät editieren sollen. Sorry für die Verwirrung. 🙂



  • frosch03 schrieb:

    (setf *x* 42.1)
    

    Hier definier ich eine Variable und weise dieser einen Wert zu. Das Konzept einer
    Variable existiert in der funktionalen Programmierung allerdings nicht.

    In einer bestimmten Auffassung des Begriffes. Allgemeingültig ist das nicht, oder willst du SML den Status einer funktionalen Programmiersprache absprechen? Wenn "funktional" automatisch "streng ohne Zuweisung" heißen würde, bräuchte man den Begriff "rein-funktional" nicht.



  • frosch03 schrieb:

    Dadurch das Haskell streng und statisch getypt
    ist, sowie ein sehr mächtiges Typensystem besitzt ist es unmöglich einen
    Typfehler zur Laufzeit zu bekommen.

    Die von Dir aufgezählten Argumente zu Gunsten von FP mögen alle richtig sein, nur hat FP den großen Nachteil, daß sie der menschlichen Intuition von "Algorithmus" zuwiderläuft, denn das natürliche algorithmische Denken des Menschen ist prozedural. Niemand schreibt von Natur aus seinen Einkaufszettel als funktionales Programm. Versteht man "Programmieren" als abstrakte, mathematische Tätigkeit, dann ist FP sicherlich ein überlegenes Konzept.

    Dennoch kann man alles, was man mit FP programmieren kann, prinzipiell auch prozedural oder mit OOP programmieren, dafür sorgt die Church-Turing-Äquivalenz.



  • u_ser-l schrieb:

    Niemand schreibt von Natur aus seinen Einkaufszettel als funktionales Programm.

    Wie würde denn das aussehen?

    Imperativ wäre das ja so:

    1. A
    2. B
    3. C
    


  • u_ser-l schrieb:

    Die von Dir aufgezählten Argumente zu Gunsten von FP mögen alle richtig sein, nur hat FP den großen Nachteil, daß sie der menschlichen Intuition von "Algorithmus" zuwiderläuft, denn das natürliche algorithmische Denken des Menschen ist prozedural.

    Meinst du nicht, dass die vielen FP-Enthusiasten es als natürlicher empfinden, funktional zu programmieren? Oder sind das alles Masochisten? Oder keine Menschen?

    Niemand schreibt von Natur aus seinen Einkaufszettel als funktionales Programm.

    Ein Einkaufszettel ist aber auch nicht imperativ, da er keine feste Reihenfolge vorschreibt. Man ordnet das dynamisch um, idealerweise so, dass die Laufwege möglichst kurz sind. :p

    Dennoch kann man alles, was man mit FP programmieren kann, prinzipiell auch prozedural oder mit OOP programmieren, dafür sorgt die Church-Turing-Äquivalenz.

    Ist das ein ernstgemeintes Argument? 😕 "Prinzipiell" kann man auch direkt in Maschinencode programmieren.



  • Taktiker schrieb:

    Wie würde denn das aussehen?

    eben. In Haskell müßte man Monaden bemühen, um einen Einkaufszettel "1. .. 2. .. 3. .." zu implementieren, also eine Nachbildung sequentiellen Verhaltens durch kategorientheoretische Tricks - nicht gerade ein Formalismus, der natürlichem algorithmischem Denken angepaßt wäre. Probleme aus der realen Welt lassen sich oft am einfachsten durch Zustände, Übergänge und sequentielle Abläufe modellieren, also genau das, was mit FP kompliziert ist und mit prozeduraler oder OO-Prog'rung einfach.

    Bei zukünftig weiter zunehmender Parallelisierung der Hardware auf allen Ebenen könnte die große Zeit von Sprachen wie Haskell in der Tat bevorstehen.



  • u_ser-l schrieb:

    Taktiker schrieb:

    Wie würde denn das aussehen?

    eben. In Haskell müßte man Monaden bemühen, um einen Einkaufszettel "1. .. 2. .. 3. .." zu implementieren, also eine Nachbildung sequentiellen Verhaltens durch kategorientheoretische Tricks - nicht gerade ein Formalismus, der natürlichem algorithmischem Denken angepaßt wäre.

    Du hast interessante Vorstellungen über Haskell. Eine Liste ist in Haskell einfach das: Eine Liste.
    In deinem Beispiel: [1, 2, 3].

    Klar kann man das kategorientheoretisch interpretieren. Aber muss man das machen, um die Liste [1, 2, 3] zu verstehen? 😕



  • u_ser-l schrieb:

    Die von Dir aufgezählten Argumente zu Gunsten von FP mögen alle richtig sein, nur hat FP den großen Nachteil, daß sie der menschlichen Intuition von "Algorithmus" zuwiderläuft, denn das natürliche algorithmische Denken des Menschen ist prozedural.

    Das ist absoluter Blödsinn. Da ich im Moment in der Lehre tätig bin und Menschen sehe die zum ersten mal programmieren, sehe ich auch, wie schwierig die prozedurale Denkweise zu erlernen ist. Bloß weil du dich an sie gewöhnt hast, ist sie noch lange nicht natürlich.

    u_ser-l schrieb:

    Niemand schreibt von Natur aus seinen Einkaufszettel als funktionales Programm.

    Niemand schreibt seinen Einkaufs-Zettel als prozedurales Programm. Denn die Sachen auf dem Zettel sind ja kein Programmablauf. Der Zettel stellt ja lediglich die Menge der Teile da, die du vor hast zu erwerben. Du wirst selten die Dinge in der Reihenfolge in den Einkaufskorb legen, wie sie auf dem Zettel stehen. Von daher: Blödes Beispiel.

    Der Mensch denkt rekursiv und nicht prozedural. Beispiel: Das Bilden der Summe von Zahlen in einer Liste. So würde ein Mensch vorgehen:

    Die Summe von zwei Zahlen kann ich. Die Summe von drei Zahlen ist die Summe von zwei Zahlen addiert mit einer weiteren Zahl... (spätestens beim nächsten mal merkt man) Die Summe von n Zahlen ist die Summe von (n-1) Zahlen plus eine weitere Zahl.

    Und genau diese rekursive Denkweise setzen die Funktionalen Programmiersprachen um.

    u_ser-l schrieb:

    Dennoch kann man alles, was man mit FP programmieren kann, prinzipiell auch prozedural oder mit OOP programmieren, dafür sorgt die Church-Turing-Äquivalenz.

    Ja richtig. Die frage ist nur, wie viel schwerer und umständlicher es ist.



  • ProgChild schrieb:

    Da ich im Moment in der Lehre tätig bin und Menschen sehe die zum ersten mal programmieren, sehe ich auch, wie schwierig die prozedurale Denkweise zu erlernen ist. Bloß weil du dich an sie gewöhnt hast, ist sie noch lange nicht natürlich.

    Mein Lieblingsbeispiel ist ja immer noch das folgende. Jemand wundert sich, dass dieses Programm nicht funktioniert:

    int x;
    int y = x*x;
    cout << "Bitte x eingeben:";
    cin >> x;
    cout << "Das Quadrat von x ist: " << y << endl;
    

    Das Beispiel ist fiktiv, aber die Situation an sich hab ich schon zu oft erlebt, um es für einen Zufall zu halten. Denkt der Mensch am Ende deklarativ? (Oder hatten diejenigen Vorerfahrung mit Tabellenkalkulationen?;) )



  • Bashar schrieb:

    Das Beispiel ist fiktiv, aber die Situation an sich hab ich schon zu oft erlebt, um es für einen Zufall zu halten. Denkt der Mensch am Ende deklarativ? (Oder hatten diejenigen Vorerfahrung mit Tabellenkalkulationen?;) )

    Keine Ahnung. Aber die Situation, wie du sie beschreibst, hatte ich auch schon so ähnlich. Da sieht man wirklich, welche Dinge man alle als selbstverständlich annimmt, die es aber nicht sind.



  • ProgChild schrieb:

    u_ser-l schrieb:

    Dennoch kann man alles, was man mit FP programmieren kann, prinzipiell auch prozedural oder mit OOP programmieren, dafür sorgt die Church-Turing-Äquivalenz.

    Ja richtig. Die frage ist nur, wie viel schwerer und umständlicher es ist.

    Wenn du uns jetzt noch verrätst, warum es hier kein Unterforum zu einer funktionalen Sprache gibt..



  • ProgChild schrieb:

    Da ich im Moment in der Lehre tätig bin und Menschen sehe die zum ersten mal programmieren, sehe ich auch, wie schwierig die prozedurale Denkweise zu erlernen ist. Bloß weil du dich an sie gewöhnt hast, ist sie noch lange nicht natürlich.

    So ein Käse. Die prozedurale Denkweise muß nicht erlernt werden, sie ist dem Menschen von Natur aus mitgegeben, weil evolutionär entstanden.

    Der Urmensch mußte auf der Jagd etliche "wenn ... dann"-Entscheidungen treffen und prozedural Jagdstrategien planen, um zu überleben. Das hat die natürliche Denkweise des Menschen maßgeblich geprägt.

    Das Gehirn ist geschaffen, um zu überleben, und nicht, um elegante Formalismen wie FP zu denken. Und zum Überleben muß es seit jeher prozedural denken. Niemand erbeutet ein Mammut mit funktionalen Überlegungen und Monadentheorie.

    ProgChild schrieb:

    Niemand schreibt seinen Einkaufs-Zettel als prozedurales Programm.

    So ein Käse. Jeder macht das. "1. Supermarkt Broccoli. 2. Bücherei 3. Blabla ..." Ich denke, das Prinzip ist klar (!)

    ProgChild schrieb:

    Der Mensch denkt rekursiv und nicht prozedural.

    wenn FP der natürlichen Denkweise entspräche, hätte sie sich längst auf breiter Basis durchgesetzt, wahrscheinlich wäre FP vor Fortran und Cobol erfunden worden, und die Turingmaschine wäre für uns dann ebenso exotisch wie für die prozedural denkende Mehrheit der Lambda-Kalkül 🙂



  • Bashar schrieb:

    int x;
    int y = x*x;
    cout << "Bitte x eingeben:";
    cin >> x;
    cout << "Das Quadrat von x ist: " << y << endl;
    

    Das Beispiel ist fiktiv, aber die Situation an sich hab ich schon zu oft erlebt, um es für einen Zufall zu halten. Denkt der Mensch am Ende deklarativ?

    der mensch denkt, du hast mit der zeile int y = x*x; eine funktion definiert, in der er nur x einsetzen muss. hat er im matheunterricht so gelernt. er rechnet ja nicht damit, dass im computer immer alles von oben nach unten ausgeführt wird und die reihenfolge eine entscheidende rolle spielt.



  • u_ser-l schrieb:

    wahrscheinlich wäre FP vor Fortran und Cobol erfunden worden

    Der Lambda-Kalkül ist meines Wissens nach deutlich älter als Fortran und Cobol.



  • Zoom schrieb:

    Bashar schrieb:

    int x;
    int y = x*x;
    cout << "Bitte x eingeben:";
    cin >> x;
    cout << "Das Quadrat von x ist: " << y << endl;
    

    Das Beispiel ist fiktiv, aber die Situation an sich hab ich schon zu oft erlebt, um es für einen Zufall zu halten. Denkt der Mensch am Ende deklarativ?

    der mensch denkt, du hast mit der zeile int y = x*x; eine funktion definiert, in der er nur x einsetzen muss. hat er im matheunterricht so gelernt. er rechnet ja nicht damit, dass im computer immer alles von oben nach unten ausgeführt wird und die reihenfolge eine entscheidende rolle spielt.

    Und genau das ist das schöne an Haskell: Man kann etwas hinschreiben und es funktioniert genau so, wie man es aus dem Mathe-Unterricht erwartet. 🙂



  • Christoph schrieb:

    Und genau das ist das schöne an Haskell: Man kann etwas hinschreiben und es funktioniert genau so, wie man es aus dem Mathe-Unterricht erwartet.

    kommt drauf an, was man will. entweder computer verstehen, oder computer benutzen.


Anmelden zum Antworten