Diskussion:Continuation-Passing Style

aus Wikipedia, der freien Enzyklopädie

return-Anweisung

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)

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

Stacktiefe

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)

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

Verständlichkeit der Erklärung und des Beispiels

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)

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)

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)
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)

Reformulierung der Beispiele in Haskell

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)

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)
scala können wohl nicht genügend leser, aber javascript klingt gut! -- 22:48, 9. Jan. 2011 (CET)
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)
Mal weiter dran rumgeschraubt. Im Übrigen Anschluss an Vorredner. --Daniel5Ko 23:29, 9. Jan. 2011 (CET)
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)

Visitor pattern

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))

Alte Notizen zu einem Rewrite des Artikels

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)