メソッドチェイン風マクロ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になってほしいところ…