プログラミングGauche

delete

gosh> (use srfi-1) #<undef> gosh> (define *p* (cons 1 2)) *p* gosh> (delete *p* (list *p* *p* (cons 1 2) *p* *p*)) () gosh> (delete *p* (list *p* *p* (cons 1 2) *p* *p*) eq?) ((1 . 2)) みたいな、第1引数を第2引数のリストから見つけて全部削除した残</undef>…

member

gosh> (member 'cookie *inventory*) (cokkie dagger) gosh> (member 'ration *inventory*) #f のように、第1引数を第2引数の中から探し、見つかった場合には見つけたものを含めた残りのリストを、見つからなかったら#fを返す。 つまり、ifなどの条件式に使…

9章はじめー

9章1節、集合。 うっはー! 代入が一般的ではないSchemeで、どうやって状態を扱うのかとても興味がある。 すべて式である なんて言っちゃってるけど、やっぱ代入しちゃうのね。 新出の手続きは以下。 member set! delete これらの手続きを使って、持ち物を表…

and-let*

8章4節、and-let*に関して。 条件式が#fじゃなければその値を使って計算して、その結果で真偽を判定して、#fならば処理を止め、#f以外ならばさらにその値を使って計算して...、みたいな場合、つまり int val1=0,val2=0,val3=0; if ((0 != (val1 = SomeFunc1(…

whenとunless

