Hier ausnahmsweise keine Frage von mir, sondern nur ein Link, da er mir interessant erscheint.
Im pdf ab Seite 36.
http://velociraptor.mni.fh-giessen.de/~ ... PP/npp.pdf
wen funktionale Programmierung interessiert lambda
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Um, 36 Seiten (mit Inhaltsverzeichnis) in das PDF hinein hat man schon was von Prolog, Python, C++, XSLT und dem Lambda-Kalkuel gehoert. Sieht fuer mich eher nach einem Sammelsurium von Sachen aus die fuer den Autor cool sind, als nach einem echten Konzept. Ich hab danach abgebrochen.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@zikzak: Das sieht aber alles nach funktionaler Programmierung mit Python-Syntax aus, allerdings ohne Rücksicht darauf ob das überhaupt in Python auf diese Weise eine gute Idee ist.
Rekursion sollte man zum Beispiel nur einsetzen wenn es sich tatsächlich um ein rekursives Problem handeln und nicht um einfache Schleifen zu vermeiden. Python hat keine Optimierung für Endrekursion und ein Rekursionslimit in das man schnell reinlaufen kann, wenn man wirklich so programmiert wie es dort gezeigt wird. Das Programm bricht dann einfach mit einer Ausnahme ab wo es mit einer Schleife problemlos funktioniert hätte.
Auch wenn das mit den lokalen Funktionen und Closures funkioniert, würde man heutzutage wohl eher `functools.partial()` verwenden. Den Begriff „curry” würde ich bei dem Beispiel für falsch halten, denn das wäre IMHO wenn man eine Funktion mit n Argumenten hat und eines davon bindet um eine Funktion mit n-1 Argumenten zu bekommen. In dem Beispiel haben wir aber eine Funktion mit einem Argument die eine Funktion mit zwei Argumenten zurückgibt.
Die gezeigten `Map()`- und `Reduziere()`-Implementierungen sind superineffizient und skalieren nicht. Python und Pythons Listen sind nicht die richtigen Mittel um in diesem Stil zu programmieren.
Auf Seite 45 unten werden Sequenzen und Listen genau umgekehrt beschrieben wie ich das bei Python sehen würde. Sequenzen sind in Python ein allgemeines Protokoll, also eine Sammlung von Eigenschaften und Verhalten die eine Sequenz ausmachen. Dazu gehören eine Länge und Indexzugriff über Zahlen von 0 bis zur Länge - 1. Sequenztypen sind zum Beispiel Tupel, Listen, oder Zeichenketten. Bei Sequenzen kann man in Python allgemein also gar nicht sagen ob die Elemente gleichen (duck) Typs sein sollten oder nicht. Bei Listen sollten sie es, im Kontrast zu dem was der Text behauptet, während Tupel eher für Werte mit unterschiedlichen Bedeutungen und damit potentiell auch Typen vorgesehen sind. Und bei Zeichenketten *müssen* alle Elemente sogar vom selben Typ sein.
Die Lisp-Listen-Funktionen die in Python nachgebastelt werden, sind dann wieder ganz gruselig ineffizient. Ausser `car()` natürlich.
Auf Seite 49 unten steht Unsinn bezüglich OOP. Natürlich sind globale Variablen nicht die einzige Möglichkeit sich Zustand über Funktionsaufrufe in Sprachen wie C zu merken. Man kann ganz einfach bei jedem Aufruf eine Datenstruktur mit dem Zustand übergeben. Das ist *ein* zusätzliches Argument. In Python macht man das syntaktisch mit dem ersten Argument bei Methoden. Das ist ein zu vernachlässigender Mehraufwand und das wurde schon seit Ewigkeiten in C-Programmen benutzt. Dafür braucht man keine spezielle Unterstützung der Programmiersprache. *Die* braucht man für Vererbung, denn da wird handgeschriebenes C welches das nachbildet eher unangenehm zu nutzen.
Bei Seite 52 wird es dann lustig. Hier wiederspricht sich das Paper selbst, denn wäre ein Zugriff tatsächlich nur auf Variablen von *aktiven* Funktionen möglich, dann hätte das Closure bei dem „curry”-Beispiel von weiter vorne nicht funktionieren dürfen, denn `f` ist dort eine Variable einer umgebenden Funktion die bereits abgearbeitet ist, wenn die verschachtelte und zurückgegebene Funktion später aufgerufen wird. Das dürfte ja nicht möglich sein wenn `f` als lokale Variable auf dem Stack liegen würde. Das Python den schreibenden Zugriff auf solche „Zwischenbereiche” verbieten *muss* ist Unsinn, was sich leicht dadurch wiederlegen lässt, dass es das ``nonlocal``-Schlüsselwort gibt, was genau das möglich macht.
Auf seite 67 wird folgendes als der einfachste Weg beschrieben um `x` in `g()` zu binden:
Dem würde ich widersprechen:
Das sieht mir übersichtlicher aus und ist auch (vor `functools.partial()`) der Weg gewesen, den man am häufigsten in solchen Fällen gesehen hat.
Abschnitt 5.1: „Rekursion: Essenz funktionaler Programme” — ja, und in dieser Rolle in Python nicht brauchbar. Fast alle rekursiven Funktionen in dem Paper sind *sauschlechtes* Python. Nicht nachmachen Kinder.
Der Text mag interessant sein um funktionale Programmierung kennenzulernen, ist aber IMHO grossteils ungeeignet um das auf Python anzuwenden. Dementsprechend unsinnig finde ich auch den Einsatz von Python in dem Text. Scheme oder Clojure würden Lesern hier deutlich mehr bringen, weil sie dann das gelernte auch direkt praktisch anwenden können. Einzig Iteratoren und Generatoren sind Python-spezifisch, da ist dann aber die Rekursion wieder mehr als gruselig. Bei der rekursiv definierten Generatorfunktion für Fibonacci-Zahlen war ich kurz davor in irres Gelächter auszubrechen.
Rekursion sollte man zum Beispiel nur einsetzen wenn es sich tatsächlich um ein rekursives Problem handeln und nicht um einfache Schleifen zu vermeiden. Python hat keine Optimierung für Endrekursion und ein Rekursionslimit in das man schnell reinlaufen kann, wenn man wirklich so programmiert wie es dort gezeigt wird. Das Programm bricht dann einfach mit einer Ausnahme ab wo es mit einer Schleife problemlos funktioniert hätte.
Auch wenn das mit den lokalen Funktionen und Closures funkioniert, würde man heutzutage wohl eher `functools.partial()` verwenden. Den Begriff „curry” würde ich bei dem Beispiel für falsch halten, denn das wäre IMHO wenn man eine Funktion mit n Argumenten hat und eines davon bindet um eine Funktion mit n-1 Argumenten zu bekommen. In dem Beispiel haben wir aber eine Funktion mit einem Argument die eine Funktion mit zwei Argumenten zurückgibt.
Die gezeigten `Map()`- und `Reduziere()`-Implementierungen sind superineffizient und skalieren nicht. Python und Pythons Listen sind nicht die richtigen Mittel um in diesem Stil zu programmieren.
Auf Seite 45 unten werden Sequenzen und Listen genau umgekehrt beschrieben wie ich das bei Python sehen würde. Sequenzen sind in Python ein allgemeines Protokoll, also eine Sammlung von Eigenschaften und Verhalten die eine Sequenz ausmachen. Dazu gehören eine Länge und Indexzugriff über Zahlen von 0 bis zur Länge - 1. Sequenztypen sind zum Beispiel Tupel, Listen, oder Zeichenketten. Bei Sequenzen kann man in Python allgemein also gar nicht sagen ob die Elemente gleichen (duck) Typs sein sollten oder nicht. Bei Listen sollten sie es, im Kontrast zu dem was der Text behauptet, während Tupel eher für Werte mit unterschiedlichen Bedeutungen und damit potentiell auch Typen vorgesehen sind. Und bei Zeichenketten *müssen* alle Elemente sogar vom selben Typ sein.
Die Lisp-Listen-Funktionen die in Python nachgebastelt werden, sind dann wieder ganz gruselig ineffizient. Ausser `car()` natürlich.
Auf Seite 49 unten steht Unsinn bezüglich OOP. Natürlich sind globale Variablen nicht die einzige Möglichkeit sich Zustand über Funktionsaufrufe in Sprachen wie C zu merken. Man kann ganz einfach bei jedem Aufruf eine Datenstruktur mit dem Zustand übergeben. Das ist *ein* zusätzliches Argument. In Python macht man das syntaktisch mit dem ersten Argument bei Methoden. Das ist ein zu vernachlässigender Mehraufwand und das wurde schon seit Ewigkeiten in C-Programmen benutzt. Dafür braucht man keine spezielle Unterstützung der Programmiersprache. *Die* braucht man für Vererbung, denn da wird handgeschriebenes C welches das nachbildet eher unangenehm zu nutzen.
Bei Seite 52 wird es dann lustig. Hier wiederspricht sich das Paper selbst, denn wäre ein Zugriff tatsächlich nur auf Variablen von *aktiven* Funktionen möglich, dann hätte das Closure bei dem „curry”-Beispiel von weiter vorne nicht funktionieren dürfen, denn `f` ist dort eine Variable einer umgebenden Funktion die bereits abgearbeitet ist, wenn die verschachtelte und zurückgegebene Funktion später aufgerufen wird. Das dürfte ja nicht möglich sein wenn `f` als lokale Variable auf dem Stack liegen würde. Das Python den schreibenden Zugriff auf solche „Zwischenbereiche” verbieten *muss* ist Unsinn, was sich leicht dadurch wiederlegen lässt, dass es das ``nonlocal``-Schlüsselwort gibt, was genau das möglich macht.
Auf seite 67 wird folgendes als der einfachste Weg beschrieben um `x` in `g()` zu binden:
Code: Alles auswählen
x = 5
g = (lambda x : lambda y : x + y)(x)
Code: Alles auswählen
x = 5
g = lambda y, x=x : x + y
Abschnitt 5.1: „Rekursion: Essenz funktionaler Programme” — ja, und in dieser Rolle in Python nicht brauchbar. Fast alle rekursiven Funktionen in dem Paper sind *sauschlechtes* Python. Nicht nachmachen Kinder.

