schemeの可変長引き数メモ
(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に適用するという意味になってしまうから。