Schemeコードバトンに参加しました

第1回 Scheme コードバトンのお知らせ - higepon blog

  • やったことは、higeponさんのコードがmosh用だったので、Gaucheで動くように最小限の変更を加えただけ
  • 第一印象で「breakのためだけにcall/ccを使ってるんでこれは削除できるなー」と思ったんだけど、自分の技量では泥沼にはまる気もしたので、とりあえずパス
  • moshでやりたい人はhigeponさんのをベース、Gaucheでやりたい人は私のをベースに書き換えるとよいと思います
  • ということで、最初の書き換えとしては妥当かな
  • 変更点
    • 読み込むライブラリをGaucheのものに変更。といっても必要なのはmatchのためのutil.matchだけ
    • (file->sexp-listはGaucheではfile.utilに用意されてるんだけど、こういうのは実装が見えてた方がいいだろうということで、higeponさんの実装をそのまま残した)
    • R6RSのlist-sortとGaucheのsortは引数の順序が逆なので、引数を入れ替え
    • SRFI1のsecondをcadrに変更(これはやらない方がいいかも)
    • 角カッコの対応が合ってなかったところを1個所修正
    • 入出力をコードの順番通りに行うためにflushを2個所追加
    • call-with-port+open-file-output-portをcall-with-output-fileに書き換え

第183回 素人くさいSICP読書会(at 三田某所)

  • 会場提供ありがとうございました
  • 解いていた問題5.17と問題5.18をプロジェクタで発表
  • 問題5.17
  • instを3要素に拡張してそこにラベルを格納する方針
  • extract-labelsの中で、命令を取り出すタイミングでラベルを書き込み。あとはmake-new-machineに「ラベルがあったら印字する処理」を追加
(define (update-label-name! insts label-name)
  (if (null? insts)
      '()
      (let ((inst (car insts)))
        (set-cdr! inst (list (cadr inst) label-name))
        insts)))
(define (extract-labels text receive)
  (if (null? text)
      (receive '() '())
      (extract-labels
       (cdr text)
       (lambda (insts labels)
         (let ((next-inst (car text)))
           (if (symbol? next-inst)
               (receive (update-label-name! insts next-inst) ;;←ここ
                        (cons (make-label-entry next-inst insts)
                              labels))
               (receive (cons (make-instruction next-inst)
                              insts)
                        labels)))))))
  • 問題5.18
  • 基本的には問題5.16と同じような処理をmake-registerに追加するだけ
  • 最初、getという内部関数名を使っていたら意味がわからないと怒られた
