Diskussion:Continuation-Passing Style

Letzter Kommentar: vor 10 Jahren von Λx.x in Abschnitt Alte Notizen zu einem Rewrite des Artikels

return-Anweisung

Bearbeiten

Die return-Anweisung ist im direkten Stil nicht unbedingt erforderlich. Es gibt etliche Programmiersprachen, in denen am Ende eines Funktionsrumpfs statt einer Anweisung ein Ausdruck steht, der das Ergebnis liefert, obgleich sie nicht CPS verwenden.
Ich schlage deshalb vor, den Satz "Daher ist ein eigenes return-Statement notwendig, um zum Aufrufer zurückzukehren." ersatzlos zu streichen. -- Joachim Durchholz 13:21, 7. Mär. 2008 (CET)Beantworten

erledigt -- 22:05, 13. Jul. 2009 (CEST)Beantworten

Stacktiefe

Bearbeiten

Der letzte Absatz ist in einem Detail falsch: der Stacküberlauf findet nur statt, wenn die Sprachimplementation keine Tail Call Optimization (TCO) durchführt.
Manche Systeme tun das allerdings durchaus. Im Fall von LLVM (einem Compiler-Toolkit) wird die Kombination aus CPS und TCO sogar unmittelbar unterstützt, so dass keine "Krücken" wie das explizite Abräumen des Stacks per Exception nötig ist.
-- Joachim Durchholz 13:24, 7. Mär. 2008 (CET)Beantworten

stimmt, hab's eingefügt. -- 22:05, 13. Jul. 2009 (CEST)Beantworten

Verständlichkeit der Erklärung und des Beispiels

Bearbeiten

Obwohl ich Informatik studiere und auch Scheme kenne verstehe ich doch nicht, was gemeint ist. Möglicherweise kann man es besser erklären? Da ich nicht weiß was eine Continuation sein soll hilft mir auch das Beispiel nicht weiter. -- Jonas Gerdel 23:03, 7. Okt. 2008 (CET)Beantworten

Vielleicht die Einleitung so oder so ähnlich:

Im CPS liefert eine Funktion keinen Wert zurück, wie in den meisten Programmiersprachen üblich. Stattdessen übergibt sie den Wert an eine "Nachfolgerfunktion", die Continuation.
Der Ausdruck, der den Aufruf einer CPS-Funktion enthält, wird gewissermaßen von innen nach außen gekrempelt: Statt
a + f (x) + b
steht dann
f (x, a + _ + c)
( a + _ + c ist hier Pseudocode für die Funktion, die a, einen Parameter und c aufaddiert).

Ich mag den Absatz nicht, der a + _ + c erklärt, wenn jemand einen Einzeiler dafür hat, dass jemand eine anonyme Funktion als Teil eines Ausdrucks hinschreibt, immer her damit.

Danach dann Inhaltsverzeichnis und ein Abschnitt mit der kompletten technischen Definition, einer zur Implementationsdetails (insbesondere dass TCO erforderlich ist), Verwendung des Idioms in der Programmierung (Event Handler u.ä.), Nutzung als Implementationstechnik (CPS als eine von mehreren Techniken zur Umgehung zu knapp bemessener Hardwarestacks).

Ich kenne leider nur das Konzept an sich, nicht seinen praktischen Einsatz, und bin daher nicht unbedingt der beste Autor für den Artikel.

-- Joachim Durchholz 10:43, 24. Apr. 2009 (CEST)Beantworten

Die folgenden Sätze geben wieder, wie ich mir selbst Continuations erkläre, vielleicht sind sie ja als Einführung geeignet:
In den meisten Programmiersprachen wird nach Beendigung einer Funktion ihr Ergebnis und der Kontrollfluss an den Aufrufer zurückgegeben. Es wäre aber auch denkbar, der Funktion eine "Nachfolgefunktion" zu übergeben, die an Stelle des Aufrufers das Ergebnis erhalten soll. Anstatt zum Aufrufer zurückzukehren, übergibt die Funktion ihr Ergebnis dieser Nachfolgefunktion. Die Funktionen bilden gewissermaßen eine Kette. Statt von einer Nachfolgefunktion kann man auch von einer "Fortführung" sprechen, das deutsche Wort für Continuation. Der CPS ist ein Programmierstil, der dieser Vorgehensweise folgt.
Ich bin selbst gerade erst dabei, Continuations zu verstehen und bin daher nicht sicher, ob dieses Verständnis korrekt ist. Das im Artikel angegebene Scheme-Beispiel verstehe ich jedenfalls immer noch nicht.
Ein Wikipedia-Profi bin ich auch nicht, aber meiner Meinung nach solltest du deine Vorschläge ruhig umsetzen. An echten Experten zum Thema scheint es ja zu mangeln, wenn man das Alter der Diskussionsbeiträge ansieht. Wenn dann doch einer vorbeikommt, kann er ja weiter verbessern. -- RubenH 16:25, 4. Jun. 2009 (CEST)Beantworten
Ich habe diese Erklärung jetzt eingebaut, nachdem ich sie in ähnlicher Form ungestraft in einer Prüfung angebracht habe. Sie ist zwar wissenschaftlich nicht 100% präzise, dafür aber sicher besser verständlich als der Satz, der vorher dort stand. -- RubenH 17:04, 1. Okt. 2009 (CEST)Beantworten

