Just $ A sandbox

プログラミングと計算機科学とかわいさ

アレ活が終わっていた

もう5億ヶ月前の話になるのだけどアレ活が終わっていた

これによってとりあえず卒業後の進路は確保できたので路頭に迷ったりニートになる必要はなくなったのでアンシンアンシン

来年から東京の某企業で仕事をするらしい。
何するか具体的にはよく知らないんだけど開発したりしなかったりするんじゃなかろうか〜と思ってる。少なくとも計算機科学を修めたことが無駄にはならない仕事のはず(そうであって欲しい)

アレ活の話も少しだけしておくと、理論計算機科学を使いたい(不可能っぽい)って言いながらやっていて、最終的には設計・フレームワークの開発・堅牢性チェック(品質保障)的なお仕事ないですか〜みたいな感じであれこれ言っていた。 あとScala求人は意外と多くて、あぁScalaって結構業務で使われてるのか。そりゃいい強みだなぁ(Haskellと比べて)と思ったり、あるいはScala求人だからと言ってそこの会社に計算機科学してる人がいるとは限らないんだなぁと思ったりしていた。

あとまぁ、仕事内容も大事だけどそれ以上にどんな人がいてどんな会話ができるか(有り体に言ってしまえば会社の中の人のレベル)って結構QOLに関わってくるので重要やなと思いました。優秀な人がいて、さらに優秀な人を受け入れることにみんな慣れてるような環境を頑張って選んだほうが幸せにはなれそうとかなんとか。

さて後はMの論を書かねばならない。一応結果らしきものは部分的に出ているのであと頑張るだけといえばそれはそう。とりあえず普通にしてれば卒業はできると信じてる。

全然関係ないけど、あと半年ちょっとで20+n年生まれ育った街を離れるのかと思うと中々寂しい気持ちがあるなと思ったりした。せっかくなのでこっちにいる間に色々やっておきたい気もするけど、大文字にのぼるほど暇でも体を動かすのが好きでもないのでせいぜい鴨川を散歩するくらいかな。

おわり

【宣伝】C92で「簡約!? λカ娘 10」が出ます

ほーむ - 参照透明な海を守る会

http://www.paraiso-lang.org/ikmsm/images/c92-cover.jpg

C92にてサークル「参照透明な海を守る会」より「簡約!? λカ娘 10」が出ます。 1日目 金曜日 東た11b だそうです。

今回私も初めて参加させていただきました。


簡約!? λカ娘 10 - 参照透明な海を守る会

モナドとひも」というタイトルで、String Diagramの気持ちをなんとなく理解してもらえればいいな〜という感じの文章を書いたつもりです。Haskell一応書けます、ぐらいの人が対象です。

予備知識なしでString Diagramの計算とか色々見れたらよいなと思っていたのですが、まーそうそう上手く行く例があまり見つからず、あとTikZで図を書くのが死ぬほどつらかったので易きに流れた結果内容が薄くなりました。

一応ウェッブサイトにてサンプル版が見れるので(他の人のもちょこっと読めます)興味あれば見てみてください。

こういう文章書くのはあんまり経験ないんですけど割と楽しかったです。もし次があるならもう少し構成とか諸々考えておくべきだなと思いました。

宣伝おわり。

foldって難しくないですか

foldって難しい、というか書きづらくて読みづらくないですか、と思った話を書きます(そういう感じの話題でTLが盛り上がってたので)

以下、foldをrecursion schemeの観点から理解していることは前提とします

foldをかく

foldを書きたい

foldを書こうと思う場合は自分の場合は明白で、可換monoid積で畳むときは必ずfoldで書きます

sum = foldl (+) 0

これは入力と出力の型が一致していて細かいことを考えなくて良いし、何しているのか見れば分かるし、畳み込み感があっていい感じだし文句はない

ただこういうのは得てしてすでに欲しい関数が定義されてたりする

foldを書きたい??

これがアキュムレータ付き再帰をしたい場合になると若干微妙で、

