Haskell



  • Und jetzt erkläre mir nochmal, wie man zur Kompilierzeit eine Situation verhindenr will, die erst zur Laufzeit (wenn ich tatsächlich eine konkrete Liste in der Hand halte und durch ihre Elemente iteriere) auftreten kann.
    (und komme mir bitte nicht mit "dafür ist Haskell nicht gedacht").

    Kurz zum Maybe (Ptr a) (aus meiner Sicht).

    Maybe ist folgendermaßen definiert:
    data Maybe a = Just a | Nothing

    D.h. Maybe (Ptr a) ist entweder Just (Ptr a) oder Nothing , d.h. falls eine C-Funktion einen ungültigen Pointer zurückgibt ( Ptr a ist teil des Foreign Function Interface) wird in Haskell daraus Nothing . Jetzt könntest du eine Funktion f schreiben, die folgendermaßen aussieht:

    f :: Maybe (Ptr a) -> a 
    f Just (Ptr a) = -- Version für einen gütligen Zeiger
    f Nothing = -- Version für einen ungültigen Zeiger
    

    Du kannst also gar nicht mit ungültigen Zeigern hantieren.

    Das könnte man auch in C++ mit Klassen und Überladung irgendwie erreichen, das macht aber niemand, weil das unnötig ineffizient ist. Stattdessen macht man eben manuelles Pattern-Matching. Mir gefällt die Haskell-Version allerdings besser.

    Selbst der Beitrag sagt nicht aus, daß du mit Haskell alle Fehler zur Compilezeit verhindern kannst.

    Du verlangst von Haskell, dass es alle Fehler zur Compilezeit verhindert? Bleib realistisch.
    Es verhindert einige (siehe Maybe (Ptr a) ), aber wie soll es denn alle verhindern?



  • was gibt eigentlich Haskell aus, wenn du den Definitionsbereich einer partiell definierten Funktion verlässt? (d.h. wenn ich für den "Nothing"-Teil nichts sinnvolles machen kann und den Teil offen lasse)

    Irgendwer schrieb:

    Selbst der Beitrag sagt nicht aus, daß du mit Haskell alle Fehler zur Compilezeit verhindern kannst.

    Du verlangst von Haskell, dass es alle Fehler zur Compilezeit verhindert? Bleib realistisch.
    Es verhindert einige (siehe Maybe (Ptr a) ), aber wie soll es denn alle verhindern?

    Ich verlange von Haskell gar nichts. Aber von den Haskell-Vertretern kam die Aussage, daß compilierte Programme fehlerfrei sind. In dem Artikel wurde gezeigt, wie man durch eine Umstellung der Semantik einige Fehler vermeiden kann - aber deswegen kann man trotzdem immer noch genug Mist bauen.



  • was gibt eigentlich Haskell aus, wenn du den Definitionsbereich einer partiell definierten Funktion verlässt? (d.h. wenn ich für den "Nothing"-Teil nichts sinnvolles machen kann und den Teil offen lasse)

    Entweder gibt's einen Pattern-Matching Fehler, d.h. du hast den Nothing Teil komplett weggelassen, oder du wirfst eine Exception oder benutzt error - genauso wie du es in C++ auch machen wirst. Ganz schön kann auch die Maybe-Monade sein, bei der nur weitergemacht wird, solange eine Funktion Just a zurückgibt, ansonsten wird direkt abgebrochen - und das alles ohne ein direktes "if" zu schreiben, da sich das alles im Bind-Operator >>= abspielt.

    Du kannst auch am immer gegen ein beliebiges Pattern matchen:

    data Bar = Foo | Bar | Baz
    f :: Bar -> Int
    f Foo = 1
    f Bar = 2
    f _   = error "Invalid value"
    

    Aber natürlich werden partiell definierte Funktionen vermieden wo es nur geht.

    Aber von den Haskell-Vertretern kam die Aussage, daß compilierte Programme fehlerfrei sind.

    Ja, mit der Aussage hat ertes wohl die Gemüter hier ziemlich in Wallungen gebracht. Ich bin kein erfahrener Haskell-Programmierer, habe aber von erfahrenen Haskellern schon häufig die Aussage gehört und gelesen, dass Programme häufig beim ersten kompilieren laufen.

    Aber vielleicht sind das auch einfach alles schlechte imperative Programmierer und Lüger noch obendrauf. 😉



  • ertes schrieb:

    head . dropWhile (<= 110) . filter even . map (^2) $ [0..]

    Durch äquivalente Umformungen wird die Liste vollständig wegoptimiert

    und in Forth kann man - bei laufender Compilierung eines Wortes (!) - den Compiler ausschalten, den Interpreter anschalten, die fragliche Zahl (min x mit 2|x und x^2>=110) vom Interpreter berechnen lassen, das Ergebnis festverdrahtet in den Maschinencode einfügen, den Compiler wieder anschalten und den Rest des Programms compilieren.

    Da wird aber nicht so ein Buhei drum gemacht wie in der funktionalen Programmierung.



  • Das Konzept "Beispiel" hast du auch nicht verstanden, oder?

    In Haskell hindert dich niemand daran obige Funktion in GHCi auszuführen und das Ergebnis direkt in den Quelltext zu schreiben. Genauso wie dich daran in C++ oder Forth keiner hindert. Den großen Vorteil in der Unterbrechbarkeit des Kompiliervorgangs sehe ich nicht...



  • Irgendwer schrieb:

    Den großen Vorteil in der Unterbrechbarkeit des Kompiliervorgangs sehe ich nicht...

    Das ist mal wieder das Blub-Paradox 🙂 Oder du siehst den Wald vor Bäumen nicht, das ist nämlich nichts anderes als Metaprogrammierung.



  • !rr!rr_. schrieb:

    und in Forth kann man - bei laufender Compilierung eines Wortes (!) - den Compiler ausschalten, den Interpreter anschalten, die fragliche Zahl (min x mit 2|x und x^2>=110) vom Interpreter berechnen lassen, das Ergebnis festverdrahtet in den Maschinencode einfügen, den Compiler wieder anschalten und den Rest des Programms compilieren.

    Zeigst Du auch hier bitte den Code, der genau das schafft?



  • Oder du siehst den Wald vor Bäumen nicht, das ist nämlich nichts anderes als Metaprogrammierung.

    So kann man das natürlich auch sehen. Ich kenne mich mit Forth nicht aus, weswegen die Frage bestehen bleibt, ob der Compiler das selber macht - also Werte (auch komplexere wie diese Funktion) vorab berechnet - oder ob ich da selber die Kompilation unterbrechen muss (so wie es !rr!rr_. beschrieben hat).



  • volkard schrieb:

    Zeigst Du auch hier bitte den Code, der genau das schafft?

    : foo [ bar ] literal ... ;
    

    "[" schaltet den Compiler aus und den Interpreter an, "]" bewirkt das Umgekehrte, und "literal" baut das vom Interpreter errechnete Ergebnis von bar festverdrahtet in das Compilat ein.

    "bar" ist ein Wort, das das gefragte min x berechnet und ist dem geneigten Leser als Übung überlassen 😃



  • komplettes Beispiel für die wo kein Forth können:

    : bar 110 1 do i dup * 110 >= i 2 mod 0= and if i unloop exit then loop ;
    : foo [ bar ] literal ;
    foo . cr  ( "12" )
    


  • Danke. Habe anscheinend viel Forth vergessen.


Anmelden zum Antworten