8章4節のwhenとunlessに関して。 when 与えた式が真となるとき(つまり#fにならないとき)に限り処理をする場合に使う。 (when <条件式> 複数のS式) を評価した後、それが#f以外になれば以降に続く「複数のS式」を順に評価して、最後のS式の値をwhen全体の値…

andとor

8章4節のandとorに関して。 and 複数の引数を取り、先頭から評価していって、#fを見つけたら直ちに評価を中止し#fを返す。 引数が全て#f以外の値だったら、最後に評価した値を返す。 gosh> (and 1 2 3 #f 4 5) #f gosh> (and 1 2 3 4 5) 5 簡単。 or 複数の…

case

8章4節のcaseに関して。 C言語とかでのswitch-case文みたいなことができるのね。 (case <key式> (リスト1 複数のS式) (リスト2 複数のS式) ... (リストn 複数のS式) (else 複数のS式) まずを評価する。 んで、リスト1、リスト2、...、リストnの順に要素にと同じもの</key式>…

すべて式である

106ページからのコラム「すべて式である」。 今までSchemeをやってきて、このコラムが言いたいことは大体理解できた。 だけど、評価結果が未定義の場合はどうするのだろう。 Schemeでの未定義な値は、Gaucheでは#らしいけど、この値を使って何かを計算するの…

仕様

どこまでがSchemeの仕様で、どこからがGaucheの拡張なのかなぁ。 この本を読んでいて、よく思う。 初心者のうちはそこまで気にする必要はないのかも知れないけど。 Schemeの仕様について知りたければ、R5RS(http://www.unixuser.org/~euske/doc/r5rs-ja/)…

cond

8章4節のcondについて。 条件判断といえば、自分はif式よりもこっちばっかり使ってるな。 たぶんThe Little Schemerのせい。 condも知らないことが結構あった。 (cond (条件式1 条件式1が#f以外の値になった場合のcond式の値) (条件式2 条件式2が#f以外の値…

if

8章4節のifについて。 今まで何度か使ったけど、知らないことも多かった。 (if 条件式 条件式が#f以外の場合のif式の値 条件式が#fの場合のif式の値) だそうだ。 3つ目の引数は省略可能だということは初めて知った。 3つ目の引数が省略された場合に「条件式…

8章3節の練習問題とか

any-predとevery-predを自分で定義しなさい、ということなので、やってみた。 (define my-any-pred (lambda args (lambda (x) (cond ((null? args) #f) (((car args) x) #t) (else ((apply my-any-pred (cdr args)) x)))))) (define my-every-pred (lambda a…

もうちょっと述語

8章3節、真偽値に関する手続き。 等価述語以外の述語 前回は等価述語だったけど、等価述語以外にも述語はたくさんありますよ、と。 型を判定したり、値の性質を判定したり。 詳しくは追々出てくるっぽい。Schemeには述語を引数にとったり、述語を返したりす…

いろいろな「等しさ」

さて、8章2節。 真偽値を返す関数のことを「述語」と呼び、とくに等しいかどうかを調べる関数を「等価述語」と呼ぶ。 C++のSTLや.NET Fremeworkでも出てくる用語なので、一応知ってた。 英語でいうとpredicateね。 ...はい。で、本題。 「値が等しい」と一口…

キーワードって何ぞ?

そういえば、キーワード引数のところ(82ページ)で、 キーワードは :名前 と、コロンの後に名前を書くことで作成できます。 とあった。 「作成できます」って書いてあるから、なにかが定義されるのかと思ったけど、そうではないみたい? 'hoge が (quote ho…

Lisp脳

大いに感動した。 手続的な発想では、毎回特殊な処理を行いそれを繰り返すという発想でプログラミングしていました。 Schemeプログラマはそうは考えません。 「データからデータへの変換を考えれば良く、出力は後からどうにでもなる」 と考えています。 「Li…

多値

これまた今までの文化に無いので、メリットが実感できない概念。 理解すんのは難しくなさそうだけどね。

部分適用

cutという構文を使うと (lambda (a) (func a x)) を (cut func <> x) って書けるそうだ。<>が引数になるような関数が作れる。 (cut func <> x) のcutを取っ払って (func <> x) にして、 さらに <> を引数にして (lambda (a) (func a x)) の出来上がり。 なん…

キーワード引数

引数に関数を適用する際に、引数に名前みたいなもの(= キーワード)をつけられる。 そのおかげで、引数の順番を覚えておかなくてもよくなるらしい。引数が多い場合に便利そう? この概念は始めて出会うなぁ。スクリプト言語にはあったりするのかな。 ってこ…

省略可能引数

C++でもデフォルト引数ってのがあったけど、おんなじような機能で「省略可能引数」ってのがあるらしい。 使い方は (let-optionals* args ((名前1 値1) (名前2 値2) ... (名前n 値n)) let-optionals*式の値となるS式) argsの要素が先頭から順に名前1、名前2、…

パターンマッチ

組み込みのappend関数を実装すると次のようになる。 (define my-append (lambda args (cond ((null? args) '()) ((null? (cdr args)) (car args)) (else (append2 (car args) (apply my-append (cdr args))))))) (define append2 (lambda (a b) (if (null? a…

複数引数をリストにして関数適用

applyという関数を使うと、 (some-function arg1 arg2 arg3 arg4) を (apply some-function '(arg1 arg2 arg3 arg4)) って書けますぜ、と。 可変長引数と相性が良いっぽい。こんな感じ。 gosh> (define make-logger (lambda (f) (lambda args (print "args="…

木構造をこねくり回す

7章4節の最後に、lambdaを使った関数定義とMIT形式の変換をやる関数が紹介されている。 特に練習問題ではないけど、自分で書いてみないと気が済まないのでやってみた。 gosh> (define primitive->mit (lambda (expr) (list (car expr) (cons (car (cdr expr)…

7章4節の練習問題

可変長引数関数の定義の仕方を参考に組み込みのlist関数を自分で実装しろ、と。 gosh> (define MyList (lambda arg arg)) MyList gosh> (MyList) () gosh> (MyList 1) (1) gosh> (MyList 1 2) (1 2) gosh> (MyList 1 2 3 4 5) (1 2 3 4 5) あまりにも簡単な…

可変長引数をとる関数の定義法

2個以上の引数を要求する関数 (lambda (a b . c) 定義) 使ってみる gosh> (define func (lambda (a b . c) (print "a=" a " b=" b " c=" c))) func gosh> (func 1 2) a=1 b=2 c=() gosh> (func 1 2 3) a=1 b=2 c=(3) gosh> (func 1 2 3 4) a=1 b=2 c=(3 4) g…

ローカル変数

let let* letrec の3つのタイプがあるそうだ。 使い方は全部同じで (let族 ((変数1 変数1を初期化するS式) (変数2 変数2を初期化するS式) ... (変数n 変数nを初期化するS式)) let族の値となるS式) ってな感じ。 「let族の値となるS式」の中で「変数1」〜「変…

7章2節の練習問題

for-each-numberとmap-numbersは簡単。 (define for-each-numbers (lambda (proc l) (for-each proc (filter number? l)))) (define map-numbers (lambda (proc l) (map proc (filter number? l)))) ですな。 これを、for-eachやmapを受け取ってfor-each-num…

tree-walkと高階関数

高階関数とは、関数自体を引数にしたり戻り値(って言っていいのかな)にしたりする関数のこと。 7章2節の冒頭に出てくるfor-eachは関数を引数にとる高階関数。僕はこの高階関数が弱点のようで、以下のtree-walk関数の動きがなかなか理解できなかった。 (def…

MIT記法

僕はThe Little SchemerからSchemeに入ったクチなので、 (define 名前 (lambda (引数1 引数2) 本体)) みたいな書き方に慣れてるから、本書で使われてる (define (名前 引数1 引数2) 本体) という書き方をいちいちlambdaのついた書き方に読み替えてた。 この…

リテラルで書けないオブジェクト?

引数に1足した数を返す関数add1を定義して、add1を評価(関数適用ではなく)してみると以下のようになる。 gosh> (define add1 (lambda (n) (+ n 1))) add1 gosh> add1 #<closure add1> この#っていうのは、61ページによると、 式の値が内部的な「手続き」オブジェクトであ</closure>…