Seite 1 von 2

Funktionale Sprachen

Verfasst: Dienstag 21. August 2007, 17:29
von birkenfeld
Und wenn man mal meint, man weiß genug zum Thema Programmieren, einfach mal ne funktionale Sprache, am besten Haskell lernen.

Edit: Vom ursprünglichen Thread abgetrennt.

Verfasst: Mittwoch 22. August 2007, 09:15
von BlackJack
Anschauen ja, staunen ja, aber *lernen*!? Solange es "lineare" Programme ohne Benutzerinteraktion und Fehlerbehandlung sind, ist Haskell ja okay, aber wie man so etwas wie russisches Roulette mit Zufallszahlen und Ausgaben und Eingaben machen soll, ist mir echt zu hoch. Jedenfalls wenn man nicht das ganze Programm in die IO-Monade "verschieben" will und letztendlich doch wieder imperativ programmiert. Da sind mir hybride Sprachen wie Scheme oder OCaml doch lieber. Ich hab's mal in OCaml versucht:

http://paste.pocoo.org/show/2793/

Verfasst: Mittwoch 22. August 2007, 13:10
von HWK
BlackJack hat geschrieben:Anschauen ja, staunen ja, aber *lernen*!? Solange es "lineare" Programme ohne Benutzerinteraktion und Fehlerbehandlung sind, ist Haskell ja okay, aber wie man so etwas wie russisches Roulette mit Zufallszahlen und Ausgaben und Eingaben machen soll, ist mir echt zu hoch. Jedenfalls wenn man nicht das ganze Programm in die IO-Monade "verschieben" will und letztendlich doch wieder imperativ programmiert.
Ganz meine Meinung. Ich fand Haskell von der Idee ziemlich interessant. Ich wollte deshalb versuchsweise mal eins meiner Mini-Python-Scripts in Haskell konvertieren. Bei der Datenausgabe wurde es dann aber mit den Monaden ziemlich wüst, so dass von der Eleganz Haskells nichts mehr zu erkennen war. Ganz zu schweigen von der Zeit, die ich im Gegensatz zu meinem ersten Python-Script brauchte, um es zum Laufen zu bringen. Ich bin zwar nur Amateur und kein Informatik-Profi, aber Freude am Programmieren bringt mir Haskell nicht.
@Blackjack: Meinst Du wirklich mit OCaml oder Scheme geht's besser? Welche von beiden würdest Du dann am ehesten empfehlen?
MfG
HWK

Verfasst: Mittwoch 22. August 2007, 13:57
von BlackJack
Ich denke mit OCaml oder Scheme geht's besser als mit Haskell. Letztlich sind beides auch imperative Sprachen, so wie Python auch eine Menge funktionales bietet. Die beiden "funktionalen" Sprachen nähern sich der Mischung eben eher von der funktionalen Seite und Python eher von der Imperativen.

Im OCaml-Buch steht unter Funktional vs. Imperativ auch sinngemäss, das beides seine Berechtigung hat und es Probleme gibt die sich einfacher Funktional ausdrücken lassen und solche die Imperativ besser beschrieben werden können.

Eben an der Stelle wo die Eleganz bei Haskell aufhört, wenn man doch mal irgendwo eine Sequenz von Anweisungen mit Seiteneffekten braucht, oder Objekte mit einem veränderbaren Zustand, kann man das in OCaml und Scheme einfach machen.

Beim russischen Roulette in OCaml hätte ich den "Revolver" zum Beispiel auch als veränderbaren "record" oder gar als Objekt modellieren können. Dann hätte ich mir einiges an hin und herreichen des Revolvers ersparen können. Aber in dem Punkt wollte ich funktional bleiben. :-)

Verfasst: Mittwoch 22. August 2007, 14:44
von HWK
Klingt vielversprechend. Wo siehst Du den Unterschied zwischen Scheme und OCaml? Welche der beiden sollte ich mir denn am ehesten einmal anschauen? Mit Haskell hatte ich mich wie gesagt bereits etwas beschäftigt. Es scheint, als ob Du OCaml bevorzugen würdest.
MfG
HWK

