Formatの文字列化
OCamlのフォーマッタで文字列化する方法
let spp pp_v () v = Format.fprintf Format.str_formatter "%a" pp_v v; Format.flush_str_formatter ()
OCamlのmliの出力方法
OCamlの型が分からない場合に、推論結果が欲しくなった。
ググってもすぐ見つからない。ということでメモ。
ocaml -i a.ml > a.mli
と書く。
複数ファイルある場合は、
ocaml a.ml -i b.ml > b.mli
関数型言語とオブジェクト指向の融合
そして、SMLがありHaskellがあります。Cleanなんてのもありました。
LispはCLOSというオブジェクト指向のCommon Lisp (CL) のオブジェクト指向プログラミング機能があります。CLOSはRubyに影響を及ぼしているようです。
SMLからCamlが生まれ、Camlをオブジェクト指向で拡張したOCamlが産まれました。OCamlからはさらに、F#が派生しています。
OCamlのオブジェクト指向の拡張はレコードを拡張してオブジェクト指向に使おうとしています。
Lispにアルゴルシンタックスをという意味でDylanが生まれ、その後Nemerleが産まれました。
Scalaは、純粋なオブジェクト指向言語でありながら関数型言語の代数データ型をクラスの継承で表したり、ScalaZといったHaskellの成果を持ち込むようなライブラリも用意されていてよく使われています。
HaxeはActionScript2.0のフリーのコンパイラであるMTASCの後継言語として作成されている言語ですが、完全ではありませんが着実に関数型言語の機能がついて来ています。
Rustはモジラが開発している言語ですがそろそろ1.0が出そうです。
Haskellの型クラスから影響を受けているようです。
GoもまたRustと同じようにHaskellの型クラスのような機能を持ち合わせています。
2014年と2015年
去年は言語をずっと作ってました。
でもまぁ、結構迷走してたかも。
・最初はLLVM向けのC言語でオブジェクト指向がある程度動くようにする。
・型推論と型理論の研究成果を生かさなきゃと方針変更
・MinCamlのシンタックスを変える方向性を探る。
・多相型推論を導入したい
・TAPLが分からず型理論の為に集合論とBNFを勉強する
・型クラスを導入したい
・ATSのスナッチ開発がいいのでLLVMをやめて、CまたはC++を考え始める。
・OCamlのオブジェクトも理解したいのでOCamlを出力する
・ATSの理論を知りたいので論理学を勉強し始める
・選挙あったので色々考えてみる。
・少子化対策を考える
・エネルギー政策を考える
って言う間に2014年が終わりました。
今年はどうなるのか分からないですけど、引き続き言語を開発する為の基礎力を付けて良い言語が作れたらと思います。
よろしくお願いします。
日本人が自信を失った理由
- 英語が苦手だ。グローバルスタンダードになれない。
- ローカリゼーションが苦手だ。日本は最高であり、アジア人は日本人のいうことを只聞けば良い。そう思っている節がある。
- 今のソフトウェアは輸入排他的になっている。
- 話し合いが苦手だ。嫌われる事を恐れるあまりに本音で話し合わない。数の多い物に合わせるだけだ。
- 悪者を作って叩いて満足する。
- 困っている人を叩く。
- 見る目がない。数が多い所に合わせるだけなので、良いか悪いかではなく、見る目がない。
- 見た目で決める。
- 小さくなるパイの奪い合いをしている。
- パイを作った人を尊重しない。
- 嘘をついてなんぼである。技術なんてお金儲けに必要ないようになってる。ポーカーフェイスがモテる。
- 感情を殺す方が良い事になっている。本音が出せず、嘘をつくのでは、幸せじゃないでしょ。
- お金でしかまとまれない。
人類のバグを発見した
環境破壊が止まりません。このままでは不味い事は誰でも分かっている事です。
しかし止められません。なぜでしょう?
様々な事が言われていますが、人口は増え続けると、それだけの人達が食べる食料と使うエネルギーが必要になることは明らかです。
人口が増えれば、環境は破壊し続けられてることになります。
化石燃料を使えば、温室効果ガスが増えて、環境破壊が進みます。
ここのところの気象は本当におかしくなっています。人ごとではありません。
TEDでは貧困層の人達の教育が進んでいないと言っています。
一方、ローマ法王は経営層の人達が自分の利益を増やす事を優先しているからだと言っています。
どちらの意見も良くわかります。しかし、人口増加が止まりません。
シムシティというゲームがかつてありました。街を作って、道を造り、家を造り、工場や、商業地を作って人が移り住んで来て、犯罪が発生すれば、警察署を作り、火災が発生すれば、消防署を作り、病人が増えれば病院を作り、電力不足になれば発電所を作ります。街は税率をうまく調整して、税金で色々な事を行います。
とても面白いゲームでしたが、残念ながら、環境の保護についてまで突っ込んだゲームにはなっていませんでした。
仮に、人口増加し続けると、竜巻が発生し、食料危機が起こり農地が荒れるゲームにしたらどうでしょう?人口はある程度まで増やしたらそれ以上は増やしたら不味い事が分かるゲームとなるでしょう。
さて、現実を人口増加が進んでいるシムシティと考えて、今後起こる災害で街がめちゃくちゃになるのを防ぐ事を考えてみましょう。
宗教という概念は厄介です。シムシティに宗教はありませんでしたが、現実にはあるのです。宗教を無くせば、いいのかもしれません。宗教禁止令を出して、宗教法人を追い出してみましょう。どうだ?人口増加は止まるか?止まりません。うーん。違うようです。
うーん。じゃあ、経営者を何とかしてみましょう。うーん。税を上げます。
引っ越して、逃げていきます。するとどうでしょう。仕事がないと住民が悲鳴をあげます。こまったな。町営の起業を作ってみます。うーん。でも人が増えます。なぜだ!
ビルゲイツがなにやら、マラリア対策をしています。これどうなんだろう。
追い出してみましょう。www
ビルゲイツだけではだめですね。
ユニセフっていうのがいて、子供に薬配ってます。
こいつらを追い出しましょう。
子供が死んでいきます。住民が訴えています。支持率は下がりますが、住民は引っ越せません。暴動が起きるので、警察署を沢山作りましょう。落ち着きました。
そして、人口増加が止まりました。これか。。。
結論から書くと、善意による慈善活動の優先順位が間違えている結果、環境破壊を引き起こしていると思います。
ユニセフのホームページを見てみましょう。
栄養失調で失われる命を募金で救おう。病気を予防しとよいことが書いてあります。
教育が大切です。確かにそう思います。
きっと、薬を配れば、親に感謝される事でしょう。子供は元気になり、成長していく姿を見るのは気持がよい物です。いいことしたなぁと思います。
しかし、避妊と家族計画を、人の居住環境や、産まれて来た子供に薬を配って生存率を上げる前にしないと、貧困層の人口増加が止まりません。
家族計画と避妊を先に教えるべきです。薬を買って上げるほうが、楽で喜ばれます。でも、間違えています。夫婦で産む子供は2人までにするべきです。これ以上産めば確実に人口が増えます。貧困な家族が2人以上の子供を作れば確実に環境破壊が進むのです。
おそらく、家族計画は良いけど、避妊は宗教家が反対するでしょう。でも、環境問題と人口問題を考えれば、避妊は現実的な解でしょう。
ユニセフが良いことをしようとしているのは分かりますが、優先順位を間違えています。
聖書の神様は、産めよ増えよ地に満ちよと言いました。しかしもう我々は産んで増えて地に満ちたのです。これ以上増えたらまずいんです。
避妊をせずに薬を配るのは環境破壊を促進するので、望んでいない偽善行為になってしまうのです。
これをはっきり言う事が今の時代に必要なのです。
ハッキリ言わないのが人類のバグであり環境破壊をもたらしているのです。
スタックマシン
OCamlではリストでスタックを表しパターンマッチで奇麗にスタックマシンを書く事が出来ます。
let rec eval (s,c) = match (s,c) with | `I a::`I b::s,`O "+"::c -> eval (`I(a+b)::s, c) | `I a::`I b::s,`O "-"::c -> eval (`I(a-b)::s, c) | `I a::`I b::s,`O "*"::c -> eval (`I(a*b)::s, c) | `I a::`I b::s,`O "/"::c -> eval (`I(a/b)::s, c) | s, `I a::c -> eval ( `I a::s, c) | `I a::s, c -> a | _ -> assert false let _ = Printf.printf "%d\n" (eval([], [`I 1; `I 2; `O "+"])); Printf.printf "%d\n" (eval([], [`I 1; `I 2; `O "+"; `I 3; `O "*"]))
実行結果:
3 9
です。
このプログラムの構造は関数の末尾で必ず値を返すか、関数呼び出しを行っています。
このようなプログラムは多くの関数型言語では末尾再帰最適化が行われます。
末尾再帰最適化とは、関数の最後の関数呼び出しをジャンプ命令に変換する最適化です。
要するにこのプログラムは再帰的な関数ですが、実は只のループとみなす事が出来ます。
只のループとしてみた場合に、引数SやCは状態を表す変数としてみなせます。
このプログラムはどのように動くか見てみましょう。
S | |||||
C | 1 | 2 | + | 3 | * |
Cに1があったら、Sに入れます。
S | 1 | |||
C | 2 | + | 3 | * |
Cに2があったら、Sに入れます。
S | 1 | 2 | |
C | + | 3 | * |
Cに+があったら、Sから値を2つ取り出して1と2を足し合わせた3をSに入れます。
S | 3 | |
C | 3 | * |
Cの3をSに入れます。
S | 3 | 3 |
C | * |
Cに*があったので、Sから値を2つ取り出して、3と3をかけた9をSに入れます。
S | 9 |
C |
答え9です。
このような構造は1964年にP.J.Landinによって作られたLISPの為の仮想マシンであるSECDマシンで採用されています。
SECDマシンは多くの仮想マシンに影響を与えている有名な仮想マシンです。
64年っていう事はSECDマシンはちょうど半世紀前に産まれたんですね。
60年にLISPが誕生しているので殆どLISPが産まれてすぐに出来たと言ってよいでしょう。
P.J. Landin, ”The Mechanical Evaluation of Expressions”, The Computer Journal, 6:308–320, 1964