放射状

勉強のメモ。

SICP六日目 〜問題1.9

三日で一問ぐらいのペースですが、本当に三日間一日一回は問題を眺めて、ぼんやり答えを予測してそれからまとめて書いています。一度に解こうとしてはいけません。眠くなります。暇なときに頭の隅で考えるぐらいがちょうどいいです。放射氏は多分正面から構えるとだめなやつコレ。

ブラックボックス抽象としての手続き

このへんです。
レキシカルスコープはC系とかの変数のスコープやnamespaceで考えるよりは、javascriptのアレかー、って考えたほうが理解が早いですよね。そのまんまですよね。

var test = (function () {
	var local_value;
	//いろいろやってるところ
}());

こんな感じ。

  • 束縛変数(bound variable)
  • 束縛する(bind)

このあたりは他の本でも出てくる言葉なのでよくよく覚えておく。bindという英単語だとイメージをつかみやすいのに、束縛と言われるとえーっとなる謎。bindは数字を変数にベタッとはりつけてる絵が浮かぶんですが、束縛は普通に亀甲縛りしてる絵ですな。

線形再帰と反復

このへんです。
脳内でシミュレーションして脳がイーッってなるのが再帰で、イーッってならないのが反復だ! と感覚的には分かるんですが(脳内スタックメモリが少ない人になら分かっていただけると思います)、言葉で説明するとなると難しいですね。
関数に代入した変数が確定するまで待たなければいけないのが再帰で、代入した時点で確定しているのが反復、とか。とにかくふわっと覚える。ふわっと。

問題1.9

問題をよく読む。
これはincとdecを実装して動かしてしまうと、「はたしてincで使った+は自分で実装した関数なのかそうじゃないのか。そうだとしてその部分も答えに含める必要があるのか」とか余計なことを考えそうなので、実際の動作確認はしないで答えることにします。あくまでもincとdecは「問題で定義されているそのままの動作とする」ということで。

置き換えモデル - 一つ目

対象はこれですね。

(define (+ a b)
  (if (= a 0)
      b
      (inc (+ (dec a) b))))

脳がイーッってなったから再帰だ。
置き換えモデルで書くと、

(+ 4 5)
(inc (+ 3 5))
(inc (+ inc((+ 2 5)) 5))
(inc (+ inc((+ inc((+ 1 5)) 5) 5)))
(inc (+ inc((+ inc((+ inc(+ 0 5) 5)) 5) 5)))
(inc (+ inc((+ inc((+ inc(5) 5)) 5) 5)))
(inc (+ inc((+ inc(6) 5) 5)))
(inc (+ inc(7 5)))
(inc 8)
(9)

はい再帰的でした。置き換えモデルは自分で書いてみると結構めんどくさいことを学習した。

置き換えモデル - 二つ目

対象はこれ。

(define (+ a b)
  (if (= a 0)
      b
      (+ (dec a) (inc b))))

イーッってしないから反復。
置き換えモデルで書くと、

(+ 4 5)
(+ 3 6)
(+ 2 7)
(+ 1 8)
(+ 0 9)
(9)

反復でした。
しかし毎度毎度問題が本当によくできているなあと思います。最低限で伝えるべき全てを伝えている。

他の方々が書いたSICPのブログをあちこち見てみました

…皆様一章は一瞬で通過しておられました。
フフッ、自分の理解の遅さを客観的に把握するとめげるのでもう見ません。

F#とHaskell参考サイトまとめ

英語が全くできない部下の中の人に面白そうな英語のサイトを教えると悔しがって面白いので、このあたりでまとめておくことにします。これを見て強く生きてほしい。

だがしかし

放射氏は日本語の書籍を買いました。

上のサイトも活用しますけどね!

やっぱり副作用が気になるんじゃ ~haskellもかじることにする~

('A`).。oO(副作用がない世界ってどんな世界なんだろう…)
('A`).。oO(CLISPのモンスター本でもことあるごとに「Haskellもいいんじゃない?」って言っていたっけ…。挙句には副作用警察みたいな漫画まで載ってたっけ…)
('A`).。oO(F#はC#の仕様にどうしても引っ張られてしまう部分があるだろうから、どうしても関数型言語としては妥協せざるを得ないところがあるかもしれないな…(別に根拠はない))
('A`).。oO(気になる…代入の一切ない世界気になる…)

というわけでHaskellはじめました。

環境作成~とりあえずREPLで動きが見られればいい人向け~

例によってぬるいプログラマなのでWindows上で環境構築します。

  1. ここからインストーラをダウンロードしてきてインストール
  2. sublime text 3をインストールしてパッケージコントロールを入れて、以下のパッケージをインストール
    1. IME Support
    2. SublimeREPL
  3. 動作確認。
    1. 最初にsublimeのメニュー「View>Layout」で画面を二つぐらいに割っておく。
    2. Tools>SublimeREPL>Scheme>Haskell」を選択。REPLが立ち上がる。
    3. REPLが出てない方のウィンドウカーソルを合わせて、「1 + 1」とを入力し、「hogehoge.hs」とかそんな感じのファイル名で保存する。
    4. hogehoge.hsを表示しているウィンドウにフォーカスがあることを確認してから、「Ctrl+,+f」を押す。REPL画面のほうに「2」と出たら成功。

環境作成 ~ちゃんとビルドしたい人向け~

意外とこのあたり面倒でした。

  • ↑の作業が終わってから、sublime textに「SublimeHaskell」というパッケージを入れます。
  • そのままsublimeを再起動すると、「hdevtoolsとか入れろよこの野郎」と怒られます。
  • 管理者権限でコマンドプロンプトを実行し、以下のコマンドを順に叩いてください。cabalはHaskellのパッケージコントローラです。
cabal update
cabal install cabal-install
cabal install stylish-haskell
cabal install haskell-docs
cabal install ghc-mod
runhaskell Setup.hs configure --user
runhaskell Setup.hs build
runhaskell Setup.hs install

最後にインストールしたディレクトリのパスが出るのでコピー。

  • sublime textを開いて、メニューの「Preferences >> Package settings >> SumblimeHaskell >> Settings - User」を選択。
{
	"add_to_PATH":
    [
        "C:\\Users\\radial\\AppData\\Roaming\\cabal\\bin"
    ],
    "enable_hdevtools": true
}

こんな感じに書いて保存してください。パスはさっきhdevtoolsをインストールしたときのパスです。

  • sublime textを再起動する。
  • 以下のような感じで打ち込んで「test.hs」とかいう名前で保存する。
main::IO()
main = putStrLn "Hello world!"
  • メニューの「Tools >> Build >> Haskell」を実行。ビルドされてhello world!とか出たら成功。

REPLとSublimeHaskellの併用

普通に動くんだけれど、REPLで動くコードがSublimeHaskellでビルドできるわけではないので(逆も然り。このあたりまだよくわかっていない)、ちょっとSublimeHaskellのエラー表示とかが鬱陶しいなーと思うことがあります。
なので、勉強し始めはREPLだけでいいかもしれませんね。

疲れた

まだぷよクエのガチャピンクッキー集めないといかんのや。