Verfasst: Mittwoch 22. August 2007, 15:13
von Leonidas
Scheme ist eben ein recht pythonisches Lisp, es hat eine sehr simple Syntax die zugleich auch als Datenstruktur dient - d.h. mit Scheme kann man Programme schreiben, die sich selbst modifizieren (indem sie die Datenstruktur ändern). Zudem in einigen Aspekten Python ähnlich, das Scoping funktioniert so ziemlich identisch. Die Syntax ist für funktionale Programmierung gar nicht mal so übel, aber imperative Programmierung macht eher weniger Spaß. Es ist einer der simpelsten Lisp Dialekte, seine Spezifikation ist etwa so lang wie der Appendix der Spezifikation zu Common Lisp. Zu Scheme gibt es auch mehrere recht akademische Bücher, im bekanntesten wird am Schluss sogar ein Scheme-Interpreter in Scheme programmiert. Scheme hat recht viele Implementationen die sich sehr unterscheiden. Fürs Lernen ist PLT-Scheme empfohlen, da es einen Editor hat, DrScheme, der extra zum lernen für Studenten gedacht ist. Daneben gibt es noch Bigloo, welches ganz verschiedenen Bytecode generieren kann, unter anderem auch für.NET.

OCaml hingegen hat eine Implementation, die sehr schnell ist und einige wenige Bücher. Die Syntax ist eher "normal", wenn man andere Imperative Sprachen gewohnt ist,ich muss aber zugeben, dass sie mir nicht gefällt - da finde ich Scheme etwas besser. OCaml ist auch im akademischen Umfeld beheimatet, Real-World-Programme gibt es auch eher wenige. Im Gegensatz zu vielen anderen funktionalen Sprachen kann man in OCaml auch Objekte nutzen (in CL gibts dafür CLOS und in Scheme bastet sich jeder sowas selbst). Es gibt noch einen Dialekt, F#, der auf .NET abzielt.

Ich habe mit keiner der beiden Sprachen sonderlich viel Erfahrung - das Problem ist auch, dass man damit nicht so leicht zu irgendwelchen brauchbaren Ergebnissen kommt.

Verfasst: Mittwoch 22. August 2007, 15:24
von HWK
Leonidas hat geschrieben:das Problem ist auch, dass man damit nicht so leicht zu irgendwelchen brauchbaren Ergebnissen kommt.
Den Eindruck habe ich auch. Aber interessante Ansätze enthält z.B. Haskell doch, z.B. die besondere "Faulheit", die es ermöglicht, "unendlich lange Listen" zu definieren. OCaml scheint ja gewisse Elemente mit Haskell gemeinsam zu haben. Außerdem schreibst Du ja auch:
Leonidas hat geschrieben:Die Syntax ist eher "normal", wenn man andere Imperative Sprachen gewohnt ist
Deshalb werde ich mir wohl OCaml einmal etwas näher anschauen.
Danke Euch beiden
HWK

Verfasst: Mittwoch 22. August 2007, 15:46
von Leonidas
HWK hat geschrieben:Den Eindruck habe ich auch. Aber interessante Ansätze enthält z.B. Haskell doch, z.B. die besondere "Faulheit", die es ermöglicht, "unendlich lange Listen" zu definieren.
Naja, sowas ähnliches geht in Python mit den Generatoren ja auch:

Code: Alles auswählen

def infinite(element):
    while True:
        yield element

infinite_generator = infinite(None)
Nur sollte man darauf dann nicht ``list()`` ausführen.

Verfasst: Mittwoch 22. August 2007, 15:46
von Craven
Ich werde mir in der nächsten Zeit wahrscheinlich Struktur und Interpretation von Computerprogrammen besorgen. Darin wird Scheme verwendet, d.h. ich könnte, wenn Interesse besteht, meinen Eindruck von der Sprache posten, etc. Wird aber 'n bisschen dauern, da ~700 Seiten. ;)

Verfasst: Mittwoch 22. August 2007, 15:51
von Leonidas
Craven hat geschrieben:Ich werde mir in der nächsten Zeit wahrscheinlich Struktur und Interpretation von Computerprogrammen besorgen. Darin wird Scheme verwendet, d.h. ich könnte, wenn Interesse besteht, meinen Eindruck von der Sprache posten, etc. Wird aber 'n bisschen dauern, da ~700 Seiten. ;)
Das ist eben das Buch von dem ich sprach, das Wizard-Book, in dem am Schluss eine Scheme Implementation geschrieben wird. Ist aber nicht als Buch vor dem Schlafengehen geeignet. ;) Mich würde dann deine Meinung zum Buch interessieren.

Verfasst: Mittwoch 22. August 2007, 15:58
von BlackJack
Ich weiss nicht ob ich OCamls Syntax als "normal" ansehen würde. Die ist schon recht funktional und der von Haskell gar nicht so unähnlich. So etwas wie Pattern-Matching findet man in imperativen Sprachen zum Beispiel selten.

Verfasst: Mittwoch 22. August 2007, 17:02
von HWK
Craven hat geschrieben:Ich werde mir in der nächsten Zeit wahrscheinlich Struktur und Interpretation von Computerprogrammen besorgen. Darin wird Scheme verwendet, d.h. ich könnte, wenn Interesse besteht, meinen Eindruck von der Sprache posten, etc. Wird aber 'n bisschen dauern, da ~700 Seiten. ;)
Das Buch schaut interessant aus. Das werde ich mir eventuell auch einmal antun.
MfG
HWK

