ラベル 9LISP の投稿を表示しています。 すべての投稿を表示
ラベル 9LISP の投稿を表示しています。 すべての投稿を表示

2010/09/14

ライフゲーム作った


9LISP の宿題。Scheme(Gauche)で作りました。作りかけですが、動くので取りあえず。
行き当たりばったりで作ったこともあり、突っ込みどころ満載でちょっと恥ずかしいですが。。

ライフゲームの動き見てるのって意外と面白いんですね。

例えば、繰り返すパターン。
(load "./lifegame.scm")

(define-constant PULSER
  '((0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
    (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)))

(define pl (endless-repeat-lifegame (const->auto-step-lifegame PULSER)))
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ○ ○ ○ ○ ○ ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ● ○ ○ ● ○ ● ○ ● ○ ● ○ ○ ● ○ ○)
;; (○ ○ ● ● ● ○ ● ● ○ ● ● ○ ● ● ● ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ● ● ● ○ ● ● ○ ● ● ○ ● ● ● ○ ○)
;; (○ ○ ● ○ ○ ● ○ ● ○ ● ○ ● ○ ○ ● ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ○ ○ ○ ○ ○ ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ● ○ ○ ○ ○ ● ○ ● ○ ○ ○ ○ ● ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ● ● ● ○ ○ ○ ● ● ● ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
(pl)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ● ○ ● ○ ● ○ ● ○ ● ○ ● ○ ○ ○)
;; (○ ● ● ● ○ ○ ● ● ○ ● ● ○ ○ ● ● ● ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ● ○ ○ ○ ● ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○ ● ○ ○ ○ ○ ○)
;; (○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○)

まだ UI がないので、IronScheme で作ろうかなぁとか考えてます。それか手っ取り早く C# で GUI 作ってデータ読み込むとか。。それなら最初から C# で作れば良いじゃんという話ですね。

プログラミングGauche

2010/05/06

9LISP - 015 やりました


2010/05/01 の 9LISP - 015 の参加者は私( @valvallow )と @aharisu さんの2人でした。
わりと雑談メインでした。
などの話。

@aharisu さんは、C# で R5RS に準拠(?)の Scheme 処理系を作ったことがあるそうです。その処理系を実装するなかで、マクロの実装を後に回したのは失敗だったということでした。
確かに、いくつかのプリミティブとマクロがあれば、残りはどうとでもなりそうな気もします。

私もその処理系を見せてもらったことがありますが、IL レベルでの末尾呼び出し最適化や、インラインで IL を書いてチューニングしてあるような、とんでもない代物でした。

私も C# は3年ほど仕事で使っていたので、ある程度は読み書きできます。しかし、IL なんて読めもしなければ書くなんてとんでもないです。うへー。



雑談しながら、@aharisu さんは、LET OVER LAMBDA Edition 1.0 の dlambda 限定の with を実装しようとしてました。
その後、どうなったんでしょう?

LET OVER LAMBDA Edition 1.0 の7章の Forth が取り合えず動かせるようにしていました。
このように、今回は特にテーマもなく、雑談しながらそれぞれ
あとは、ランチして解散。

LET OVER LAMBDA Edition 1.0

2010/04/18

9LISP - 012, 013, 014


まとめ(?)を書いていませんでした。

012

高階関数の練習問題などをやりました。高階関数の例題がなかなか思いつきませんでした。木構造関連の例題をやりました。何か良い例題というか問題はないでしょうか・・・。

午後は量子論。

013

マクロに入りました。
どのように進めて行くか話合いました。
何を作るか話し合いました。
午後は、きゅーりすぷたん検討会。(こっちの方が盛り上がったかもしれない)

