Wie üblich schien es für mindestens eine Person (mich) nützlich zu sein, also der Continuation-Passing-Stil (CPS) jeder Sprache. Die Beispielbeschreibung von ist als Artikel zusammengefasst.
Ersetzen Sie im interaktiven Modus "x" durch 10 und lassen Sie dann "x + 20" auswerten.
>>> x = 10
>>> x + 20
30
Wenn ich diese Programmbeschreibung in eine Datei umwandle und vom Python-Interpreter ausführen lasse, wird nichts angezeigt. Dies liegt daran, dass im interaktiven Modus (REPL) das als Ausdruck ausgewertete Ergebnis angezeigt wird, während in der Dateiausführung (Skript) eine solche Anzeige nicht durchgeführt wird.
C:\Users\hoge>type sample.py
x = 10
x + 20
C:\Users\hoge>python sample.py
C:\Users\hoge>
Wenn Sie das Bewertungsergebnis durch Ausführen der Datei anzeigen möchten, müssen Sie es beispielsweise mit "Drucken" anzeigen, nachdem Sie das Bewertungsergebnis erhalten haben.
C:\Users\hoge>type sample.py
x = 10
print(x + 20)
C:\Users\hoge>python sample.py
30
C:\Users\hoge>
Betrachten Sie hier bei der Beschreibung als Ausdruck einen Mechanismus, bei dem die Funktion angegeben werden muss, die das Bewertungsergebnis verarbeitet. Das Folgende ist ein Beispiel für die Definition einer Funktion "cadd20", die aufgerufen wird, indem das Bewertungsergebnis als Argument an die Funktion "f" übergeben wird, nachdem "x + 20" ausgewertet wurde, und "print" für "f" angegeben wird. ..
C:\Users\hoge>type sample.py
def cadd20(x, f): f(x + 20)
x = 10
cadd20(x, print)
C:\Users\hoge>python sample.py
30
C:\Users\hoge\python>
Auf diese Weise lautet die Programmiermethode, die einen Mechanismus zum Festlegen der Prozedur für die Verarbeitung des Ergebnisses im Voraus voraussetzt, "[Continuous Passing Style](https://ja.wikipedia.org/wiki/%E7%B6%99%]. E7% B6% 9A% E6% B8% A1% E3% 81% 97% E3% 82% B9% E3% 82% BF% E3% 82% A4% E3% 83% AB) “(Continuation-Passing-Stil, CPS) ). Dieser Stil wurde auf verschiedene Implementierungen angewendet, einschließlich unbewusster Formen.
try
(aufzurufende Prozedur) und Except
(anzugebende Prozedur)Es ist einfach, eine Funktion in CPS zu konvertieren, aber ein gewisser Einfallsreichtum ist erforderlich, um die konvertierte Funktion zu verwenden. Hier werden die Konvertierung vorhandener Funktionen in CPS und Verwendungsbeispiele gezeigt (der Hauptteil dieses Spickzettel).
from operator import add, sub, mul
# func(x, y) = (x + y) * (x - y)
def func(x, y): return mul(add(x, y), sub(x, y))
print(func(10, 20)) # => -300
def cps(f):
def cps(x, y, c): return c(f(x, y))
return cps
cps(add)(10, 20, print) # => 30
def cfunc(x, y, c):
return cps(add)(x, y, lambda c1: # x + y -> c1
cps(sub)(x, y, lambda c2: # x - y -> c2
cps(mul)(c1, c2, c))) # c1 * c2 -> c
cfunc(10, 20, print) # => -300
Scheme(Gauche,Guile)
; func(x, y) = (x + y) * (x - y)
(define (func x y) (* (+ x y) (- x y)))
(display (func 10 20)) ; => -300
(define (cps f) (lambda (x y c) (c (f x y))))
((cps +) 10 20 display) ; => 30
(define (cfunc x y c)
((cps +) x y (lambda (c1) ; x + y -> c1
((cps -) x y (lambda (c2) ; x - y -> c2
((cps *) c1 c2 c)))))) ; c1 * c2 -> c
(cfunc 10 20 display) ; => -300
Ruby(CRuby)
# func(x, y) = (x + y) * (x - y)
def func1(x,y) (x+y)*(x-y) end
p func1(10,20) # => -300
add = -> x,y { x+y }
sub = -> x,y { x-y }
mul = -> x,y { x*y }
prn = -> x { p x }
cps = -> f { -> x,y,c { c.(f.(x,y)) } }
cps[add][10,20,prn] # => 30
cfunc = -> x,y,c {
cps.(add).(x, y, -> c1 { # x + y -> c1
cps.(sub).(x, y, -> c2 { # x - y -> c2
cps.(mul).(c1,c2,c) }) }) # c1 * c2 -> c
}
cfunc[10,20,prn] # => -300
JavaScript(Node.js)
// func(x, y) = (x + y) * (x - y)
function func1(x,y) { return (x+y)*(x-y) }
console.log(func1(10,20)) // => -300
add = (x,y) => x+y
sub = (x,y) => x-y
mul = (x,y) => x*y
cps = f => (x,y,c) => c(f(x,y))
cps(add)(10,20,console.log) // => 30
cfunc = function(x,y,c) {
return cps(add)(x, y, c1 => // x + y -> c1
cps(sub)(x, y, c2 => // x - y -> c2
cps(mul)(c1,c2,c))) // x * y -> c
}
cfunc(10,20,console.log) // => -300
Recommended Posts