Gauche

Gaucheの*load-path*(その2)

スクリプトで (add-load-path "/home/username/dev/src/lib") ってやっても良いけど、goshは起動時のコマンドライン引数のオプションでも*load-path*に追加できるらしい。 gosh -I/home/username/dev/src/lib または gosh -A/home/username/dev/src/lib でい…

Gaucheの*load-path*

俺ライブラリを書き始めた。モジュールとして作って、それをuseしようと試みたらエラーになって1時間くらい悩んだのでメモ。 ;; ~/dev/src/lib/hoge.scm (define-module hoge (export foo)) (select-module foo) (define x 42) (define (foo n) (+ x n)) (pr…

新たな変数名の作成

id:yagiey:20100305:1267761841にトラバもらった。id:trotr:20100308:1268043643 引数を加工することが必要っぽいので、objectを書き直してみた。 今度はちゃんとget-○○○って名前にした。 (define-macro (object args . methods) `(lambda ,args (lambda (mn…

使い捨てのシンボル

適当なシンボルを生成したいときは、シンボルを生成してくれる手続きgensymを使えばいい。 gosh> (gensym) #:G1 とまあ、こんな感じ。 このgensymと伝統的なマクロを使って、id:yagiey:20100127:1264595558で定義したmy-orを書き直してみると (define-macro …

objectマクロを非R5RSマクロで

今回は勝手にシンボルをでっちあげて、新しい名前を作ってみる。 271ページの 例えば構造体を定義するマクロdefine-structを定義することを考えます。fileという構造体を定義し、それがnameというスロットを持つ場合、自動的にfile-nameというスロットアクセ…

新たな変数名の作成

id:yagiey:20100213:1266088272で 「新たな変数名を作り出す」という要請に対しての解決策という形で紹介される伝統的なマクロ とか言ったけど、 (define-macro (make-foo) 'foo) でも、立派に新しい名前を作ってると言えるよね。ただ、外側でfooが束縛され…

やっと分かった

ずっと (define-macro (my-when test . body) `(if ,test (begin . ,body))) が理解できなかった。具体的に言うと、 (my-when (even? 4) 1 2 3 4) って使うと、,testが#tになると思い込んでいたので、,bodyが(1 2 3 4 5)という関数適用でエラーにならないこ…

R5RSマクロの限界

Schemeのマクロには大きく分けて R5RSマクロ:パターンマッチによるマクロ レガシーなマクロ:LISPに伝統的なマクロ があるとid:yagiey:20100126:1264525307で紹介した。 今回は後者に関して。 R5RSマクロは以下のようなマクロを実現できない、もしくは実現…

マクロの使用例

マクロ定義の実例として、簡単なオブジェクトシステムを書くことを想定したケースが紹介されている。ここで登場するオブジェクトは、以下のような銀行口座を表すオブジェクト。(以下のC#コードは動作確認してません) using Sysmtem; public class Account …

マクロをいつ使うか

letはlambdaによる無名関数の適用へと展開される(id:yagiey:20100128:1264705405)。 だからletは(仕様が要求するけど)必須構文ではない。 だけどletによって「ローカル変数」という概念ができる。 このように、 そのマクロによってまとまった、明確な抽…

マクロの健全性

id:yagiey:20100127:1264595558のorマクロを使って次のようなコードを書いたとする。 (let ((tmp 2)) (or #f tmp)) orを素直に展開すると (let ((tmp 2)) (let ((tmp #f)) (if tmp tmp tmp))) ってなって、展開前に意図した結果が得られない。困った。 さら…

R5RSマクロその2

R5RSマクロは、 式の構造のパターンマッチ マッチした時に展開されるテンプレート という形で定義されるってのはこの前やった。 しかし、式の構造だけではなく、同じ字句かどうかで判定しなければならないことがある。それがcondで、なぜならelseという字句…

let

マクロの練習に、自分でletを定義してみた。 (define-syntax my-let (syntax-rules () ((my-let ((var init) ...) expr ...) ((lambda (var ...) (begin expr ...)) init ...)) ((my-let fname ((var init) ...) expr ...) (my-let ((fname #f)) (set! fname…

R5RSマクロその1

R5RSマクロはパターンマッチの仕組みを利用して、式の変換規則を定義する。 こんな感じ。 (define-syntax マクロ名 (syntax-rules () (パターン1 テンプレート1) (パターン2 テンプレート2) ;; 中略... (パターンn テンプレートn))) パターン1、パターン2と…

構文の拡張

やっとここまで来たなぁ。18章は「構文の拡張」。 ...って、12〜17章はすっ飛ばした。悪しからず。いつか読む。 とにかく18章と19章が早く読みたかったし、特に飛ばしても差し支えなさそうだったし。 さて、18章はLISPをLISPたらしめると言われている(どこ…

気になったので実験してみた

useしたものは、局所環境フレームに束縛が追加されるのかな? gosh> (begin ((lambda () (begin (use srfi-1) #t))) (iota 10 1)) (1 2 3 4 5 6 7 8 9 10) あれ?iotaされてしまった。 Gaucheのドキュメント読まないと分からんなぁ。

ポップされた環境フレーム

前のエントリで、ポップされた環境フレームに関する疑問をちょっと書いた。 で、それっぽい答えを出したけど、その答えが正しいとしたら、また新たな疑問がでてくる。 例えば、次の条件を全て満たすような場合はどうするんだろう。 環境からポップされた環境…

環境フレームモデル

置き換えモデルではbeginやset!が絡んだ時に正しい値にならなかった。だけど、環境フレームモデルでは正しく計算できるらしい。 だい〜ぶお利口、置き換えモデルよりいくらかCOOL(by 宮崎吐夢 環境フレームモデルでも「環境」を用いるが、置き換えモデルの…

漠然とした不安

なにがそんなにモヤモヤするのかちょっと考えてみた。そしたら、以下のことが、漠然とした不安を感じさせているんじゃないかと気づいた。 gosh> (lambda (a b) (foo a b)) #<closure #f> gosh> ((lambda (a b) (foo a b)) 1 2) *** ERROR: unbound variable: foo Stack T</closure>…

作用順序評価

2つの評価モデルの話に進む前に、作用順序評価という概念について少し。 id:yagiey:20100103:1262535864の最後らへんで書いた内容に関係するような気がするなぁ。 Schemeでリストを式として評価する時は基本的に関数適用になるけど、この関数適用に先立って…

評価モデル

計算の様子を理解するためにはどうすればいいだろうか? 計算機で実際に動かす 何をやってるかは分かるだろうけど、ある特定のプログラムに関してしか使えない方法だ。計算一般で使えるような方法はないか? 機械語を追って計算機をシミュレート あまりにも…

置き換えモデルと副作用

置き換えモデルでは、副作用がある式を扱えない場合があるらしい。まず「副作用」を定義しなくちゃいけないだろうけど、自分もちゃんと理解できていないので定義せずスルーする。ごめんなさい。では、置き換えモデルで (((lambda (y) (lambda (x) (begin (se…

置き換えモデル

「名前」と「名前に紐づけられた値」のペアを束縛という。 ある時点での束縛は複数あることが普通。ここでは piが3.14に fooが42に barが"hello"に 束縛されているとしたら、 名前 値 pi 3.14 foo 42 bar "hello" みたいな表になる。これを環境と呼ぶ。束縛…

例外その2

今回はGaucheのtest*、test-start、test-endの簡易版を実装してみようという内容。 今までの知識を以ってすれば特に難しくはないが、簡易版test*であるmytestの実装でのthunkの話がポイントですかね。 手続きの評価を遅らせるために、関数適用ではなくラムダ…

例外その1

10章のうち、後半の例外について。まず、他の言語との概念の違いについて。Schemeには例外に関係する用語として以下のようなものがある。 例外:例外的な事象のこと。 コンディション:例外が発生した時に作成される、例外の状況を記述するためのオブジェク…

テスト

10章「テストと例外処理」のうち、テストに関する箇所をば。 手続きtest* ちなみに、test* は以下でも出てきた。 id:yagiey:20090307:1236410685 id:yagiey:20090321:1237653683 評価結果が○○と等しくなるはずだ!ってな感じで、次のように使う。 gosh> (use…

気になったので実験

ちょっと気になったことを実験してみた。 実験1:defineで名前をつけるとき、2つ目の引数は評価されるのか? gosh> (define add-n (lambda (m) (+ m n))) add-n gosh> (add-n 1) *** ERROR: unbound variable: n Stack Trace: _____________________________…

多値をreceiveで受け取らなかったら

114ページからの「手続きによるパターンの抽象化」を読み返しているとき、ふと不思議に思ったことがある。 それは、手続きtraverseを使ったmember2の定義内での、valuesの使い方。 ;; traverseを用いない (define member2 (lambda (elt lis . opt) (let-opti…

delete-1

さて、半年つんどくしていました「プログラミングGauche」。 続きからやろうと思ったら「今まで何やってたっけ?」っていう感じだったので、9章の始めからつらつらと読んでた。 で、つまずいてたdelete-1のnon-copyバージョンを書いてみると、割とすらすらと…

WindowsでGauche

WindowsでGaucheやるには、おそらくGaucheboxが一番お手軽。 以下よりダウンロード、インストール。 http://practical-scheme.net/wiliki/wiliki.cgi?Gauche%3AGauchebox