014

  • Common Lisp処理系を入れましょう(次回までに)
  • Common LispとSchemeについて違いを少々
    • t, nil, (car '()), undef, defun, dynamic-scope, funcall, setf, zerop, など
  • quote類について
書けばイメージもそれなりに湧くはず、ということで。マクロは書かないと書けるようにはならない。たぶん。

例えば、PostScriptのこんなコードが・・・、
/x 10 def
/y 10 def
x y moveto
5 5 lineto
S式でこういう風に書けたら、うれしくね?
((let ((x 10)
       (y 10))
   (lambda (x1 y1)
     (moveto x y)
     (lineto x1 y1))) 5 5)
ということで。


私の端末には、CLISP, SBCL, AllegroCLが入っています。Emacs+SBCL+SLIMEでやってみることにします。そういえば今回、これがLISPだ! (Information & computing (30)) を始めて目にしました。


Rubyで作る奇妙なプログラミング言語 ~Esoteric Language~LET OVER LAMBDA Edition 1.0初めての人のためのLISP[増補改訂版]

quasiquoting

さっそく、マクロに使うテクニックを。クォートが4種類あります。それぞれの名前は覚えていません。
より

  • quoteは式を評価せず式のまま返す
  • quoteは'(シングルクォート)記号で代用できる
  • quasiquoteはquoteに似ているが、式の中でunquoteとunquote-splicingが使える
  • quasiquoteは`(バッククォート)記号で代用できる
  • unquoteは式の値を評価し、評価結果を式に埋め込む
  • unquoteは,(カンマ)記号で代用できる
  • unquote-splicingはリストの外側の括弧を取り払ってその場に展開する
  • unquote-splicingは,@(カンマとアットマーク)記号で代用できる
  • quote, quasiquote, unquote, unquote-splicingは特殊形式である



プログラミングGauche

2010/04/03

新ロゴ

ロゴが新しくなりました。春ですし。



どちらもロゴジェネレータで作ったものですけども。。
現在、@msskndさんにお願いして擬人化プロジェクトが進んでいたりします。9LISPの読み方は「きゅうりすぷ」「くりすぴー」「くりすぷ」「ないんりすぷ」・・・など、なんでも良いです。ですが9LISPたんは「きゅうりすぷたん」です。乞うご期待。
やっぱどこかに「λ」が欲しいですね・・・。

2010/03/10

9LISP - 011 をやりました

先週の土曜日に開催されました。
内容を書くのが遅くなってしまいました。

また、オンライン中継を行なう予定でしたが、ネットワーク不調のため急遽中止ということになり、オンライン参加予定だった方、のぞいてみる予定だった方、すみませんでした。
しかし、Google WaveとSkypeを使ったオンライン自習会が開催されたようです。すげー。

 

あと前回、「裸に見えるジェネレータ」について話が出てましたが、@aharisuさんがクローン(?)を作ってました(笑)前回9LISPの次の日には作ったんだとか。しかもandroidアプリにしてました(笑)@aharisuさんはいつもすごい。

 

概要

  1. 今後の進め方について
  2. 前々回、前回の復習
  3. 問題を解いてみる
  4. クロージャ
  5. C#とかJavaとか
  6. オンライン参加

1.今後の進め方について

  • 現在は高階関数をやっている
  • 次(継続)に進むか?それとも高階関数について深めるか?
    • もっと例題を解いてみたり、現実的な問題を解いてみよう
    • SICPの図形言語とかどうかな?
    • 次回までに高階関数、クロージャ関連の練習問題を探してみる

2.前々回、前回の復習

  • 前々回
    • The Little Schemer の rember(remove member), rember-f(高階関数) insertL, insertR, insert-g(高階関数)
  • 前回
    • map, fold, for-each を自前で定義してみる
    • fold, unfold とか

 

3.問題を解いてみる

  1. ループを使わずに配列を逆順に
  2. ループを使わずに1~10の総和を
  3. xにf, gを適用させるcompose
  4. xにn回fを適用するrepeated

1は最近、2は以前流行ってたので。3, 4はSICPの2章から。

関数合成、curry化、部分的なcurry化など。

コードは例えば以下のようなもの。

4.クロージャ

  • レキシカルスコープ
  • クロージャの簡単な例
    • counter など
  • C#のクロージャだとステップデバッグでわかりやすい
  • C#のラムダ式
  • クロージャで簡易OO的なもの
  • クロージャって、newしたクラスのインスタンスに似てるよね
  • クロージャがあればOOできるしOOがあればクロージャできる
  • map, for-each, fold の例、動作イメージなど

高階関数やクロージャに馴染みのない参加者の方もいます。ホワイトボードにたくさんSchemeのコードを書きました。

5.C#とかJavaとか

  • Javaのインナークラスでクロージャもどきできるよね
  • C#のクロージャも結局はインナークラスだよ
  • C#でクロージャ書いてdisasmしてILのぞいて見よう
  • クロージャをステップデバッグしてみよう

VSのステップデバッグわかりやすい。

オンライン参加

カメラ、多人数用のマイク、プロジェクターなど準備はできていたもののネットワーク不調によりネットできず断念。

  • 自習会が開かれた模様
    • Google Wave + Skype + Twitter

ネットワーク不調は改善されたようなので、次回こそは中継できそうです。

追記

オンライン自習会のまとめが書かれていました!

The Little Schemer, 4th Edition計算機プログラムの構造と解釈

2010/02/22

9LISP - 010 をやってきました

9LISP

Lispの勉強会を名乗っていますが、Common Lisp ではなく Scheme の学習を進めています。Common Lisp はその後の予定。

隔週の土曜日、午前10時から行なっています。毎回、勉強 → ランチ → 雑談 という流れです。

 

今回の参加者は4人と少な目でした。しかし、今回は遠隔地からskypeで@cametan_001さんに参加頂き、いつもと違った面白さがありました。

あと Google wave すげー!リアルタイムコード共有的な意味で。

 

今回の内容

前回は「Schemeで高階関数を書いてみよう」ということで、リストから要素を取り除くrember手続きを書き、段階を追ってsrfi-1のfilter相当の高階関数rember-fに書き換えていく、というようなことをやりました。リストに要素を加えるinsertR, insertL, insert-g(高階関数)も。

rember は The Little Schemer に出てくるもので、Remove Member ということで良いかと思います。insertR, L, -g も同じく The Little Schemer に出てきます。

 

今回は、

  1. map, for-each, fold を自前で定義してみよう
  2. unfoldっていつ活躍するんだろう・・・。そもそもunfoldって何がunなfoldなの?
  3. fold-rightってreverseとか使わずにスマートに定義できるの?

というようなことがありました。

1はともかく、2は放置、3はループしかないかな?ということでした。

 

ところでsrfiって「サーフィ」って読むんですね。まんまと「えすあーるえふあい」って読んでました。

 

オンライン中継

010からustreamとskypeでオンライン中継を行なうことにしました。

skypeの方、当初「9lisp」とATNDに書いてました。正しくは「qlisp」です。9lispで探された方、申し訳ありませんでしたorz

 

マイクが私の端末にしかなく、中継は終始グダグダになってしまいました。別途マイクを用意しようと思います。(次回準備できるかわかりませんが・・・)

グダグダな中継に付き合って下さった方々、ありがとうございました。

また次回からも行ないますので、気が向いたらのぞいてみてください。

 

The Little SchemerThe Seasoned SchemerThe Reasoned Schemerv

2010/02/08

9LISP - 010


次回は2010/02/20(土)です。

9LISP - 009

9LISP の 009 回目を開催してきました。

午前中は9LISP、午後はKPFの第五回という楽しい一日でした。
内容はshunsukさんのこちらの記事をどうぞ。
9LISP では引き続きThe Little Schemerをテキストとして使用しています。
今回からはテキストを頭から順に進めていくスタイルを止めて、下記ポイントに絞って進めていくことになりました。
The Little Schemerでは末尾再帰とマクロについては扱われていませんし、継続渡しスタイル(CPS)の例も複雑で、正直わかりづらいです。
この辺はまたそのうち検討するということで。

継続についてはThe Little Schemerの続きであるThe Seasoned Schemerでページを割いてあるのでそちらも検討してみます。

今回は高階関数の例題を書いてみよー!ということでやってみました。
9LISP の参加者には高階関数やクロージャってなんぞ?な人から、息をするように使う人までいろんな人が参加しています。

高階関数やクロージャというのは、「概念そのものより説明することの方が難しい」という話が前回も出ていました。その点で「値渡しと参照渡し」とか「ポインタ」に似てるよねーと。たぶん継続もそうなんだろうね、ということでした。

ということで、説明うんぬんより実践あるのみということで以下の例題をやりました。
  1. 指定した要素をlistから削除するrember関数を定義する(つまりsrif-1のfilterのような関数)。
  2. list内に要素oldが存在した場合、その隣に要素newを挿入するinsert関数を定義する(挿入位置をパラメータの関数に任せる)。
実際にはまず非高階な関数を定義して、高階関数に書き換えてみる、という手順で進めました。
The Little Schemerの流れと同じです。
rember(非高階)


(define rember
  (lambda (a lat)
    (cond
     ((null? lat) lat)
     ((eq? a (car lat))(cdr lat))
     (else (cons (car lat)
                 (rember a (cdr lat))))))) 
multirember(非高階)

 (define multirember

  (lambda (a lat)
    (cond ((null? lat) lat)
          ((eq? a (car lat)) (multirember a (cdr lat)))
          (else (cons (car lat)(multirember a (cdr lat)))))))
rember*(非高階)

 (define rember*

  (lambda (a l)
    (cond ((null? l) l)
          ((atom? (car l)) (cond ((eq? a (car l))(rember* a (cdr l)))
                                 (else (cons (car l)(rember* a (cdr l))))))
          (else (cons (rember* a (car l))
                      (rember* a (cdr l)))))))
rember-f(高階)

 (define rember-f

  (lambda (test? a l)
    (cond ((null? l) l)
          ((test? a (car l)) (rember-f test? a (cdr l)))
          (else (cons (car l)
                      (rember-f test? a (cdr l)))))))
rember-f(高階)

 (define rember-f

  (lambda (test?)
    (lambda (a l)
      (cond ((null? l) l)
            ((test? a (car l))((rember-f test?) a (cdr l)))
            (else (cons (car l)
                        ((rember-f test?) a (cdr l))))))))
multirember-f(高階)

 (define multirember-f

  (lambda (test?)
    (lambda (a lat)
      (cond ((null? lat) lat)
            ((test? a (car lat))((multirember-f test?) a (cdr lat)))
            (else (cons (car lat)
                        ((multirember-f test?) a (cdr lat))))))))
というような流れです。2のinsertも同じように。

2のinsertの方は、The Little Schemerでは以下のような解答となっています。

 (define insert-g

  (lambda (seq)
    (lambda (new old l)
      (cond ((null? l) l)
            ((eq? old (car l))(seq new old (cdr l)))
            (else (cons (car l)
                        ((insert-g seq) new old (cdr l))))))))
参加者の方からも「冗長だよねー。」とか「きっともっとスマートに書けるはずだよねー、でもどう書いたらスマートだろう?」というような声がありました。

私もそう思います。ということで、考えて書いてみましたが、こんなんでどうでしょうか。srfi-1のfold-rightを使用しています・・・。


(define insert-g
  (lambda (set-f)
    (lambda (new old lat)
      (fold-right (lambda (e l)
                    (cond ((eq? old e)(set-f new old l))
                          (else (cons e l))))
                  '()
                  lat))))

ところd、foldって言語によってfold, reduce, inject, aggregateというように呼び名が違うらしいですね。

The Little Schemer, 4th EditionThe Seasoned Schemer