Scheme

省略可能引数

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

ドットリスト、ドット対

いまいち理解しきれてない。使いどころが分からん。 例えば、 (define MIT->primitive (lambda (expr) (match expr (('define (func . args) . body) (list 'define func (list* 'lambda args body)))))) のmatchのパターンのところが、なぜ ('define (func …

パターンマッチ

組み込みの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のついた書き方に読み替えてた。 この…

めんどうくさい

今はGauche@Emacs@Ubuntu8.04@VMware Player@Windows XPでSchemeやってるけど、いちいちVM立ち上げんの面倒くさい。 つーことで、デュアルブートするかUbuntuをホストにするか検討中。 メモリ1GBしかないし、ゲストのXP上でVisualStudioはちょっと厳しいかな…

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

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

LISPをみんなで勉強しよう!

というグループブログを見つけたので、参加してみることにしたよ。 一人でヒソーリコソーリやってきたけど、こういうのに参加するのもいいかも...なんて。 LISPをみんなで勉強しよう!:http://blog.livedoor.jp/lisp_learner_group/ 「LISPをみんなで勉強し…

末尾再帰と継続渡しスタイル

再帰には 末尾再帰 末尾再帰以外 の2種類があるそうな。 で、前者の末尾再帰なる形で書いておけば、Schemeが(規格に則って?)最適化してくれるらしい。 んで結果的に速いコードになるよ、ということらしい。

6章の練習問題とか

今回はappend2、reverse、find、length、filterを。 それぞれ名前をMyAppend、MyReverse、MyFind、MyLength、MyFilterに変更してます。 (define MyAppend (lambda (a b) (cond ((null? a) b) (else (cons (car a) (MyAppend (cdr a) b)))))) (define MyRever…

リストで木構造

LISPの入門書でコンスセルを表すとき、carとcdrの箱を横に2個並べた図をよく見る。 でもScheme初心者の僕としては、箱を縦に並べて木構造になっていることがもっと分かるように書いた方が良いいんじゃないかと思う。 リストで木構造を表しているんだよ、って…

deep-copy-list

今、Gauche本こと「プログラミングGauche」を読んでる。7章を読んでいるところ。プログラミングGauche作者: Kahuaプロジェクト,川合史朗出版社/メーカー: オライリージャパン発売日: 2008/03/14メディア: 大型本購入: 22人 クリック: 713回この商品を含むブ…

Schemeの開発環境

Windowsの再セットアップに伴い、Scheme環境もインストールしなおした。 この機会に備忘録をば。 ちなみに、ほぼhttp://kayui.blog38.fc2.com/blog-entry-45.htmlのコピペ。 emacsとかあんまし慣れてないんで、間違いとかあったらツッ込んでください、口汚く…

高階関数と再帰

理解したような気がしても次の瞬間には何が何だか分からなくなっている。 せっかく掴んだ脆く危うい理解も、砂のように指の間をすり抜けてこぼれてゆく。 掴みどころがない。 再帰と高階関数のコラボ。 凶悪極まりない。 発狂しそうだ。 再帰がスタックを食…

脳内変換

((lambda (f) (f f)) hoge) から (hoge hoge) へ、スムーズに脳内変換できない。 ((lambda (n) (+ n 1)) 5) から (+ 5 1) へはすぐ変換できるのに。 なかなか高階関数に慣れない。

ぽちっとな

プログラミングGauche作者: Kahuaプロジェクト,川合史朗出版社/メーカー: オライリージャパン発売日: 2008/03/14メディア: 大型本購入: 22人 クリック: 713回この商品を含むブログ (244件) を見る来たどー!日本語のSchemeの本だYO! しかもオライリーの動物…

継続渡しスタイルの練習

アトムatomと、アトムからなるリストlatを受け取り、latの中にatomが含まれるかどうかを調べる以下のような関数 (define contains (lambda (atom lat) (cond ((null? lat) #f) ((eq? (car lat) atom) #t) (else (contains atom (cdr lat)))))) を、multiremb…

継続に無理やり名前をつけてみた

どうやらletという関数を使うと、ローカルな名前付の関数を作れるらしい。 ということで、簡単なfact/cpsでやってみる。 (define fact/cps (lambda (n cont) (if (= n 0) (cont 1) (fact/cps (- n 1) (lambda (m) (cont (* m n))))))) で、else以下で作って…

継続渡しによる階乗計算をトレースしてみる

僕のカニみそ級の脳みそでは、無名関数が混じっていると混乱してしまうっぽいので、適当に名前を付けながらトレースしてみました。 (define fact/cps (lambda (n cont) (cond ((= n 0) (cont 1)) (else (fact/cps (- n 1) (lambda (m) (cont (* m n)))))))) …

DrSchemeからMeadow+Gaucheへ

今までDrSchemeを使ってSchemeのコーディングをやってたんだけど、開発者のはしくれとしてemacsに憧れがあって、「emacs使わんで何が漢ぞ!!」とばかりにやってみました。 ってかemacsじゃなくてMeadowなんだけども。 あ、あとDrSchemeってファイルを開くダイ…