cut

昨日、あとで調べてみよう、と書いた cut について調べてみた。

 cf. 4.3 手続きを作る – Gauche ユーザリファレンス

[SRFI-26] 手続きを簡潔に書ける便利なマクロです。 いわゆる部分適用を実現するために使えます。

SRFI-26 とあるけど、Gauche では標準で使えるようになっている。

たとえば、文字列3つを引数にとって、”-” でつなげる手続きを考えよう。

gosh> (define foo
  (lambda (a b c)
    (string-join (list a b c) "-")))
foo
gosh> (foo "hoge" "fuga" "piyo")
"hoge-fuga-piyo"

この手続き foo の引数のうち、2つめだけをあとから与えるようにしたいとする。つまり、1つめと3つめだけ先に部分適用したい、と。そういうときに cut を使えば実現できる。

gosh> (cut foo "hoge" <> "piyo")
#<closure #f>

シンボル <> が後から与えられる引数の代わりになっている。実際に使ってみると:

gosh> ((cut foo "hoge" <> "piyo") "fuga")
"hoge-fuga-piyo"

確かに2つめの引数をあとから与えることができている。
シンボル <> はいくつあってもいいらしい。後から与えられる引数と対応した <> に当てはめられる。

シンボル <...> を使うと可変長引数をとることができるようになる。

gosh> (cut list <...>)
#<closure #f>
gosh> ((cut list <...>) "foo" "bar" "baz")
("foo" "bar" "baz")

なるほどねぇ。つまり昨日の (cut show-help (car args)) は手続き(ただし、引数なし)を作っていたわけだ。