Reformulierung der Beispiele in Haskell

Bearbeiten

Was haltet ihr davon, dass man die Beispiele in Haskell formuliert, da dieses (meiner Meinung nach) leichter zu lesen ist? Wir hätten dann sowas:

Anstatt:

(define (fakultaet n)
 (if (= n 0)
     1
     (* n (fakultaet (- n 1)))))

hätte man:

fakultaet :: Integer -> Integer
fakultaet 0 = 1
fakultaet n = n * fakultaet (n-1)

Was meiner Meinung nach für den unbedarften Leser wesentlich einfacher zu lesen ist. Weiteres Beispiel:

define (fakultaet-cps n k)
 (if (= n 0)
     (k 1)
     (fakultaet-cps (- n 1) (lambda (zwischenergebnis) (k (* n zwischenergebnis))))))

versus

fakultaet_cps :: Integer -> (Integer -> a) -> a
fakultaet_cps 0 f = f 1
fakultaet_cps n f = fakultaet_cps (n-1) ( \zwischenergebnis -> f (n * zwischenergebnis))
-- Die letze Zeile würde ich persönlich so formulieren, dass währe aber nicht so einfach verständlich:
fakultaet_cps n f = fakultaet_cps (n-1) (f . (*n))

Ich hätte gerne Meinungen dazu, am besten von Leuten die weder LISP noch Haskell können, also einen neutralen Blick auf die Syntax haben. --FUZxxlD|M|B 06:57, 9. Jan. 2011 (CET)Beantworten

Problematisch an der Verwendung von Haskell ist dessen nicht-Striktheit, die ja irgendwie implementiert werden muss. Das führt zu einem komplizierten Speicher-Performance-Modell, und irgend etwas über TCO zu sagen, wird damit eher seltsam bis falsch.
Wie wär's mit Scala (oder JavaScript! :D )? --Daniel5Ko 14:52, 9. Jan. 2011 (CET)Beantworten
scala können wohl nicht genügend leser, aber javascript klingt gut! -- 22:48, 9. Jan. 2011 (CET)Beantworten
spaßeshalber mal in JS übersetzt. wer tippfehler findet, darf sie behalten; für editwars um die formatierung stehe ich jederzeit zur verfügung. -- 23:05, 9. Jan. 2011 (CET)Beantworten
Mal weiter dran rumgeschraubt. Im Übrigen Anschluss an Vorredner. --Daniel5Ko 23:29, 9. Jan. 2011 (CET)Beantworten
Es ging mir weniger um die Sprache selbst, mehr um die Syntax, die auch ohne Haskell Kenntnisse sehr einfach zu lesen ist, da sie sich sehr stark an die mathematische Notation anlehnt. --FUZxxlD|M|B 08:04, 12. Jan. 2011 (CET) Edit: Das Javascript Beispiel ist so nicht schlecht, man merkt aber schon, dass die Javascript Syntax eher auf imperative Programme ausgelegt ist (zum Beispiel anhand der vielen Klammern). --FUZxxlD|M|B 08:06, 12. Jan. 2011 (CET)Beantworten

Visitor pattern

Bearbeiten

der Besucher weist einige parallelen zum CPS (ersetzt ihn jedoch nicht, da CPS deutlich verschachtelter sein kann ) auf ... ggf. kann man es auch darüber erklären. (PS: ein schönes Beispiel wäre hier auch die Ackermann Funktion) (nicht signierter Beitrag von 87.189.90.191 (Diskussion) 23:39, 23. Feb. 2013 (CET))Beantworten

Alte Notizen zu einem Rewrite des Artikels

Bearbeiten

Ich wollte vor Jahren (2008?) diesen Artikel neu schreiben, kam aus Faulheit und Mangel an Verständnis nicht dazu. Ich machte mir damals Notizen mit Mängeln, von denen inzwischen glücklicherweise der größte Teil bereinigt ist. Übrige Anstoßpunkte und was ich damals vermisste:

  • der Artikel behandelt zu sehr die umständliche von-Hand-Nutzung von CPS, während eher die Kompilation nach CPS und deren interne Nutzung in Transformationen interessant ist.
  • Implementation von CPS
  • konkrete Vorteile des internen Einsatzes
  • beziehung zu call/cc (first class goto?)

--id (Diskussion) 22:26, 2. Mai 2014 (CEST)Beantworten