(define (make-register name)
  (let ((contents '*unassigned*)
        (trace-on? #f))
    (define (display-when-get)
      (if trace-on? (begin (display name)
                           (display ": ")
                           (display contents)
                           (newline))))
    (define set
      (lambda (value)
        (if trace-on? (begin (display name)
                             (display ": old-value = ")
                             (display contents)
                             (display " new-value = ")
                             (display value)
                             (newline)))
        (set! contents value)))
    (define (dispatch message)
      (cond ((eq? message 'get) (display-when-get) contents)
            ((eq? message 'set) set)
            ((eq? message 'trace-on)  (set! trace-on? #t))
            ((eq? message 'trace-off) (set! trace-on? #f))
            (else (error "Unknown request -- REGISTER" message))))
    dispatch))
  • make-new-machineのメッセージ処理はこんな感じ↓
((eq? message 'register-trace-on)
 (lambda (name) ((lookup-register name) 'trace-on)))
((eq? message 'register-trace-off)
 (lambda (name) ((lookup-register name) 'trace-off)))
  • フィボナッチでは同じ値を代入する処理が思いのほか多かった
  • 組み込みなどでメモリ・デバイスの速度がボトルネックの場合には、こういう場合は代入を行わないようにするとか
  • 「この読書会は恵まれている」(佐野さん)
  • たしかに一人で読むのはつらい本
  • この本にはチューター役と生徒役が必要。どんなに人数が少なくなってもその役割分担は保たれていると思った

Schemeにおけるリファクタリングのパターン

TwitterCommon Lispアンチパターンの話があって、Schemeもリファクタリングの際のパターン(というほど大げさものでもないけど)があるんじゃないかと思ったので、思いつくまま挙げてみる。

  • 再帰に一時変数を導入して末尾再帰にする(基本)
    • consを使った場合には順番が逆になるので最後にreverseをかける
  • 再帰(末尾再帰)からmapやapplyを使う形に書き換える
    • 実際には、mapやapplyが適したケースは最初から自明なことも多いけど
  • 同じ計算を繰り返している部分をletでまとめる
  • 長いlambdaに内部defineで名前を付ける
  • 多値の受け渡しの方法を変更する
    • ペア(またはリスト)にして渡す
    • CPSを使う
    • values/receiveを使う(Gauche等)
      • R5RSのcall-with-valuesって使ってるの見たことないなあ
  • SRFIを使う
    • 目的に合ったシンプルな関数を自作した方がSRFIの関数より高速な場合もある。ケースバイケース


【20:15追記】

  • 複数のmap等でリストを走査している場合、処理をまとめることでリストの走査回数をなるべく少なく抑える

世界一短い(かもしれない)オブジェクト指向フレームワーク「nekoduck」

●ソースコード
(define (object parent . methods)
  (lambda (method-name . params)
    (if (null? parent)
        (let ((root-value (assoc method-name methods)))
          (if root-value ((cadr root-value) params) 'not_found))
        (let ((my-value (assoc method-name methods)))
          (if my-value ((cadr my-value) params) (parent method-name))))))
●使い方
(define オブジェクト名
  (let ((フィールド1 初期値1)
        (フィールド2 初期値2)
                        ))
    (object 親オブジェクト名
            `(メソッド1 ,処理1)
            `(メソッド2 ,処理2)
                          ))))
  • ルートオブジェクトの場合は親オブジェクトとして空リストを指定
  • 外からフィールドにアクセスするにはアクセサを用意する
  • 継承の例は発表資料を参照
●オブジェクトの例(カウンタ)
(define counter
  (let ((c 0))
    (object '() `(up ,(lambda (p) (set! c (+ c 1))))
                `(plus ,(lambda (p) (set! c (+ c (car p)))))
	        `(show ,(lambda (p) c)))))
(counter 'show)
0
(counter 'up)
1
(counter 'plus 5)
6


【追記】
よく見たら親オブジェクトにメソッドの引数渡してなかった。ダメすぎ
引数を一つに限定して、複数の引数を渡したいときはリストを渡すようにすればOKか。コードは略


【2010-03-20追記】
親オブジェクトにメソッドの引数を渡すのはapplyでいいのに気付いた。なんでわからなかったんだろう

(define (object parent . methods)
  (lambda (method-name . params)
    (if (null? parent)
        (let ((root-value (assoc method-name methods)))
          (if root-value ((cadr root-value) params) 'not_found))
        (let ((my-value (assoc method-name methods)))
          (if my-value ((cadr my-value) params) (apply parent method-name params))))))

ついでに、カウンターのplusも任意の個数の引数を取れた方がいいよね

(define counter
  (let ((c 0))
    (object '() `(up ,(lambda (p) (set! c (+ c 1))))
                `(plus ,(lambda (p) (set! c (apply + c p))))
	        `(show ,(lambda (p) c)))))

第182回 素人くさいSICP読書会(at 三田某所)

  • 会場提供ありがとうございました
  • 参加者4名。ほやの干物効果で約1名増員
  • プチ忘年会気分
  • スポーツドリンクが凍ったという話→凝固点/沸点と圧力の話
  • 無線マウスの話→電子レンジの話→マイクロウェーブ・ドライヤー。内側から髪を痛めつける
  • 問題5.18
  • 問題5.17は先週解いたので、適当に雑談しつつ、ぼちぼちやった
  • 基本的には問題5.16とあまり変わらない
  • make-registerは引数でnameを取っているのに内部で全く使っていなかった。実は問題5.18で必要になるということだったらしい
  • 最初、pcをtrace-onして表示が大変なことに
  • うまく動いたっぽい
  • フィボナッチの計算では、レジスタの値を同じ値に書き換える動作が多かった。しょうがないけど
  • マイコンとかだと、書き込みが極端に遅いデバイスを使っている場合には、同値なら書き込みをパスするという判定を入れた方がいいという話とか
  • オレンジニュースについて
  • 二郎で初心者はニンニク入りを頼んではいけないという豆知識をゲット
  • CLの人がおなか空いたと言うので、いつもより20分早く店じまい
  • 今年はこれで終わり
  • 来年は問題5.17と問題5.18の答合わせから始めます

某所でのshiroさん講演のtwitterまとめ

garaemonさん、kabusさん、ありがとうございました

garaemon講演タイトル: Lisp, メタプログラミング, プログラマの使命link
garaemon流しのプログラマってかっこよすぎだろ...link
garaemonプログラマになろうと思ってるひと? => 4, 5人link
garaemonコードを書きたいが本音. 好きなコードをかきまくれるキャリアlink
garaemon今や誰でもコードを書ける時代.link
garaemonがんばってコーディングすればするほどコードベースが大きくなってる.link
garaemon90年代; 昔のUNIXは簡単だった. いまや一人でコードをよめないlink
garaemonはたしてそれで良いのか? >> 膨張するコードベースlink
garaemon文章とのアナロジーで考える. プロの物書きは顧客の満足できる質の文章を書く.link
garaemon多くの人が読みたがる文章を書けるのはプロでもほんの一握り.link
garaemonスタープログラマ. スタープラチナみたいな?wlink
garaemonLinux, matzさんはスタープログラマと言えるのではないかlink
garaemonプログラムは使うもの, 文章は読むものlink
garaemon仕様をみたせば良い, というものではない. 提示するモデルも考えないとlink
garaemonユーザを考えましょうという話link
garaemon対照を最も的確に, 簡潔に記述link
garaemonuser => 自分, peer programmerslink
garaemon問題の記述, 操作, 記述するための言語link
garaemon言語ってのをよく考えよう. いかに問題を記述するか?link
garaemon問題点: ライブラリでいいじゃん => ベースげんご と問題記述言語のミスマッチlink
garaemon抽象的すぎると性能がでない => 処理系が残念link
kabus「抽象的すぎると性能が出ない」のは言語のせいじゃなくて処理系のせいlink
garaemonHaskellでゲームは(一般的には)書けない. でもそれは処理系がよくないんだよlink
garaemonなんで昔の文章はよめるのに, ソフトウェアは昔のものがつかえないんだろう?link
garaemon限られた時間で問題を解決するためにミニ言語をつくったりしてた.link
kabusawkC言語プリプロセッサlink
garaemonゼロ階のメタプログラミング. DSL. T: S' => Slink
garaemonTにdomain knowledgeがうめこまれてるlink
garaemon不適切な抽象化link
garaemonREPLのないサーバプログラムは信用しない(キリlink
kabus「実行中に修正が効くREPLは便利」link
garaemon自分がやったことのあるゲームがshiroさんのプログラムだったなんて! 感動link
garaemonいまこのはなし. http://bit.ly/4oJu4flink
garaemonLispイイ!link
kabusLispイイ!」link
garaemonアプリケーション本体とユーザかくちょう のシームレスな結合link
garaemonユーザ拡張のためのスタブは冗長になっちゃうよねlink
garaemon日本SGI - Onyx2 - http://bit.ly/4NAxoWlink
garaemonMOP ktkrlink
yadokarielectriMeta Object Protocollink
garaemonVRMLってばーむるってよむのかーlink
kabusVRML使ったゲームの話 Schemeで全部書いてVRMLファイルとJavascriptコードを生成link
garaemonVRMLっていうと3dモデル記述フォーマットのイメージ. おなじものなのかな?link
garaemonMOPイイ!link
kabus「MOPイイ!」link
garaemonデータとプログラムの境界は曖昧.link
garaemonprogram as dataのはなしかな?link
garaemon操作されるものと操作するものが同じ言語link
kabus「当時はSTkを使っていました」link
garaemonOODBかーlink
kabusLisp MOPによるOODBlink
garaemonこないだのFranzのLispチュートリアルでもあったなぁlink
kabus「クラス定義がそのままスキーマ定義」「柔軟にスキーマの変更ができる」link
garaemon@ddk50 いまってAllegroGraph? http://bit.ly/5O3WkFlink
garaemonDSLですなぁlink
garaemon緊急時のEmacsによる高速編集wwwlink
garaemonreplはいいよね, やっぱlink
garaemonデモのときにいろいろ大変になってくるのはあるあるwwwlink
garaemonGauche ktkr!link
garaemonCiSEってドキュメントあったっけ?link
yadokarielectrihttp://practical-scheme.net/wiliki/wiliki.cgi?Shirolink
garaemonsuper instructionlink
garaemonCiSE => さいずlink
garaemonコードが増える大きな要因は, 性能のためのっkludgelink
yadokarielectrikludgeってその場しのぎという意味らしいlink
garaemonKahua ktkr!link
garaemonKahua, 永続化. インタラクションの抽象的記述をしたいlink
garaemonCatyスクリプトの構文 - 檜山正幸のキマイラ飼育記 - http://bit.ly/5o5IxNlink
garaemonLispセミナーではなしてたやつ? >> ACL Regex Enginelink
garaemonこれははんぱない...link
garaemon抽象化のレベルを意識せよlink
garaemonad hocな抽象化. 1階の抽象化. 高階の抽象化link
garaemonLispのマクロ. 高階の抽象化. 使い方を誤ると収集つかないlink
garaemonライブラリか構文拡張か? 境界はあいまいlink
garaemon簡潔で本質的なコードを書ける言葉を探すlink
garaemon真のプロはコードを増やすのではなくへらすlink
kabus「簡潔で本質的なコードを書ける言葉を探す」「真のプロはコードを増やすのではなく減らす」「真のプログラマはメタプログラマだ」link
garaemon真のプログラマはメタプログラマlink
kabus「良いコードは読みやすいはず」link
kabusやっぱまずは書いてみてそれから重複してるところをマクロにしていくよねlink
garaemonかきたいこととコードの間の差, こういうことしたいんだからこうかきたい, くりかえし, が抽象化のチャンスlink
kabusみんなメタプログラマになればいいのにlink
garaemon淘汰されるものはよくないモデル, 残っていくものが良いモデルlink
garaemonshibuya.lispでしてたはなしだlink
garaemon質問: なぜLispはやらないの?link
garaemon> がんばって普及させなくていいんじゃない?link
kabus「抽象化して短くなったが少し読みにくくなった => 慣れてないだけかもしれないが,抽象化が不十分なのかもしれない」link
garaemonrubyにあってlispにないものってなに?link
garaemonおわったーlink
garaemon結論: shiroさんかっこいいlink
garaemon竹内先生の挨拶なう. S式重要だよlink
garaemonこれから第二幕link
garaemonフリー質問たいむlink
garaemonR5RSとR6RSlink
garaemonRuby JIS Speclink
garaemonLisp1のほうが好き, という話link
garaemonannotationとかはようわからん. マクロでいいんじゃないとかおもってしまうlink
garaemon最近のゲームでlispつかわれてたのあるよねlink
garaemonconcurrency, parallelのはなし,link
garaemonClojureについてlink
garaemonsrfiについて.link
garaemonrubyのinspect. describeとかformat-objectみたいなもんかな?link
garaemonGCのはなしlink
garaemonone-shot continuation, full-shot continuationlink
garaemonpartial-continuationlink
garaemonthread vs continuationlink

裏で何が起きていたのか

Amazonの履歴によると持ってるはずの「プログラミングの基礎」が見あたらない

yadokarielectric on Twitter: "Amazonの履歴によると持ってるはずの「プログラミングの基礎」が見あたらない"

こないだ日本語訳を買った「プログラミングHaskell」の原著が部屋から出てきて驚いているところ。持ってたんだ…

yadokarielectric on Twitter: "こないだ日本語訳を買った「プログラミングHaskell」の原著が部屋から出てきて驚いているところ。持ってたんだ…"

DS版のウィザードリーが部屋から出てきて驚いているところ。持ってたんだ… というか駄目な人過ぎですね、さっきから

yadokarielectric on Twitter: "DS版のウィザードリーが部屋から出てきて驚いているところ。持ってたんだ… というか駄目な人過ぎですね、さっきから"

もちろんゲームは例によって未開封

yadokarielectric on Twitter: "もちろんゲームは例によって未開封"

やっと見つかった

yadokarielectric on Twitter: "やっと見つかった"

アホす