list-tabulate
要素が n 個の list '(x y z) が与えられたときに、"," で連結された文字列を作る。n=3のときは、 "i32 %arg1, i32 %arg2, i32 %arg3" が欲しい(リストの中身は使っていない)。「(Common Lisp の)loop マクロ無しにどうやって '(1 2 3) を作るんだ?doか?」と思う。また CL の format なら "~{~a~^,~}" とか書けば","で連結できるが gauche の拡張された format にこの機能は無いようだ。string-join(http://practical-scheme.net/gauche/man/gauche-refj_48.html#IDX379)) を使うらしい。Gauche ユーザーリファレンスの「4. 基本的な構文 4.8 繰り返し」。do にはほとんど例が無く何となく「繰り返し」は嫌われていると感じる。
do は分かりにくいので named-let, map を使ってみる。いかにも素人っぽく冗長な気がする。
gosh> ((lambda (as) (let loop ((i 1) (res ())) (if (> i (length as)) (reverse res) (loop (+ i 1) (cons (format #f "i32 %arg~a" i) res))))) '(a b c)) ("i32 %arg1" "i32 %arg2" "i32 %arg3") gosh> (let ((i 1)) (map (lambda (as) (format #f "i32 %arg~a" i) (set! i (1+ i))) '(a b c))) *** ERROR: unbound variable: |1+| Stack Trace: _______________________________________ 0 (|1+| i) At line 42 of "(stdin)" gosh> (let ((i 1)) (map (lambda (as) (set! i (+ 1 i)) (format #f "i32 %arg~a" i)) '(a b c))) ("i32 %arg2" "i32 %arg3" "i32 %arg4") gosh> (let ((i 1)) (string-join (map (lambda (as) (set! i (+ 1 i)) (format #f "i32 %arg~a" i)) '(a b c)) ", ")) "i32 %arg2, i32 %arg3, i32 %arg4"
loop マクロが恋しい。某掲示板で見たばかりの「Yow! Loop macrosで検索するとたどりつくcomp.lang.schemeのloop投稿」に心が動くがこらえる。ようやく SRFI-1 iota と list-tabulate にたどりつく。これで一応シンプルに書ける、気がする。
gosh> (use srfi-1) #<undef> gosh> (list-tabulate 3 (lambda (i) (format #f "i32 %arg~a" i))) ("i32 %arg0" "i32 %arg1" "i32 %arg2")