Verfasst: Mittwoch 22. August 2007, 19:34
von birkenfeld
So, hier ist die Haskell-Version vom Russischen Roulette.

Sie ist dem OCaml-Pendant nicht unähnlich, sprich, wo es imperativ ist, ist es Haskell auch, und das problemlos:

http://paste.pocoo.org/show/2828/

(Und die Einrückung ist bedeutsam, aber das nur am Rande :))

Wenn ich mal Lust habe, schreibe ich noch eine Version mit State-Monade, also ohne Revolver-Herumreichen ;)

Verfasst: Mittwoch 22. August 2007, 19:59
von veers
Mein Problem mit funktionalen Sprachen ist vor allem das ich nicht weiss wann ich sie verwenden sollte. Scheme habe ich mal etwas im zusammenhang mit Gimp gebraucht. Aber das war es dann auch schon mit praktischer anwendung. Naja auch als vim Benutzer werde ich mir wohl mal die Zeit gönnen und Lisp lernen. Und sei es nur aus reiner Freude am lernen.

Verfasst: Mittwoch 22. August 2007, 20:20
von birkenfeld
Genau das ist es, was mich zu Haskell gebracht hat: Freude am Lernen. Und der Gedanke: wenn ich mir schon eine neue Programmiersprache anschaue und evtl. sogar aneigne, dann sollte es eine ganz radikal andere sein, die in ihrem Gebiet ebenso herausragend ist wie Python auf seinem.

Und dem Mathematiker in mir geht bei dieser Sprache einfach das Herz auf :D

Natürlich werde ich jetzt Python deswegen nicht über Bord werfen. Aber ich werde weiter dabeibleiben mich über den erweiterten Horizont freuen.

Verfasst: Mittwoch 22. August 2007, 20:22
von HWK
birkenfeld hat geschrieben:So, hier ist die Haskell-Version vom Russischen Roulette.

Sie ist dem OCaml-Pendant nicht unähnlich, sprich, wo es imperativ ist, ist es Haskell auch, und das problemlos:

http://paste.pocoo.org/show/2828/

(Und die Einrückung ist bedeutsam, aber das nur am Rande :))

Wenn ich mal Lust habe, schreibe ich noch eine Version mit State-Monade, also ohne Revolver-Herumreichen ;)
Das sieht gut aus. Ich hätte aber irgendwie ein anderes Verhalten erwartet. Hier einmal ein Probelauf:

Code: Alles auswählen

Main> main
---------
Spieler
Trommel drehen?
j
Trommel dreht sich
*klick*
---------
Computer
*klick*
---------
Spieler
Trommel drehen?
n
***Peng***     -- Ich wollte ja gar nicht schießen
==========
Spieler ist tot.

Main> main
---------
Spieler
Trommel drehen?
j
Trommel dreht sich
*klick*
---------
Computer
*klick*
---------
Spieler
Trommel drehen?
j
Trommel dreht sich
*klick*
---------
Computer
*klick*
---------
Spieler
Trommel drehen?
n
*klick*  -- Ich habe ja wieder nicht geschossen
---------
Computer
*klick*
---------
Spieler
Trommel drehen?
n
*klick*
---------
Computer
Trommel dreht sich
***Peng***
==========
Computer ist tot.
MfG
HWK

Verfasst: Mittwoch 22. August 2007, 20:23
von birkenfeld
Trommel drehen != Abdrücken. Abgedrückt wird nach jedem Zug, du kannst halt vorher die Trommel verdrehen (-> die volle Patrone wird wieder zufallsverteilt) oder nicht (-> die Trommel dreht sich um eins weiter).

Verfasst: Mittwoch 22. August 2007, 20:24
von HWK
Alles klar.
Danke
HWK

Verfasst: Mittwoch 22. August 2007, 20:33
von birkenfeld
So, hier ist noch die Version mit State-Monade: http://paste.pocoo.org/show/2830

In dem Fall ist das aber kaum übersichtlicher, lohnt sich also nicht.

Verfasst: Mittwoch 22. August 2007, 20:40
von BlackJack
@birkenfeld: Die Ähnlichkeit ist wirklich nicht zu übersehen. Mir hätte so aus dem Kopf `return` gefehlt und der Datentyp für `Player`. Das sieht aus wie `record`\s in OCaml, wusste gar nicht, dass es so etwas in Haskell gibt. In "Haskell - The Craft of Functional Programming" kommt das glaube ich nicht vor.