Funktionale Programmiersprachen wie Haskell

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Hallo,

ich bin auf meiner Suche nach neuem "Programmierer-Wissen" auf Funktionale Programmierung gestoßen, und möchte dazu jetzt einfach mal ein paar Fragen stellen. Ich habe mal ein Haskell Tutorial überflogen. Schon der erste Satz
C-Programmierer. Vergeßt! Vergeßt am besten alles, was Ihr über Programmierung und Programmiersprachen wißt.
macht mich irgendwie stutzig. Da Python und C jetzt ja nicht "so" weit auseinander liegen, muss ich wohl auch vergessen.

Wenn man sich z.B. diese einfach Haskell Funktion anschaut

Code: Alles auswählen

sq(n)=n*n
, dann ist das doch das selbe wie

Code: Alles auswählen

def sq(n): return n*n
oder? Dies nur mal als kleines Beispiel. Was ich auch nicht verstehe, ist der Gedanke, dass Zeit keine Rolle spielen soll. Ich meine, die Zeit ist vorhanden, also müssen auch diese Programme, in einer zeitlichen Reihenfolge ausgeführt werden, es sei denn, die Anweisungen werden gleichzeitig gelesen.
Mir ist klar, dass man dafür wahrscheinlich viel tiefer eintauchen müsste, aber so auf den ersten Blick versteh ich überhaupt nicht, was das soll.

Ich hoffe, jemand kann etwas Licht ins dunkel bringen
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Um ehrlich zu sein habe ich nicht viel verstanden, aber gerade soviel das ich in Python was mit anfangen kann. Habe glaube ich das gleiche Tutorial gelesen wie du ;) http://www.informatik.uni-bonn.de/~ralf ... .html#SEC4

Das witzige ist, das keins der Beispiele mit WinHugs funktionierte. Naja...

lg
BlackJack

basti33 hat geschrieben:Ich habe mal ein Haskell Tutorial überflogen. Schon der erste Satz
C-Programmierer. Vergeßt! Vergeßt am besten alles, was Ihr über Programmierung und Programmiersprachen wißt.
macht mich irgendwie stutzig. Da Python und C jetzt ja nicht "so" weit auseinander liegen, muss ich wohl auch vergessen.
Ja, Python bietet zwar viel um funktionale Programmierung zu unterstützen, ich benutze das auch gerne, aber *rein* funktional wie Haskell ist es nicht. Und diese "Reinheit" ist es was Haskell so kompliziert macht wenn man C oder Python gewohnt ist.
Wenn man sich z.B. diese einfach Haskell Funktion anschaut

Code: Alles auswählen

sq(n)=n*n
, dann ist das doch das selbe wie

Code: Alles auswählen

def sq(n): return n*n
oder?
Im Grunde schon. Hier hast Du aber in Python eine Funktion im funktionalen Sinne geschrieben. Bekommt ein Argument, berechnet etwas, berechnet bei gleicher Eingabe immer das gleiche Ergebnis und hat keine Seiteneffekte.
Was ich auch nicht verstehe, ist der Gedanke, dass Zeit keine Rolle spielen soll. Ich meine, die Zeit ist vorhanden, also müssen auch diese Programme, in einer zeitlichen Reihenfolge ausgeführt werden, es sei denn, die Anweisungen werden gleichzeitig gelesen.
Die Ausführung von Haskellprogrammen benötigt auch Zeit. Aber es gibt keine Seiteneffekte, also auch kein Vorher und kein Nachher was einen Seiteneffekt angeht, es gibt keine Veränderungen. Und wenn es kein eindeutiges Vorher und Nachher gibt, dann ist der Zeitbegriff bedeutungslos. Was ein Haskell-Compiler zum Beispiel dazu nutzen kann, Teile des Programms so zu übersetzen, dass sie wirklich gleichzeitig laufen. Multicore-Prozessoren sind ja keine Seltenheit mehr.

Wenn man mit der "realen" Welt in Kontakt kommt, dann gibt's natürlich doch wieder so etwas wie Seiteneffekte, das wird in Haskell in "Monaden" gekapselt. Da gibt's ein ganz schickes theoretisches Erklärungsmodell warum das immer noch rein funktional ist, aber da raucht einem der Kopf wenn man sich damit näher beschäftigt. :-)
BlackJack

sape hat geschrieben:Das witzige ist, das keins der Beispiele mit WinHugs funktionierte. Naja...
Die Definitionen müssen in einer Textdatei stehen die geladen wird. Interaktiv lassen sich nur Ausdrücke auswerten.
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Danke für die Antworten.
BlackJack hat geschrieben:Im Grunde schon. Hier hast Du aber in Python eine Funktion im funktionalen Sinne geschrieben. Bekommt ein Argument, berechnet etwas, berechnet bei gleicher Eingabe immer das gleiche Ergebnis und hat keine Seiteneffekte.
Und wie ist das bei Haskell?
BlackJack hat geschrieben:Die Ausführung von Haskellprogrammen benötigt auch Zeit. Aber es gibt keine Seiteneffekte, also auch kein Vorher und kein Nachher was einen Seiteneffekt angeht, es gibt keine Veränderungen. Und wenn es kein eindeutiges Vorher und Nachher gibt, dann ist der Zeitbegriff bedeutungslos. Was ein Haskell-Compiler zum Beispiel dazu nutzen kann, Teile des Programms so zu übersetzen, dass sie wirklich gleichzeitig laufen. Multicore-Prozessoren sind ja keine Seltenheit mehr.
Was kann ich mir unter so einem "Seiteneffekt" vorstellen?
BlackJack

