--- title: 複数の引数をとる手続きだよ author: kazu634 date: 2008-08-03 url: /2008/08/03/_1062/ wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4185;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - gauche - Lisp ---

勉強だよ。

複数の引数をとる手続きだよ

こんな風に書くらしい。「. args」が「0個以上の引数リスト」を意味する。「1つ以上の引数リスト」は「a . args」となるそうな。

(use srfi-1)
(use util.match)
(define (append . args)
(match args
[() '()]
[(a) a]
[(a . b) (append2 a (apply append b))]))

このようにしてやると、引数のチェックをして、複数の引数をとる手続きを書けるみたい。

省略可能引数

こんな感じー

gosh> (define (make-list num . args)
(define (maker n init)
(if (= n )
'()
(cons init (maker (- n 1) init))))
(maker num (if (null? args) #f (car args))))
make-list
gosh> (make-list 10)
(#f #f #f #f #f #f #f #f #f #f)
gosh> (make-list 10 1)
(1 1 1 1 1 1 1 1 1 1)

基本的な考え方としては「可変長引数が空」という扱いにするらしい。それ以外の方法としては let-optionals*を使うらしい。

gosh> (define (make-list num . args)
(let-optionals* args ((init #f))
(define (maker n)
(if (= n ) '() (cons init (maker (- n 1)))))
(maker num)))
make-list
gosh> (make-list 1)
(#f)
gosh> (make-list 1 2)
(2)

多値

Lispは複数の返値を返すことができる。それの受け取り方や、複数の返値を返す方法を考えてみるよ。

多値を受け取る

receive手続きを使うよ。mix&maxは最小値と最大値を返す手続き。

gosh> (receive (min-val max-val)
(min&max 3 1 2)
(list min-val max-val))
(1 3)

二つの戻り値に対して二つの格納する変数を用意する方法だけでなく、一つのリストとして格納することもあり。

gosh> (receive all-values
(min&max 3 1 2)
all-values)
(1 3)

values-refを使うと、戻り値を配列に格納したかのようにして扱うことができる。

gosh> (values-ref (min&max  3 -1) )
-1

これで戻り値の0番目の数字を取り出すように指示している。

FizzBuzz

データからデータへの変換を考えればよく、出力は後からどうにでもなる。

これがSchemeプログラマの基本的な発想…らしい。

gosh> (for-each print
(map
(lambda (x) (cond [(= (modulo x 15) ) 'FizzBuzz]
[(= (modulo x 5) ) 'Buzz]
[(= (modulo x 3) ) 'Fizz]
[else x]))
(iota 100 1)))
プログラミングGauche

プログラミングGauche