Gauche の手続き : 4

呼称: 可変長引数とその他の引数
目的: 可変長引数の渡し方と、省略可能引数/キーワード引数を学ぶ

可変長引数を渡す場合、apply を使用する。<引数リスト>の各要素を引数として<手続き>を呼び出す。

(apply <手続き> <引数リスト>)

使用例。

(define (map/log . args)
  (print "args=" args)
  (apply map args))

gosh> (map/log (lambda (x) (* x x)) '(1 2 3))
args=(#<closure #f> (1 2 3))
(1 4 9)


引数のチェックのような条件判断に match 構文を使用する方法があります。

(use util.match)
(match <式>
  (<パターン1> <式> ...)
  (<パターン2> <式> ...)
  ...)

使用例。

(use util.match)
(define (my-rev . args)
  (match args
    [() '()]
    [(a) (reverse a)]
    [(a . b) (my-rev (apply append a b))]))

gosh> (my-rev '(1 2) '(3 4) '(5 6))
(6 5 4 3 2 1)
gosh> (my-rev)
()

省略可能引数を使用するために、引数リストのチェックをする構文として、let-optionals* 構文があります。

(let-optionals* <引数リスト> ((<変数1> <省略時式1>)
                              (<変数2> <省略時式2>)
                              ...)
                <本体> ...)

使用例。

(use srfi-1)
(define (make-filter lis . args)
  (let-optionals* args ((proc print))
  (filter proc lis)))

gosh> (make-filter '(1 #f 3 4 "str"))
1
#f
3
4
str
(1 #f 3 4 "str")
gosh> (make-filter '(1 #f 3 'str) number?)
(1 3)
gosh> (make-filter '(1 #f 3 "str") string?)
("str")
gosh> (make-filter '(1 #f 3 4 "str") boolean?)
(#f)

キーワード引数を使用するには、呼び出し側で : 記号で始まるキーワード名を一緒に渡します。

;; キーワードの作成
gosh> :name
:name
gosh> (make-keyword 'age)
:age
gosh> (make-keyword "age")
:age

;; キーワードの判別
gosh> (keyword? :name)
#t
gosh> (keyword? 'name)
#f
gosh> (keyword? :address)
#t ; キーワードを作成していなくても True が返る?

;; キーワード引数のチェック構文として、let-keywords 構文がある
;; let* 同様の let-keywords* 構文もある
(let-keywords <引数リスト> ((<変数1> <省略時式1>)
                            (<変数2> <省略時式2>)
                            ...)
              <本体> ...)

使用例。

(define (product . args)
  (let-keywords args ((name "unknown")
                      (version "major")
                      (release "minor")
                      (license "GPL")
                      . other-args)
     (print name "-" version "-" release ", license : " license)
     (print "Others : " other-args)))

gosh> (product :name "forest book" :version "0.8" :release "1fb" :date "2008/09/11")
forest book-0.8-1fb, license : GPL
Others : (date 2008/09/11)
#<undef>