basti33 hat geschrieben:
BlackJack hat geschrieben:Im Grunde schon. Hier hast Du aber in Python eine Funktion im funktionalen Sinne geschrieben. Bekommt ein Argument, berechnet etwas, berechnet bei gleicher Eingabe immer das gleiche Ergebnis und hat keine Seiteneffekte.
Und wie ist das bei Haskell?
Na genau so ist das bei Haskell. Und man kann nur solche Funktionen schreiben.
BlackJack hat geschrieben: Was kann ich mir unter so einem "Seiteneffekt" vorstellen?
Das sich irgendwo im Speicher oder sonstwo ein Zustand ändert, der ausserhalb einer Funktion sichtbar ist.

Code: Alles auswählen

a = range(5)

def f(a, i, v):
    a[i] = v

f(a, 2, 0)
Hier ändert sich ein Element der Liste `a`. Das geht in Haskell nicht. In Haskell ist alles "immutable". Zuweisungen gibt's auch nicht -- das `=` ist eine Definition im mathematischen Sinn. Einmal gemacht, kann man sie nicht mehr verändern.
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!
C-Programmierer. Vergeßt! Vergeßt am besten alles, was Ihr über Programmierung und Programmiersprachen wißt.
Das Tutorial kenn ich auch, ich find's allerdings nicht gut. Wobei ich ehrlich sagen muss, dass ich bis jetzt kein wirklich gutes Haskell-Tutorial gefunden habe. Haskell ist mir irgendwie zu hoch.
BlackJack

mawe hat geschrieben:
C-Programmierer. Vergeßt! Vergeßt am besten alles, was Ihr über Programmierung und Programmiersprachen wißt.
Das Tutorial kenn ich auch, ich find's allerdings nicht gut. Wobei ich ehrlich sagen muss, dass ich bis jetzt kein wirklich gutes Haskell-Tutorial gefunden habe. Haskell ist mir irgendwie zu hoch.
Es gibt noch Haskell for C Programmers. Letztendlich stimmt der Satz da oben: Vergessen was man von nicht-funktionalen Programmiersprachen weiss. Dann geht's leichter. Vor allem sollte man vermeiden sich vorzustellen wie Haskell wohl in C übersetzt aussieht.
BlackJack

Spätestens ab Kapitel 3 ist es dann aber nicht mehr für Haskell geeignet. Lisp ist keine reine funktionale Programmiersprache.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Als Einstieg würde ich YAHT empfehlen. Lässt sich sehr gut lesen und durch die ersten Seiten bekommt man einen sehr guten Einstieg ohne das man durch irgendwelche Details erschlagen wird.
BlackJack

Vielleicht könnte mal jemand mit der Berechtigung dazu den Benutzer Lafgatie löschen. Das scheint ein Spambot zu sein, der öfter mal Beiträge bringt die nicht so ganz passen und immer einen Link zu der gleichen Webseite enthalten.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Vielleicht könnte mal jemand mit der Berechtigung dazu den Benutzer Lafgatie löschen. Das scheint ein Spambot zu sein, der öfter mal Beiträge bringt die nicht so ganz passen und immer einen Link zu der gleichen Webseite enthalten.
Done. Zusätzlich habe ich auch die Postings gelöscht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

basti33 hat geschrieben:Ich habe mal ein Haskell Tutorial überflogen. Schon der erste Satz
C-Programmierer. Vergeßt! Vergeßt am besten alles, was Ihr über Programmierung und Programmiersprachen wißt.
macht mich irgendwie stutzig. Da Python und C jetzt ja nicht "so" weit auseinander liegen, muss ich wohl auch vergessen.
Wie sagte Yoda so schön? You must unlearn what you have learned. Funktionaler Programmierung liegt ein anderes Ausführungskonzept zugrunde. Wie Blackjack schon schrieb: Es gibt kein Vorher und Nachher, es wird nichts sequentiell ausgeführt sondern Ausdrücke werde auf Werte nach gewissen Regeln reduziert.

Variablen in Haskell (und anderen funktionalen Sprachen wie z.B. Erlang) können nur einmal gebunden werden und sind danach unveränderlich. Alle Anweisungen wie `i = i + 1` sind unmöglich. Schleifen (for, while) gibt es nicht. Streng genommen auch kein `if` für Bedingungen. Dies ist nur syntaktischer Zucker. Bei Haskell werden zudem Ausdrücke erst dann ausgewertet, wenn sie benötigt werden. Das ist fundamental anders als bei den üblichen "call by value"-Sprachen wie Python, C, usw. In Haskell ist z.B. das Äquivalent zu

Code: Alles auswählen

def ones(): return (1,) + ones()
kein Problem, das in Python eine (rekursive) Endlosschleife ist. Python braucht ein zusätzliches syntaktisches Konstrukt des Generators, um etwas ähnliches wie in Haskell zu realisieren:

Code: Alles auswählen

def ones():
  while True:
    yield 1
Wenn man sich z.B. diese einfach Haskell Funktion anschaut

Code: Alles auswählen

sq(n)=n*n
, dann ist das doch das selbe wie

Code: Alles auswählen

def sq(n): return n*n
oder?
Jein. Für einstellige Funktionen gilt das noch, doch allgemein benutzt Haskell "currying", um eigentlich mehrstellige Funktionen in mehrere jeweils wieder einstellige Funktionen zu verwandeln. Etwas wie `add x y = ...` definiert eigentlich zwei Funktionen. Die erste Funktion bekommt ein Argument und liefert eine Funktion, die dann ein weiteres Argument bekommen kann, um schließlich die Addition (oder was auch immer `add` bedeuten könnte) durchzuführen. In Python wäre das dann dies:

Code: Alles auswählen

def add(x):
  def inner_add(y):
    return x + y
  return inner_add
und man kann das mit `add(3)(4)` dann aufrufen, was einem `add 3 4` in Haskell entsprechen würde.

Stefan
Antworten