f xs = go xs 0 where
  go [] acc = acc
  go (x:xs) acc = go xs (x @@ acc)

-- ↑これが
-- ↓こうなる

f = foldl (@@) 0

上が下になるわけですが、下の方が見やすくていいやんけ、と思うじゃないですか? しかし下をパッと書くためには困ったことにfoldlの第一引数の型を暗記している必要があるので私はググるコンパイラがある場面でしか自信を持って下は書けません。

もちろん上より下の方が「良い」コードであることは明白ですが、悪いコードの方が圧倒的に自信を持って書けるのなんかおかしくないかって思いますね。

foldを書きたくない

畳み込み関数がより複雑になる可能性のあるケースでは自分はもうfoldは使いません。それが永久に修正されない、あるいは計算量を保証したいとかでなければもう再帰でいいと思っています。

そもそもこれ以上複雑なケースの場合は自分は一旦再帰の形を経由してしかfoldの処理を理解できないので、わざわざそれを頭の中でやるくらいならおとなしくコードに書けばよいのではないかという気持ちになるからです。

f = go where
  go [] = a0
  go (x:xs) = (なんかめっちゃ複雑な式) $ go xs

-- ↑元の形
-- ↓アキュムレータで書き直す

f xs = go xs b0 where
  go [] acc = acc
  go (x:xs) acc = go xs (さらに複雑な式 x acc)

-- ↓foldで書き直す

f = foldl (さらに複雑な式) b0

例えば一般に何も考えていない時は一番上の書き方をしていて、それをfoldに変えようとすると一旦アキュムレータを使う形に変える必要があります

というわけで真ん中の再帰の形を経由してから一番下に変えるわけですが、一番上から一番下には自分は脳内だけでは変換できません。(脳内ワーキングメモリー足りない人類なので)

そもそも一番下のコードを読むときにも脳内で真ん中の形に展開しないと自分は読めないので、常に真ん中経由なら真ん中でよくないか?ってなるし、計算量とか気にしないならむしろ一番上でいいでしょって思うわけです

この辺は好みや脳内ワーキングメモリーとの相談になりますがプログラムを書く際に極限まで脳みそを使いたくない自分のような人間はこういうケースではまずfoldを使いません。

また、一番上から真ん中は比較的簡単に修正可能ですが、再帰部を色々いじる可能性がある場合も一番下の式で再帰部の形をごりっと書き換えたりするのはかなり大変なので、あとで修正が入りそうな関数も敢えてfoldつかわなかったりします

foldは何がしんどいか

個人的にはこういうことだと思ってる。

foldのつらみを緩和

さて上の3つの問題は例えばこんなふうに書けると割と楽だと思います。

fold {nil: g0} {cons(x): \acc -> gn x acc} xs

まぁ当然タイプ数が増えるわけですが、しかしfoldの引数とnil,consのデータコンストラクタとの対応が見えやすいのでわかりやすいよね? しかもこれなら一般の代数的データ型に対していい感じのsyntaxが提供できるし!(その場合foldという名前はいかがなものかと思うけれど)

しかし当然Haskellではこんなsyntaxはないのでどうしようもないけれど…じゃあ妥協してこういうのでどうかな

instance TaglessList b where
  nil = acc0
  cons = \x acc -> gn x acc

おっ…これならまだ…ってお前tagless finalやんけ!!!

こんな面倒なことするくらいなら素直にfoldでよくないか

ここまで読んだ上でなお「こんな面倒なことするくらいなら素直にfoldでよくないか」と言えるのは多分脳内ワーキングメモリーが有り余ってる人なのでメモリー分けて欲しい

まとめ

  • fold難しい
  • 避けたいし再帰で書きたいけどパフォーマンス上の問題やらを引き起こす可能性が高まるかもしれないことは常に意識しておくべき
  • Haskell(に限らず大体どの言語もだけど)のsyntaxが悪い説もまぁある
  • tagless finalは便利(ただしこれだけだとリストリテラルで表現されたデータは手に入らないので使うときは注意)
  • 頑張って慣れていきましょう