メソッドチェイン風マクロ2
cutマクロみたいに「<>」でもいいかも.
http://mono.kmc.gr.jp/~yhara/d/?date=20080203#p02
これいいかも。
というわけで、メソッドチェイン風マクロで計算結果の挿入位置を<>で指示出来るようにしてみる。
補助マクロins
まず、補助マクロとしてリストの中の<>に指定した要素を挿入するマクロを作る
(define-syntax ins (syntax-rules (<>) ((_ x y) (ins x y ())) ((_ () y z) z) ((_ (<> x1 ...) y (z ...)) (ins (x1 ...) y (z ... y))) ((_ (x1 x2 ...) y (z ...)) (ins (x2 ...) y (z ... x1)))))
実行例
gosh> (ins (list 1 <> 2 <> 4) 0) (1 0 2 0 4) gosh> (macroexpand '(ins (list 1 <> 2 <> 4) 0)) (list 1 0 2 0 4)
おぼえがき
省略記号...は正規表現の*と似てる。1個以上の繰り返しは..*と書くのと同じように、(x1 x2 ...)と識別子が2つ必要。
テンプレート側では...の後ろにも要素が書けてappendと同じ事が出来る。
<>対応版chain
上記マクロを使ってchainの<>対応版を作る
(define-syntax chain (syntax-rules () ((_ e1) e1) ((_ e1 e2 e3 ...) (chain (ins e2 e1) e3 ...))))
実行例
gosh> (chain '(1 2 3) (cons 4 <>) (reverse <>) (map (cut * <> 2) <>)) (6 4 2 8)
あえて<>を使うcutを組み合わせてみたがちゃんと動いているようだ。
末尾挿入版chain
計算結果を一番前ではなくて一番後ろに挿入するバージョンも作ってみた。
(define-syntax chain (syntax-rules () ((_ e1) e1) ((_ e1 (f e2 ...) e3 ...) (chain (f e2 ... e1) e3 ...))))
実行例
gosh> (chain '(1 2 3) (cons 4) (reverse) (map (pa$ * 2))) (6 4 2 8) gosh> (chain 9 (/ 3) (- 1)) -2/3
consやmapの呼び出しがすっきりした
しかし2番目の実行例はやっぱり9/3-1=2になってほしいところ…