(let () a b . . .)
コードの方↓は、なんともゴチャゴチャしてしている。
ところで明日は 9LISP。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; letcc leftmost | |
; The Seasoned Schemer | |
(define leftmost | |
(lambda (l) | |
(let/cc skip | |
(lm l skip)))) | |
(define lm | |
(lambda (l out) | |
(cond | |
((null? l)(quote ())) | |
((atom? (car l))(out (car l))) | |
(else (let () | |
(lm (car l) out) | |
(lm (cdr l) out)))))) | |
(leftmost '(((a) b (c)))) | |
; -> a | |
; again | |
(define leftmost | |
(letrec | |
((lm (lambda (l out) | |
(cond | |
((null? l)(quote ())) | |
((atom? (car l)) | |
(out (car l))) | |
(else | |
(let () | |
(lm (car l) out) | |
(lm (cdr l) out))))))) | |
(lambda (l) | |
(let/cc skip | |
(lm l skip))))) | |
(leftmost '(((a) b (c)))) | |
; again | |
(define leftmost | |
(lambda (l) | |
(letrec | |
((lm (lambda (l out) | |
(cond | |
((null? l)(quote ())) | |
((atom? (car l)) | |
(out (car l))) | |
(else | |
(let () | |
(lm (car l) out) | |
(lm (cdr l) out))))))) | |
(let/cc skip | |
(lm l skip))))) | |
(leftmost '(((a) b (c)))) | |
; again | |
(define leftmost | |
(lambda (l) | |
(let/cc skip | |
(letrec | |
((lm (lambda (l out) | |
(cond | |
((null? l)(quote ())) | |
((atom? (car l)) | |
(out (car l))) | |
(else (let () | |
(lm (car l) out) | |
(lm (cdr l) out))))))) | |
(lm l skip))))) | |
(leftmost '(((a) b (c)))) | |
; again | |
(define leftmost | |
(lambda (l) | |
(let/cc skip | |
(letrec | |
((lm (lambda (l) | |
(cond | |
((null? l)(quote ())) | |
((atom? (car l)) | |
(skip (car l))) | |
(else (let () | |
(lm (car l)) | |
(lm (cdr l)))))))) | |
(lm l))))) | |
(leftmost '(((a) b (c)))) | |
(define (leftmost l) | |
(let/cc skip | |
(letrec | |
((lm (lambda (l) | |
(if (null? l) | |
'() | |
(let ((kar (car l))) | |
(if (list? kar) | |
(let () | |
(lm kar) | |
(lm (cdr l))) | |
(skip kar))))))) | |
(lm l)))) | |
(leftmost '(((a) b (c)))) | |
; named let | |
(define (leftmost l) | |
(let/cc skip | |
(let loop ((l l)) | |
(if (null? l) | |
'() | |
(let ((kar (car l))) | |
(if (list? kar) | |
(let () ; begin | |
(loop kar) | |
(loop (cdr l))) | |
(skip kar))))))) | |
(leftmost '(((a) b (c)))) | |
(leftmost '((() (a) b (c))) |
Scheme の begin には面白い特徴があります。
返信削除新しいスコープを作らないのです。
例えば ↓ こんなコードでエラーが起こりません。
(begin (define a 1))
(display a)
a はトップレベルで定義されたことになります。
記事中のコードは begin と let のどちらを使っても問題ないと思いますが、同等と考えていると不意につまづくこともあるかもしれません。
begin のこの性質はマクロを書くときに必要になることがあります。
ご指摘ありがとうございます!
返信削除全然、等価じゃないみたいですね^^;