Archive for 2月, 2008

ふつうのHaskell

日曜日, 2月 17th, 2008

『ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門』を買いました。
Haskellの本を買うのは初めてなんですが、私がHaskellに抱いていたイメージとして
「インデントでブロックを表す言語」というものがありまして、まあ、実際その通りなんですが、

「{ }」と「;」を使うと、複数の式を束ねる構文がインデントを使わずに記述できます。
(7.2節 レイアウト)

とあり、実は

main = do {
cs <- getContents;
putStr cs
}

こんな書き方もできるようです。
ああ、これなら読みやすい……と一瞬思ったのですが、
Haskell使ってる方は使ってないような気がします。
(使ってたら、逆にインデントの話の方がマイナーな話になるだろうし。)
だとしたら、あまり使わない方がいいですね。
とりあえず、最初の方は大体読んだので、
たのしみにしていたモナドの説明は明日にでも読めそうです。
ワクワクして寝れなくなったら今日中に読むかもしれませんが(笑)
話は変わりますが、
「car/cdrを使っていたらCommonLispを使う職場で笑われて、
それ以降はfirst/restを使うようにした」
なんて記事を読んだことがあるのですが、そんなもんなんですかね。
本しか読んでないとその言語の常識ってのがいまいち分からないです。

ブラックホールに束縛されている変数

金曜日, 2月 15th, 2008

R6RSのAppendix A. Formal semanticsを読みました。
R5RSの形式的意味論は日本語で呼んでもさっぱり分からなかったけど、
R6RSの形式的意味論は英語でも(*)結構分かった気分になれました。
すこし面白かったのがletrecの説明。

… but it initializes both ordinary variables, and variables that are current bound to the black hole(bh).
しかし、それは通常の変数と現在ブラックホール(bh)に束縛されている変数の両方を初期化する

ブラックホールに束縛されている変数ですよ。ブラックホール。
まあ、天文学のブラックホールとは一切関係ないと思いますが。
(変数に割り当てたロケーションにとりあえず放り込んでおく値です)
あと、気になったのがリストが循環しているか確かめるメタな述語(関係?)

b ∈ 2pp×val×(sf …)
b [[ pp1, pp2, (sf1 ... (pp2 (cons v1 v2)) sf2 ...) ]] if pp1 = v2
b [[ pp1, pp2, (sf1 ... (pp2 (cons v1 v2)) sf2 ...) ]]
  if b [[ pp1, v2, (sf1 ... (pp2 (cons v1 v2)) sf2 ...) ]] and pp1 ≠ v2
(画像版はこちら)

リストに循環部分がないか、これをリストの全ての要素に適用して確かめてるんですが、
これって、リストの途中に循環構造があった場合一生終わらない気がするんですが、いいんでしょうか。

(*)いろんな文章に対して「英語で読んだ方が分かりやすいよ」とかいう言葉を聞きますが、
英語がろくにできない人にとってはどんな文章でも日本語版と英語版があれば、
どう考えても日本語版の方が分かりやすい…そういっても過言ではないかもしれません
いえ、ずばり過言ではないでしょう

外国のニュースグループも案外2ちゃんねると変わらない?

木曜日, 2月 14th, 2008

comp.lang.schemeを見てたら(別の意味で)面白いものがあった。
2ch風に書き直すとこんな感じ。

1.
この問題がわからないです。
助けてください。
~~を定義せよ。
~~を定義せよ。
~~を記述せよ。

クロージャを教えるのは苦労じゃ

火曜日, 2月 12th, 2008

大学に入ってすぐの頃、「クロージャって何ですか」と聞いたときの返答がこれでした。
そのときはCのstaticな変数と同じようなものかと理解したけど、
今思うと遠いような近いような……

R6RSという奴は…

日曜日, 2月 10th, 2008

R6RSではR4RSで登場したsyntax-caseが復活すると聞いていました。
確かに、R6RSの9.2節に
「syntax-caseでもdatum->syntaxを使わなければ衛生的なマクロが定義できる(12.6節参照)」
という説明がありましたが、syntax-caseという言葉が登場するのは恐らくそこだけで、
おまけに、R6RSは11章までしかありませんでした。
でも、よく見てみたら参照と書いてあるのは、標準ライブラリ(*)の12.6節でした。
R6RSの本体が90ページ(付録を除いても60ページ)もあるのに、
標準ライブラリの説明も70ページもあります。
英語がろくに読めない私にはあまりにも過酷です。
仕様書が薄いのがSchemeの特徴だったはずじゃ……
(*) Revised6 Report on the Algorithmic Language Scheme — Standard Libraries
—-
でも、syntax-caseが仕様に戻ったというのは嬉しいです。
syntax-ruleだけじゃ、私には使いこなせない気がするからです。
というのも、去年の夏休み、Common Lispでyaccもどきを作ったんです。
ただ、yaccのようにファイルに記述したBNFを読み取ってソースを吐き出すのではなく、
S式として記述してあるBNFを入力とし、Lispのプログラムを吐き出すマクロとして作りました。
例えば、次のような文法の構文解析器を生成したいとします。

