再帰がなくてループができるか!!!!

SICP読書会にて、再帰なしでループができるか、という話題がでていたので、「継続つかえばできるんじゃないすかね」とか適当に発言してみた。

んで、さっき適当に考えながら書いてみた。0から9までをprintするというもの。

(let1 i 0
  (let/cc cc
    ((call/cc call/cc)
     (lambda (x)
       (if (= i 10)
	   (cc #t)
	   (begin (print i)
		  (set! i (+ i 1))
		  (x x)
		  ))))))

なんかよくわからないけど、(call/cc call/cc)の値が継続で、それに引数でxをわたすと (x x) という式が評価されるらしい。そこに適当な無名関数ほうりこめばいいよねー、そんで終了条件で一番上の継続呼べばいいよねーとか適当に書いたら動いた。けどこれって(x (x (x ... (x x)))) という構造だから結局再帰じゃねーか! とおもった。

どうなんだろう。このコードの解釈がこれであっているのかどうかわからない。自分でも意味がわからないのに動くコードをはじめて書いた気がする。。。ツッコミ希望。



追記

某天才プログラマ上野氏によるRubyコード

#!/usr/bin/ruby
 
def countten
  cont = nil
  i = 1
  callcc { |c| cont = c }
  p i
  i += 1
  cont.call if i <= 10
end
 
countten

それをSchemeに焼きなおした

(let ((loop ()) (i 0))
  (begin
    (let/cc cc (set! loop cc))
    (print i)
    (set! i (+ i 1))
    (if (< i 10)
	(loop 'dummy)
	'end)))