「継続」と言う機能はScheme及びScheme系言語特有の機能だ(例外的に継続を持ってるプログラミング言語はRubyくらいしかないだろう・・・と言う事は「権威ある公式仕様」を持ってる言語で唯一「継続」を持ってるのはRubyだ、って事かもしんない)。
ただし、「継続受け渡しスタイル」(CPS)でプログラムを記述する、と言う事自体はラムダ式が使える言語なら基本何でも出来る。なんせ、「継続受け渡しスタイル」と厳つい名称は付いてるが、本質的にはCPSは単なる高階関数だから、だ。
従って、Racketで
(define (map1 proc xs k)
(if (null? xs)
(k '())
(map1 proc (cdr xs) (lambda (u)
(k (cons (proc (car xs)) u))))))
こう書ける物は、いつぞや見せたが、Pythonでも
def map1(proc, xs, k):
if xs == []:
return k([])
else:
return map1(proc, xs[1:], lambda u:
k([proc(xs[0])] + u))
と書ける。
当然、OCamlでも記述可能だ。
let rec map1 proc xs k = match xs with
[] -> k []
| first::rest -> map1 proc rest (fun u -> k ((proc first)::u))
Pythonのラムダ式はreturnが要らないし、LispやOCamlは「値を返す」仕様になってるからいいが、割にJavaScriptはマジメで、無名関数でもreturnが入らないとならない。
function map1(proc, xs, k) {
if (!xs.length) {
return k([]);
} else {
return map1(proc, xs.slice(1), (u) => {return k([proc(xs[0])].concat(u))});
}
}
Rubyもちとメンド臭い。枠組みは同じだし、基本「必ず返り値を返す」仕様を持ってるんだが、メソッドを呼び出す際にはcallが必要になる。
def map1(proc, xs, k)
if xs.empty?
k.call([])
else
map1(proc, xs[1..-1], -> (u) {k.call([proc.call(xs[0])] + u)})
end
end