EE+T
ET
TT*F
TF
F→<E>
F→i

この場合は、次のように書きます。
(ここでは、構文解析と同時に計算もするものを作ってます)

(setf (symbol-function 'parser)
(make-parser (E (E '+ T) (+ $1 $3)
(T) $1)
(T (T '* F) (* $1 $3)
(F) $1)
(F ('< E '>) $2
('i) $1)))

そしたら、こんな関数が作られます。


#<CLOSURE :LAMBDA (#:G267)
(LET ((#:G266 '(#:G253)) (#:G268 (POP #:G267)))
(LABELS
((#:G265 (#:G269)
(IF (EQ #:G268 '#:G252) (CAR #:G267)
(CASE #:G269
((#:G264)
(CASE #:G268
((#:G230)
(LET (($1 NIL))
(SETF $1 (PROGN (POP #:G266) (POP #:G266) (POP #:G266)))
(LET ((#:G292 (CAR #:G266))) (PUSH #:G268 #:G267) (SETF #:G268 'T)
(PUSH $1 #:G267) (#:G265 #:G292))))
((*)
(LET (($1 NIL))
(SETF $1 (PROGN (POP #:G266) (POP #:G266) (POP #:G266)))
(LET ((#:G291 (CAR #:G266))) (PUSH #:G268 #:G267) (SETF #:G268 'T)
(PUSH $1 #:G267) (#:G265 #:G291))))
(以下略)

まあ、正直いいものとは言いがたいのですが、
とりあえず、動くものを作ることができました。
けど、実はCommon Lispのマクロをまともに使ったのはこれが初めてでした。
それでも問題なく書けたのは、マクロを使ったといっても、それは最初に入力を受け取る箇所だけで、
後は普通にLispの関数を書きなぐっただけだったからです。
だから、ボトムアップに開発を進めることができて、
関数単位でテストができたので、Cなんかで同じものを作るよりも、
圧倒的にデバッグが楽だったと思います。
しかし、これをR5RS通りのsyntax-caseがないSchemeで作ろうとすると、
syntax-ruleでマクロを書く必要があり、
syntax-ruleでは展開コードはテンプレートで記述する必要があり、
テンプレートからは普通のSchemeの関数を呼び出したりはできないので……
と、考えただけでも恐ろしいことになりそうです。
という訳で、Schemeを使ってマクロ展開コードを生成できるsyntax-caseが
復活したことに私は賛成です。(といっても、syntax-caseをいまいち分かってないんですが(笑))

「偽のゆとり教育」を受けた学生はどうなるのか

土曜日, 2月 9th, 2008

「真のゆとり教育」が生んだ18歳天才プログラマー
ゆとり教育で「情報」の授業が必修になりましたが、
私の高校ではレポート一枚で終わりました。
翌年、その事実が発覚して色々大変なことになりました。

     ____
   /      \
  /  _ノ    ⌒\  偽のゆとり教育というか、
/    (○)  (○) \  本物のゆとり教育を受けたやる夫はどうすればいいお…
|       (__人__)    |   アホプログラマーになれるのか…
/     ∩ノ ⊃  /   
(  \ / _ノ |  |
.\ “  /__|  |
  \ /___ /

カッココッカにしてあげる♪【してやんよ】

            ___
       /      \
      /ノ  \   u. \     なんという歌…
    / (●)  (●)    \    やっぱりLispはネタが多いお…
    |   (__人__)    u.   |    京大にはLisper魔美なんてものもあるらしいし…
     \ u.` ⌒´      /    
    ノ           \    
  /´               ヽ  
 |    l              \
 ヽ    -一””””~~``’ー–、   -一”””’ー-、.
  ヽ ____(⌒)(⌒)⌒) )  (⌒_(⌒)⌒)⌒))
       ____
     /      \
   /  _ノ  ヽ、_  \   世の中は広いお…
  /  o゚⌒   ⌒゚o  \  本を出したり、すごいモノつくってる人たちの中に混じって、
  |     (__人__)    | ゆとり世代の大学生がgauche.nightに出るのは
  \     ` ⌒´     /  無理があったかもしれないお…
            ’ー/.:.:.:.:.:.::::/.:.:.:.:.:.:/.://.:.:.:.:.:.:.:.:.:..:.:.:.:.:.:.:.:.\
            /.:.:./.:::::::/.:.:.:.:.∨.:/ ./.:.:.:.:.:.:.:.:.:.:.:.:.:.:./:.:.:.:.:.:.:ヽ
           /.:.:.:.:/.:.::::::::/.:.:.://X   ,’.:.::.:::.:.:.:.:.:.:.:.:.:.:/ :.:.:.:.:i::.:.:.∧
.         ー–イ.:.::::::::::,’.:.:; ‘    \i.:.:.::::.:.:.:.:.:./.:.::;イ:.:.:… ;    ’,
             /.::::::::/|.:./        !.:::::.:.:.:.:.:,イ.:.::/ |:.:.:.:.:.,’:..     i
              ,’::::::,イ::::::|イ  \    |::::.:.:.:./7ーrー-|–:./.:.:.:.:..  .;
         /i:::;イ::Y.::::::/    \   |:::.:/ //  .|.:.:./.:.:.:.:.:.:.:.:./
         ’´ |//:::,’::::::/  ̄ ̄ ̄   j/       |.:/.:.:.:.::.:.:.|:./
             //|.:::八 :::::::           ___ j/:..:.:.:::.:.:..j/ 大丈夫
      __/´ ̄_) 、 |.::::::∧   ___       \     /.:.:.:.:::::::::.:.:|  だってヴぁ!
      /_: :`: . 、  )ノ |:.::;:’.j/\ i´‘′`ヽ     \ /.:.:.:::::::;イ:.:.:;’  秘策が
.     /_: :`: : 、: :\)’r|.:/ / :¨`r_>、   ,!  ::::::::::: , ‘:.:::::::/|::|.::/  あるってヴァ!
   ,.ノ‐ 、`: :、: :\: :ヽj/ / : : /‐- 、` ¨i´‐rー–‐/.:::::::/_,ノ:.:|/
.  /    \: :\: :ヽ/.’ / : : /    .>’´: : :`ヽ/::.:::::;:イ:::/ヽ:::.:.|
 /        ヽ: : ヽ/: :i i : : ;’   /: : :;-r‐r=r-<´ |:/   \|
       ____
     /⌒  ⌒\     先輩、助かります!
   /( ●)  (●)\    (この先輩は色々とすごいひとだお!
  /::::::⌒(__人__)⌒::::: \   きっといい案があるに違いないお!)
  |     |r┬-|     |  
  \      `ー'´     /   
               / : : : : : : /: : : : : : : : : : : : : : : : : : \
                /: : : : /: : /| : : : : : : : : : : /: : : : : : : : : ヽ
              /: : /: :/: :{/  | : : : : : : /: : /: : : :│: : : : : : '.
          /: :〃: : :,': :.∧  |:l: : : : :./ | :ハ. : : : |: /: : : : : |
        \  /// : : /l: :/ __\ハ: : : : / j/ _,斗: : :j/: : : : :l: :|
.     ―‐-   /'´/⌒V:│;〃アf心ヾ: :Vー孑ゥ≠ミ: : / : : : : : l: |
.    --―     /    V:l小. {ト イ| ∨   f{ノ::Ⅵ ∨: : : :.j: : :| | 「ゆとり代表」って
    _, -'´   {     V: : } Vヒソ     |トーイソ/: : : : ∧.:.:|: | 書いたTシャツを
          ∧      '; : { ''    ' -―v` ー〃: : : : : :/ヽ'; :|: :| 着とけば
          レ ヘ、   ヽ:ゝ ._  f     )′: : : : : /_ノ: V|\| いいってヴぁ!
            \  j/⌒\>ゝ .. _//:.: :/∨: :/\ |
             `/     \ : : :_|厶-―< ^}/|/
           __/  /    マ'弋\ `ヽ\  ∨
          /   {  /   /  ∨ヘ    \\∧
           (____`ー{ _,/    |川     \ヽ|
       ____
     /      \
   /  _ノ  ヽ、_  \
  /  o゚⌒   ⌒゚o  \  先輩はやっぱりすごいお・・・
  |     (__人__)    |  涙がとまらないお…
  \     ` ⌒´     /
(この物語はフィクションです)

最もダメになる「初心者用言語」はC言語

木曜日, 2月 7th, 2008

中学のとき、初めてC言語とやらに触れてみた。
気が付いたら、リリカルLispなんてカオスなものを作っていた。
私がここまでダメになったのはC言語を最初に触れたせいに違いない。

              へ
      __/ |  ` ‐ 、
      /    ハ      ̄ヽ
    | /  /  i l!      丶
    |/  /∧ ∧ハ i   |!  i
    レイV V   VVWV1  |
      }━━    ━━ |   i     「私をダメにした責任、とってもらうからね」
     ⊂ニ⊃       ⊂ニ⊃| !
      | \ 「 ̄ ̄ ̄ ] /|  i  |
      |  ハ`ー┬―‐<   ! レル′
      VV   / !    ハ レレ
      r0へ〈 i   / !
      く    }/  /   ヽ
      \__ノ ̄` し、   〉
       /: : : : : :i: : :\ /
        〈_ _ _ _ _ ヽ_ _人つ
       ’ ; : ; : ; : ; : ; : ; : ; :’

ニコニコ動画でシューティング

火曜日, 2月 5th, 2008

明日でようやく試験も終わりです。
なので、こんなものを作りました。
開く前に注意
「ムービー中のスクリプトが原因で…(中略)…スクリプトの実行を中止しますか?」
というメッセージボックスが表示されますが、ここで「いいえ」を選ぶという問答をなんども繰り返す必要があります。
(私のノートでは10回程でした)

結論:
ニコスクリプトであんまし無茶をやっちゃいけない
ニコスクリプトの開発者の方にはもう少し高速化してもらいたいものです。
あと、もう少し機能を追加して欲しいものです。
最後に、もう少しだけ簡単な文法にして欲しいです。できればS式で。
スクリプトに入れた空白は自動的に取り除かれるようなのですが、
『” “』(二重引用符の中にスペース)のスペースまで取り除くのはどうかと……

R6RSはポータブルじゃない

月曜日, 2月 4th, 2008

R6RSを印刷すると紙の枚数が多くなる。
非常に重い。
持ち運びに不便。
ポータブルじゃない。

Y Combinatorって言いにくいから不動点演算子で。

土曜日, 2月 2nd, 2008

なんか最近(*) Y Combinator(以下『不動点演算子』)の話題が各所であがっていますが、
あれこれ話はあるものの結局のところ、
F(YF) = YF
という式を成り立たせるもの――”不動点”という名の通り、YFをFの不動点にするものだと思います。
(ここの説明が分かりやすいかと。)
不動点演算子自身はこれ以上でも以下でもなく、使い道し次第かと。
記号や演算を最小限にしたのがλ計算だって話もあがってますが、
単純にするならもっと単純にできます。
K ≡ λxy.x
S ≡ λxyz.(xz)yz
この二つを使えば関数抽象(関数の作成)をすることなく、
関数適用(関数の呼び出し)だけで全てを表せます。
例えば、チャーチ数の 0≡λgu.u は ((s ((s (k s)) (k k))) (k k)) と表せますし、
チャーチ数の後者関数 suc≡λxgu.g((xg)u) は

((s ((s (k s)) ((s ((s (k s)) ((s (k k)) (k s)))) ((s ((s (k s)) ((s (k k)) (k k)))) ((s ((s (k s)) (k k))) (k k)))))) ((s ((s (k s)) ((s ((s (k s)) ((s (k k)) (k s)))) ((s ((s (k s)) ((s ((s (k s)) ((s (k k)) (k s)))) ((s ((s (k s)) ((s (k k)) (k k)))) ((s (k k)) ((s k) k)))))) ((s ((s (k s)) ((s (k k)) (k k)))) ((s ((s (k s)) (k k))) (k k))))))) ((s ((s (k s)) ((s ((s (k s)) ((s (k k)) (k s)))) ((s (k k)) (k k))))) ((s (k k)) (k k)))))

と表せます。もちろんこの調子で不動点演算子も表せます。
もっと遊びたい方はこちらへどうぞ。
そういえば昔、JavaScriptを使ったλ計算っぽい話を内輪向けに書いた気がすると思い出し、
探してみたところ、見つかりました。
プログラマは○学生
タイトルからして既におかしいですが、内容もかなりおかしいです(笑)
思えばこれがリリカルLispの原点だったのかもしれません。
あと、『コンピュータプログラミングの概念・技法・モデル』ではλ計算について次のように書いてあります。

λ計算やπ計算のような基本的計算理論は、プログラミングを最小個数の要素に分解する。
そういう要素は数学的解析を単純化するように選ばれていて、プログラマの直感を助けるものではない。
(「はじめに」より)

なんだかこの言葉が最もな気もします(笑)
(*)最近な方々。