Der Text mag interessant sein um funktionale Programmierung kennenzulernen, ist aber IMHO grossteils ungeeignet um das auf Python anzuwenden. Dementsprechend unsinnig finde ich auch den Einsatz von Python in dem Text. Scheme oder Clojure würden Lesern hier deutlich mehr bringen, weil sie dann das gelernte auch direkt praktisch anwenden können. Einzig Iteratoren und Generatoren sind Python-spezifisch, da ist dann aber die Rekursion wieder mehr als gruselig. Bei der rekursiv definierten Generatorfunktion für Fibonacci-Zahlen war ich kurz davor in irres Gelächter auszubrechen.
- diesch
- User
- Beiträge: 80
- Registriert: Dienstag 14. April 2009, 13:36
- Wohnort: Brandenburg a.d. Havel
- Kontaktdaten:
Ist wohl ein Skript zu einer Vorlesung über Nichtprozedurale Programmierung.cofi hat geschrieben:Um, 36 Seiten (mit Inhaltsverzeichnis) in das PDF hinein hat man schon was von Prolog, Python, C++, XSLT und dem Lambda-Kalkuel gehoert. Sieht fuer mich eher nach einem Sammelsurium von Sachen aus die fuer den Autor cool sind, als nach einem echten Konzept. Ich hab danach abgebrochen.
Dem Datum nach bezieht es sich wohl auf Python 2.3
Nach kurzem Querlesen halte ich es für ganz interessant, wenn man sich allgemein mit nichtprozeduraler Programmierung beschäftigen will, aber nur eingeschränkt sinnvoll, wenn man funktionale Programmierung in Python lernen will.
http://www.florian-diesch.de