2006-05-16
■ list* 
list*と同じ機能を持つmylist*という関数を定義しました(練習)。
(mylist* 1 2 3) #=> (1 2 . 3) (mylist* 1) #=> 1 (mylist*) #=> ()
結城のプログラムは以下です。
(define (mylist* . xs) (cond ((null? xs) '()) ((null? (cdr xs)) (car xs)) (else (cons (car xs) (apply mylist* (cdr xs))))))
疑問:任意個数の引数を渡すとき、applyを使うしかないのでしょうか。たとえば(mylist* . (cdr xs)) みたいな感じにできないものかと。
追記:shiroさんからコメントをいただきました。「applyが「任意個数の引数を渡すプリミティブ」だと考えた方が良いでしょう」とのこと。なるほど、なるほど。いつもありがとうございます。
追記:適用可能なオブジェクトは微妙に関連しそうな話題。参考:object-apply と reader macro
■ define-syntax でユニットテスト 
tomapdさんが、define-syntax でユニットテストというエントリで、マクロの素敵な使い方をご紹介している。なるほど、なるほど。重複している部分を見つけ、さくりとマクロ化できたら楽しそうですね。
■ 自然対数の底e 
自然対数の底eを計算してみます。特に工夫なし。
(use srfi-42) (define (factorial n) (cond ((<= n 0) 1) (else (* n (factorial (- n 1)))))) (define (approx-e n) (cond ((< n 0) 0) (else (+ (/ 1 (factorial n)) (approx-e (- n 1)))))) (do-ec (: n 1 20) (print (approx-e n)))
実行結果です。
2 2.5 2.6666666666666665 2.708333333333333 2.7166666666666663 2.7180555555555554 2.7182539682539684 2.71827876984127 2.7182815255731922 2.7182818011463845 2.718281826198493 2.7182818282861687 2.7182818284467594 2.71828182845823 2.718281828458995 2.718281828459043 2.7182818284590455 2.7182818284590455 2.7182818284590455
トラックバック - http://sicp.g.hatena.ne.jp/hyuki/20060516
はい。「使うしかない」というよりも、applyが「任意個数の引数を渡すプリミティブ」だと考えた方が良いでしょう。何らかのsyntax sugarを作って、それをapplyを使う形に展開するということが考えられますが、元のSchemeではsyntax sugarもprefixになってしまうのであまり変わらないかと。S式の範囲を逸脱するなら少し見やすい形があるかもしれませんが。
なお (mylist* . (cdr xs)) は定義により (mylist* cdr xs) と同じなので、使えません。