2010/03/12

TSS rember-beyond-first, rember-up-to-last, let/cc, call/cc

let/cc ・・・、これは便利。

極端に言うとただのジャンプです。でもなんというか goto や break, continue, throw などのジャンプ文を知った時は別段感動などありませんが、let/cc の方は衝撃というか夢がヒロガリングというか・・・・。左手で字を書くような妙な感覚です。

パラダイムがシフトしそうなのかもしれません。

初めてクロージャを実用的な意味で理解した時とか、interface や abstract クラスの存在意義を初めて理解した時とか、そういうのと似た、いわゆる「悟り体験」的な感覚でしょうか。

let/cc は call/cc (call-with-current-continutation)により実現されていますが、The Seasoned Schemer では call/cc はまだほとんど出てきません。
しばらく let/cc が続きそう。
少し大げさになった気もしますが、取り合えず以下コード。
; rember
(use srfi-1)
; fold
(define (multirember a lat)
(fold (lambda (e acc)
(if (eq? e a)
acc
(cons e acc)))
'()
lat))
(multirember 'a '(a b c a b c))
; -> (c b c b)
; The Little Schemer
(define rember
(lambda (a lat)
(cond ((null? lat) '())
((eq? a (car lat))(cdr lat))
(else (cons (car lat)
(rember a (cdr lat)))))))
(rember 'a '(a b c a b c))
; -> (b c a b c)
; The Seasoned Schemer
(define rember
(letrec
((R (lambda (lat)
(cond ((null? lat) '())
((eq? a (car lat))(cdr lat))
(else (cons (car lat)
(rember (cdr lat))))))))
(R lat)))
(rember 'a '(a b c a b c))

; rember-beyond-first
; (rember-beyond-first 'roots '(noodles spaghetti spatzle bean-thread roots potatoes yam others rice))
; -> (noodles spaghetti spatzle bean-thread)
; fold
(define (rember-beyond-first a lat)
(reverse
(let/cc hop
(fold (lambda (e acc)
(if (eq? e a)
(hop acc)
(cons e acc)))
'()
lat))))
(rember-beyond-first 'roots '(noodles
spaghetti spatzle bean-thread
roots
potatoes yam
others rice))
; -> (noodles spaghetti spatzle bean-thread)
(rember-beyond-first 'others '(noodles
spaghetti spatzle bean-thread
roots
potatoes yam
others
rice))
; -> (noodles spaghetti spatzle bean-thread roots potatoes yam)
(rember-beyond-first 'sweetthing '(noodles
spaghetti spatzle bean-thread
roots
potatoes yam
others
rice))
; -> (noodles spaghetti spatzle bean-thread roots potatoes yam others rice)
; The Seasoned Schemer
(define rember-beyond-first
(lambda (a lat)
(letrec
((R (lambda (lat)
(cond
((null? lat)(quote ()))
((eq? (car lat) a)
(quote ()))
(else (cons (car lat)
(R (cdr lat))))))))
(R lat))))
(rember-beyond-first 'roots '(noodles
spaghetti spatzle bean-thread
roots
potatoes yam
others rice))
; -> (noodles spaghetti spatzle bean-thread)
(rember-beyond-first 'others '(noodles
spaghetti spatzle bean-thread
roots
potatoes yam
others
rice))
; -> (noodles spaghetti spatzle bean-thread roots potatoes yam)
(rember-beyond-first 'sweetthing '(noodles
spaghetti spatzle bean-thread
roots
potatoes yam
others
rice))
; -> (noodles spaghetti spatzle bean-thread roots potatoes yam others rice)

; rember-up-to-last
; The Seasoned Schemer
(define rember-up-to-last
(lambda (a lat)
(let/cc skip
(letrec
((R (lambda (lat)
(cond
((null? lat)(quote ()))
((eq? (car lat) a)
(skip (R (cdr lat))))
(else (cons (car lat)
(R (cdr lat))))))))
(R lat)))))
(rember-up-to-last 'cookies '(cookies
chocolate mins
caramel delight ginger snaps
desserts
chocolate mousse
vannilla ice cream
German chocolate cake
more cookies
gingerbreaddman chocolate
chips brownies))
; -> (gingerbreaddman chocolate chips brownies)


The Seasoned Schemer

0 件のコメント:

コメントを投稿