Funktionale Programmierung mit Haskell



  • Also ich kenne mich nicht mit Haskell aus, bin eher bei Scheme. Dort gibt es Zustaende. Wenn sie aber lokal sind, dann kann man es Closure nennen. Die sind echt toll, da sie fuer (gewoehnlich) keine Seiteneffekte haben. Gewiss hat Haskell sowas aehnliches, da Zustand auch immer in Parametern kodiert werden kann.

    Wie sortiert ein Kind Spielkarten?

    Wenn ein Computer Suchmaschinenanfragen oder -treffer so verarbeitet, wie ein Kind Spielkarten sortiert, dann wuerde google echt lange fuer eine Antwort brauchen.



  • frosch03 schrieb:

    Na, das ist nicht ganz richtig. Allerdings merkt man auch nicht auf den ersten Blick wo Microsoft überall hintersteckt :). So wird z.B. der ghc (DER Haskell Compiler :)) federführend von Microsoftmitarbeitern entwickelt. Auch bei der Erstellung des Haskell98 Standards war Microsoft federführend. Der Vollständigkeit halber sollte man vielleicht noch erwähnen, dass es sich dabei um Microsoft Research handelt.

    Hast du dazu eine Quelle? Ich konnte lediglich verifizieren, dass GHC-Entwickler nach mehreren Jahren an der Arbeit am GHC von Microsoft Research angestellt wurden und dort dann am GHC weiter gearbeitet haben.



  • knivil schrieb:

    Also ich kenne mich nicht mit Haskell aus, bin eher bei Scheme. Dort gibt es Zustaende. Wenn sie aber lokal sind, dann kann man es Closure nennen. Die sind echt toll, da sie fuer (gewoehnlich) keine Seiteneffekte haben. Gewiss hat Haskell sowas aehnliches, da Zustand auch immer in Parametern kodiert werden kann.

    In Haskell wird dieser Parameter einfach mit etwas "syntactic sugar" hinter einem Monad versteckt. So dass man am Ende, wenn man wollte einen Zustand verwenden könnte, ohne sich über das "woher" Gedanken machen zu müssen.



  • u_ser-l schrieb:

    Wie sortiert ein Kind Spielkarten? Bestimmt nicht rekursiv mit Quicksort. Eher einfach "immer die nächstgrößte Karte nach vorne" oder vielleicht mit Bubblesort.

    Soweit ich weiß, benutzen Menschen intuitiverweise etwas in der Gegend von Insertion Sort.

    Insertion Sort in Haskell (http://en.wikibooks.org/wiki/Haskell/Algorithm_complexity) ist natürlich ziemlich elegant. 🙂

    sort []  = []
    sort [x] = [x]
    sort (x:xs) = insert (sort xs)
        where insert [] = [x]
              insert (y:ys) | x <= y    = x : y : ys
                            | otherwise = y : insert ys
    


  • ProgChild schrieb:

    Ich behaupte lediglich, dass der Mensch nicht sequenziell denkt.

    Und ich bestreite das lediglich. Paralleles oder funktionales Denken ist eine intellektuelle Errungenschaft, die erlernt werden muß.

    Die Sprache verrät, wie der Mensch von Natur aus denkt:

    "if ... then"
    "wenn ... dann"
    

    "then" ebenso wie "dann" haben jeweils zwei Bedeutungen:

    1. eine logischen Bedeutung (im Sinne von "daraus folgt")

    2. eine zeitliche Bedeutung ("danach")

    Also ist selbst die einfache logische Operation der Implikation (, die Grundbestandteil jeden strategischen Denkens und gedanklichen Vorwegnehmens von Vorgängen der realen Welt ist,)
    gedanklich untrennbar mit zeitlicher Abfolge verbunden.

    Einen deutlicheren Beweis dafür, daß der Mensch von Natur aus sequentiell denkt, kann es kaum geben - zumindest im germanischen und angelsächsischen Sprachraum.



  • kann es einen klareren Beweis geben ? - wir haben dasselbe Wort für das Schlußfolgern und die zeitliche Vorstellung!



  • u_ser-l schrieb:

    ProgChild schrieb:

    Ich behaupte lediglich, dass der Mensch nicht sequenziell denkt.

    Und ich bestreite das lediglich. Paralleles oder funktionales Denken ist eine intellektuelle Errungenschaft, die erlernt werden muß.

    Wie ich schon erwähnt habe, sehe ich sehr viele Menschen, die Probleme haben prozedural zu denken. Erkläre mir das mal, wenn das so natürlich ist.

    u_ser-l schrieb:

    Einen deutlicheren Beweis dafür, daß der Mensch von Natur aus sequentiell denkt, kann es kaum geben - zumindest im germanischen und angelsächsischen Sprachraum.

    Wo ist da der Beweis. Bloß weil der Mensch eine zeitliche Konsequenz, wie eine logische Konsequenz sprachlich gleich setzt, heißt das doch noch lange dass er in zeitlichen Konsequenzen denkt. Oder dass er in logischen Konsequenzen denkt.

    Du hast hier einfach nur einen Begriff durch einen anderen Ersetzt. Der Beweis, dass ein Mensch deswegen genau so denke, den bleibst du weiterhin schuldig.



  • Menschliches Sprechen, Denken und Wahrnehmen sind drei Aspekte eines verbindenden Phänomens (Bewußtsein) und entwicklungsgeschichtlich untrennbar miteinander verwoben.

    Wir können von Natur aus im Grunde genommen nur das denken, was wir sagen oder wahrnehmen können. Alles Andere führen wir gedanklich durch Analogien und Projektionen auf "erfahrbare" Objekte zurück.

    Wobei sich die Analogien natürlich mit zunehmendem Abstraktionsgrad verselbständigen können, bis man kaum noch erkennen kann, welches Objekt der realen Welt zugrunde liegt (Beispiel aus der abstrakten Algebra: Anzahl (in der realen Welt) => (abstrakte) Zahl => Primideal ... )



  • u_ser-l schrieb:

    Menschliches Sprechen, Denken und Wahrnehmen sind drei Aspekte eines verbindenden Phänomens (Bewußtsein) und entwicklungsgeschichtlich untrennbar miteinander verwoben.

    Nehmen wir mal an, dass diese Behauptung wahr ist. Jetzt hast du gezeigt, dass zeitliche Konsequenzen und logische Konsequenzen von uns als ähnlich gesehen werden. Nur was sagt uns das darüber wie wir denken? Rein gar nichts! Das sagt nämlich nicht, wie wir darauf kommen, diese als ähnlich zu sehen. Und das sagt erst recht nichts darüber aus, wie ein Mensch daran geht, komplexe Probleme zu lösen.

    Und du hast meine Frage schon wieder ignoriert. Erkläre mir mal bitte, warum so viele Menschen mit der prozeduralen Denkweise Probleme haben, wenn sie doch so natürlich ist.



  • Eine Frage am Rande:

    Haskell ist rein Funktional; Scheme unterstützt mehrere Paradigmen. Aber es sollte sich doch in Scheme alles ebenso elegant mit FP darstellen lassen wie in Haskell, oder täusche ich mich da?

    Nach der Diskussion will ich unbedingt FP ansehen und ich bin am überlegen, mit welcher Sprache ich einsteigen soll. 😉



  • ProgChild schrieb:

    Nur was sagt uns das darüber wie wir denken? Rein gar nichts!

    Stark vereinfacht: Denken ~ Wahrnehmen ~ Sprechen ~ Denken ("~" heißt: "ist beeinflußt von")

    Die Diskussion dreht sich im Kreise: lambda t.x(D(t)))2+(y(D(t)))2 == 1 😃

    ProgChild schrieb:

    Erkläre mir mal bitte, warum so viele Menschen mit der prozeduralen Denkweise Probleme haben, wenn sie doch so natürlich ist.

    wieviele haben denn mit prozeduralem Denken mehr Probleme als mit funktionalem? Prozedurales Denken muß nicht einmal erlernt werden. Ich erinnere mich noch an "was passiert dann ?"-Sketche in einer Kindersendung (war es die Sesamstraße? ) An einen Sketch "welche Funktion ergibt sich, wenn man die folgenden beiden komponiert ?" kann ich mich allerdings nicht erinnern, zumindest nicht im Kinderprogramm. 😕



  • @ProgChild: Jupp, mit deiner Vermutung könntest du richtig liegen, dass weiß ich nicht so genau. Was ich weiß ist, dass Peyton Jones und Marlow vor allem hinterm ghc stehen und die sind beide bei Microsoft Research angestellt. So wie Erik Meijer auch, wobei er glaub ich nicht wirklich am ghc-core arbeitet. Ich wollte im übrigen nur unterstreichen, dass man mittlerweile die Wichtigkeit von funProg bei Microsoft verstanden hat und Forschung in diese Richtung fördert.

    long long double schrieb:

    sollte sich doch in Scheme alles ebenso elegant mit FP darstellen lassen wie in Haskell, oder täusche ich mich da?

    Du hast sicherlich recht, dass man in Scheme alles ebenso funktional lösen kann wie in Haskell. Eleganz liegt im Auge des Betrachters. Ich möchte nicht für andere sprechen, aber für mich persönlich lassen sich Probleme in Haskell am elegantesten lösen. Von daher würde ich dir zu Haskell raten :).



  • u_ser-l schrieb:

    ProgChild schrieb:

    Nur was sagt uns das darüber wie wir denken? Rein gar nichts!

    Stark vereinfacht: Denken ~ Wahrnehmen ~ Sprechen ~ Denken ("~" heißt: "ist beeinflußt von")

    Du hast meinen Satz aus dem Zusammenhang genommen. Entweder du willst mir nicht folgen, oder du kannst es nicht.

    Du sagst, der Mensch kann nicht parallel Denken. Tatsache ich doch, dass ich gleichzeitig sehe, höre, schmecke, fühle, usw. Nach deiner Auffassung wäre das unmöglich.

    Und bloß weil meine Wahrnehmung beeinflusst, was ich denke, so sagt das nichts darüber aus, wie ich es denke! Aber ich wiederhole mich.

    u_ser-l schrieb:

    Die Diskussion dreht sich im Kreise

    Da stimme ich mit dir überein.

    u_ser-l schrieb:

    wieviele haben denn mit prozeduralem Denken mehr Probleme als mit funktionalem?

    Darauf kann ich dir keine Antwort geben. Ich kann dir nur sagen, dass das, was du als selbstverständlich erachtest, auch erst erlernt werden musste. Und es ist nicht so leicht, wie du tust. Wie gesagt ich sehe sehr viele Menschen, die genau die prozedurale Denkweise Probleme bereitet.

    Solange du diesen Schritt nicht akzeptierst, braucht ich dir nichts über die Einfachheit von funktionaler Programmierung erzählen. Denn du würdest immer nur sehen, dass es anders ist, als wie du es gewohnt bist.

    Dazu fällt mir folgendes Zitat ein.

    Languages less powerful than the one you know look impoverished [armselig].
    Languages more powerful than the one you know look weird [komisch].
    (Paul Graham)

    frosch03 schrieb:

    @ProgChild: Jupp, mit deiner Vermutung könntest du richtig liegen, dass weiß ich nicht so genau. Was ich weiß ist, dass Peyton Jones und Marlow vor allem hinterm ghc stehen und die sind beide bei Microsoft Research angestellt. So wie Erik Meijer auch, wobei er glaub ich nicht wirklich am ghc-core arbeitet. Ich wollte im übrigen nur unterstreichen, dass man mittlerweile die Wichtigkeit von funProg bei Microsoft verstanden hat und Forschung in diese Richtung fördert.

    Naja gut. Soweit ich weiß forscht Microsoft Research an so ziemlich allem. Das sagt eigentlich nichts aus. Ob Microsoft da irgendwann man was produktives mit auf die Beine stellt ist eine andere Sache.

    Der GHC hat ja schon eine lange Geschichte hinter sich. Und er ist OpenSource! Darum sehe ich auch kein Problem darin, dass jemand, der den Compiler weiter entwickelt irgendwann mal von Microsoft Research angestellt wurde. Der GHC enthält Code von über 60 Entwicklern und wenn er im Moment der beste Compiler ist, so ist er ja nicht der einzige. Haskell ist ja standardisiert. Es spricht also nichts dagegen, der Compiler zu verwenden.



  • ProgChild schrieb:

    Du sagst, der Mensch kann nicht parallel Denken.

    Das sage ich nicht. Ich sage, prozedurales oder objektorientiertes Denken ist dem Menschen natürlich mitgegeben, funktionales, deklaratives oder massiv paralleles Denken sind Kulturtechniken.

    Das Absehen vom zeitsequentiellen Aspekt erfordert Abstraktion, die erlernt und geübt werden kann.

    Die aber für das Überleben des Urmenschen keine große Rolle spielte, und daher nicht im Gehirn "festverdrahtet" zu sein braucht.

    [quote="ProgChild"]
    Dazu fällt mir folgendes Zitat ein.

    Languages less powerful than the one you know look impoverished [armselig].
    Languages more powerful than the one you know look weird [komisch].
    (Paul Graham)

    Ein schöner Aphorismus.



  • u_ser-l schrieb:

    Also ist selbst die einfache logische Operation der Implikation (, die Grundbestandteil jeden strategischen Denkens und gedanklichen Vorwegnehmens von Vorgängen der realen Welt ist,)
    gedanklich untrennbar mit zeitlicher Abfolge verbunden.

    Sprachliche Ausdrücke entwickeln sich immer vom Konkreten zum Abstrakten. Letztlich kann man es runterbrechen auf: Erst körperbezogene Bedeutung, dann Ortsangabe, dann Zeitangabe, dann weitere Abstraktion wie z. B. logische Bedingungen. Im Deutschen lässt sich die komplette Reihe in der Regel nicht mehr direkt finden. Dafür haben andere Sprachen in historischer Zeit für Ausdrücke die ganze Reihe durchlaufen. Aber auch im Deutschen lassen sich jede Menge Indizien finden. So haben diverse Zeitausdrücke ihre Entsprechungen in Ortsangaben (am Montag/am Rathaus, um 5 Uhr herum/um das Haus herum, zwischen 3 und 5 Uhr/zwischen Tisch und Stuhl, ...). Aber auch das körperbezogene Koordinatensystem lässt sich stellenweise noch im Deutschen und (besser) im Englischen erknnen. Zum Beispiel in "zurück" oder "back" steckt noch ziemlich gut erkennbar der Rücken.

    Die Entwicklung von konkret zu abstrakt ist universell und sagt noch nichts über menschliche Denkweisen im Allgemeinen aus. Sondern erst einmal nur über die Fähigkeit Analogien zu bilden. Im Grunde ist jedes Funktionswort eine tote Metapher.

    Im Fall von "dann" ist das nicht anders. Im Althochdeutschen hat "dann" ausschließlich örtliche oder zeitliche Bedeutung. Die kausale entwickelte sich erst in den letzten Jahrhunderten. Eine funktionale Unterscheidung zwischen "dann" und "denn" erfolgt sogar erst seit dem 18. Jahrhundert. Davor hatte selbst "denn" keine kausale Bedeutung.

    ProgChild schrieb:

    Wie ich schon erwähnt habe, sehe ich sehr viele Menschen, die Probleme haben prozedural zu denken. Erkläre mir das mal, wenn das so natürlich ist.

    Ich habe an der Universität sowohl Kurse für prozedurale, als auch für objektorientierte und für logische Programmierung betreut. Logische Programmierung ist eben so deklarativ wie funktionale Programmierung. Dein Summenbeispiel sähe in Prolog z. B. so aus:

    summe([], 0).
    summe([H|T], S) :- summe(T, ST), S is ST + H.

    Das ist ein unglaublich einfaches Programm. Der Wert von keiner Zahl zusammengezählt ist 0, ansonsten nimmt man eine Zahl von der Liste, rechnet die Summe für den Rest aus und addiert darauf diese Zahl, fertig.

    ?- summe([3,5,7], S).
    S = 15.

    Meine Erfahrung aus diesen Kursen ist, dass Programmieranfänger, die noch nie mit Programmierung in Berührung kamen, völlig unabhängig vom Paradigma der Programmiersprache enorme Probleme haben. Du sagst, die rekursive Lösung des Summenbeispiels sei natürlich und einfach. Doch meine Erfahrung ist, dass ausgerechnet die Rekursion die Anfänger vor schier unlösbare Probleme stellt. Es braucht in der Regel lange und viel Frust, bis sie einfache Probleme rekursiv lösen können. Und dafür ist es egal, was für ein Paradigma die Programmiersprache verfolgt. Nur bei deklarativen ist es natürlich offensichtlicher.

    Ich würde aufgrund meiner Erfahrung also nicht sagen, dass es die prozedurale Programmierung ist, die schwer erlernbar ist. Denn echte Anfänger haben mit der deklarativen Programmierung ebenfalls ihre liebe Not. Für mich sieht die Situation wie folgt aus: Das Paradigma ist nicht das Problem. Viel eher ist das streng formale Durchdenken einer Aufgabe das Problem. Daran hackt es bei echten Anfängern.

    Wenn man aber prozedurale gegen deklarativ antreten lässt, dann würde ich persönlich eher zu u_ser-l neigen. Wenn man den Anfängern erklärt, dass y = x*x keine Bedeutung definiert, sondern einen konkreten Ablauf ausführt, dann kapieren sie das schnell. Aber Rekursion - und ohne die geht es in deklarativen Sprachen nicht wirklich - das ist eine ganz andere Nuss. Die kann man ihnen fünfmal erklären und sie produzieren dann immer noch *hust* Mist *hust* 😉



  • u_ser-l schrieb:

    Das sage ich nicht. Ich sage, prozedurales oder objektorientiertes Denken ist dem Menschen natürlich mitgegeben, funktionales, deklaratives oder massiv paralleles Denken sind Kulturtechniken.

    Das Absehen vom zeitsequentiellen Aspekt erfordert Abstraktion, die erlernt und geübt werden kann.

    Die aber für das Überleben des Urmenschen keine große Rolle spielte, und daher nicht im Gehirn "festverdrahtet" zu sein braucht.

    Wenn der Urmensch auf die Jagt ging, musste er alle seine Sinne benutzen. Zum Beispiel musst er gleichzeitig lauschen, ob sich irgendwo was bewegt und langsam vorwärts schreiten.

    Er hat sich bestimmt nicht gedacht: "Ich gehe einen Schritt. Dann bleibe ich stehen und lausche. Dann gehe ich wieder einen Schritt. Dann bleibe ich wieder stehen..."
    Er wird wohl gedacht haben: "Ich gehe langsam vorwärts und währenddessen lausche ich."

    Aber egal. Belassen wir es dabei!



  • minhen schrieb:

    Aber Rekursion - und ohne die geht es in deklarativen Sprachen nicht wirklich - das ist eine ganz andere Nuss. Die kann man ihnen fünfmal erklären und sie produzieren dann immer noch *hust* Mist *hust* 😉

    Das Problem an der Sache ist, dass man sagt: "Rekursion ist wenn eine Funktion sich selber aufruft." Das ist so abstrakt, dass der Zuhörer reflexartig sagt: "Verstehe ich nicht." Wenn man ihnen aber ein paar Beispiele präsentiert und wie man sich Schritt für Schritt immer komplizierteren Problemen nähert, so wird das alles plötzlich total natürlich.

    Denke man mal an die ganzen Graphen und Baum-Algorithmen. Ohne Rekursion wäre die meisten nicht so einfach nachvollziehbar.



  • ProgChild schrieb:

    minhen schrieb:

    Aber Rekursion - und ohne die geht es in deklarativen Sprachen nicht wirklich - das ist eine ganz andere Nuss. Die kann man ihnen fünfmal erklären und sie produzieren dann immer noch *hust* Mist *hust* 😉

    Das Problem an der Sache ist, dass man sagt: "Rekursion ist wenn eine Funktion sich selber aufruft." Das ist so abstrakt, dass der Zuhörer reflexartig sagt: "Verstehe ich nicht." Wenn man ihnen aber ein paar Beispiele präsentiert und wie man sich Schritt für Schritt immer komplizierteren Problemen nähert, so wird das alles plötzlich total natürlich.

    Nein, ist es nicht. Oder glaubst du ernsthaft, ich rede von solchen Erklärungen:

    Erklärung 1: Rekursion ist, wenn sich eine Funktion selbst aufruft.
    Versteht ihr nicht? Ok:
    Erklärung 2: Eine sich selbst aufrufende Funktion nennt man rekursiv.
    Versteht ihr nicht? Ok:
    Erklärung 3: Rekursiv bedeutet, dass sich die Funktion immer wieder selbst aufruft.
    Versteht ihr immer noch nicht? Mensch, seid ihr doof!

    Wenn du das unter "Rekursion erklären" verstehst, nur weil man eine andere Meinung als du hast ... dann brauchen wir das Thema gar nicht weiter diskutieren, weil es dann schlicht sinnlos wäre.



  • sollte es nach der neuen Rechtschreibung nicht konsequenterweise 'funkzionale Programmierung' heißen?

    - vgl 'Differenzial' vs 'Differential'




Anmelden zum Antworten