schemeの可変長引き数メモ

SICPこの辺を読んでたら、

(define (make-serializer)
  (let ((mutex (make-mutex)))
    (lambda (p)
      (define (serialized-p . args)
        (mutex 'acquire)
        (let ((val (apply p args)))
          (mutex 'release)
          val))
      serialized-p)))

のという関数定義があって、これの(define (serialized-p . args)が見慣れない形だと思ったのでメモ。

  • lispでは、関数呼び出しは先頭要素が関数であるようなリスト。
  • lispのリストとは、要素をcons, i.e. ( . ) で繋げたもの。
    • (item1 . (item2 . (item3 . ... . (itemN . ())...)
  • (serialized-p . args) を上の形に当てはめると、
    • serialized-p -> 先頭要素
    • args -> リスト(serialized-p . args)から先頭要素を除いたリスト
  • と理解出来る。
  • つまり、argsは、実際に serialized-pが呼ばれた時の引き数全部。
  • こういう形を許せば、可変長の引き数にも自然に対応出来ている。なるほど。

ちなみに、(apply p args) を (p args)と書くのはだめ。(p args)だと、一引数関数pを一つのリストargsに適用するという意味になってしまうから。