Hatena::ブログ(Diary)

Scala で TAPLを勉強しつつ LLVM コンパイラを作る日記

2014-12-04 日本人が自信を失った理由

日本人が自信を失った理由

  • 英語が苦手だ。グローバルスタンダードになれない。
  • ローカリゼーションが苦手だ。日本は最高であり、アジア人は日本人のいうことを只聞けば良い。そう思っている節がある。
  • 今のソフトウェアは輸入排他的になっている。
  • 話し合いが苦手だ。嫌われる事を恐れるあまりに本音で話し合わない。数の多い物に合わせるだけだ。
  • 悪者を作って叩いて満足する。
  • 困っている人を叩く。
  • 見る目がない。数が多い所に合わせるだけなので、良いか悪いかではなく、見る目がない。
  • 見た目で決める。
  • 小さくなるパイの奪い合いをしている。
  • パイを作った人を尊重しない。
  • 嘘をついてなんぼである技術なんてお金儲けに必要ないようになってる。ポーカーフェイスモテる
  • 感情を殺す方が良い事になっている。本音が出せず、嘘をつくのでは、幸せじゃないでしょ。
  • お金でしかまとまれない。

2014-08-23 環境破壊の原因

人類のバグ発見した

環境破壊が止まりません。このままでは不味い事は誰でも分かっている事です。

しかし止められません。なぜでしょう?

様々な事が言われていますが、人口は増え続けると、それだけの人達が食べる食料と使うエネルギーが必要になることは明らかです。

人口が増えれば、環境破壊し続けられてることになります

化石燃料を使えば、温室効果ガスが増えて、環境破壊が進みます

ここのところの気象は本当におかしくなっています人ごとではありません。

TEDでは貧困層の人達教育が進んでいないと言っています

一方、ローマ法王経営層の人達自分利益を増やす事を優先しているからだと言っています

どちらの意見も良くわかります。しかし、人口増加が止まりません。

シムシティというゲームがかつてありました。街を作って、道を造り、家を造り、工場や、商業地を作って人が移り住んで来て、犯罪が発生すれば、警察署を作り、火災が発生すれば、消防署を作り、病人が増えれば病院を作り、電力不足になれば発電所を作ります。街は税率をうまく調整して、税金で色々な事を行います

とても面白いゲームでしたが、残念ながら、環境保護についてまで突っ込んだゲームにはなっていませんでした。


仮に、人口増加し続けると、竜巻が発生し、食料危機が起こり農地が荒れるゲームにしたらどうでしょう?人口はある程度まで増やしたらそれ以上は増やしたら不味い事が分かるゲームとなるでしょう。

さて、現実人口増加が進んでいるシムシティと考えて、今後起こる災害で街がめちゃくちゃになるのを防ぐ事を考えてみましょう。

宗教という概念は厄介です。シムシティ宗教はありませんでしたが、現実にはあるのです。宗教を無くせば、いいのかもしれません。宗教禁止令を出して、宗教法人を追い出してみましょう。どうだ?人口増加は止まるか?止まりません。うーん。違うようです。

うーん。じゃあ、経営者を何とかしてみましょう。うーん。税を上げます

引っ越して、逃げていきます。するとどうでしょう。仕事がないと住民悲鳴をあげます。こまったな。町営の起業を作ってみます。うーん。でも人が増えます。なぜだ!

ビルゲイツがなにやら、マラリア対策をしています。これどうなんだろう。

追い出してみましょう。www

ビルゲイツだけではだめですね。

ユニセフっていうのがいて、子供に薬配ってます

こいつらを追い出しましょう。

子供が死んでいきます住民が訴えています支持率は下がりますが、住民は引っ越せません。暴動が起きるので、警察署を沢山作りましょう。落ち着きました。

そして、人口増加が止まりました。これか。。。

結論から書くと、善意による慈善活動優先順位が間違えている結果、環境破壊引き起こしていると思います

ユニセフホームページを見てみましょう。

http://www.unicef.or.jp/cooperate/coop_monthly2.html?utm_source=googlea&utm_medium=cpc&utm_campaign=monthly

栄養失調で失われる命を募金で救おう。病気を予防しとよいことが書いてあります

教育が大切です。確かにそう思います

きっと、薬を配れば、親に感謝される事でしょう。子供は元気になり、成長していく姿を見るのは気持がよい物です。いいことしたなぁと思います

しかし、避妊と家族計画を、人の居住環境や、産まれて来た子供に薬を配って生存率を上げる前にしないと、貧困層の人口増加が止まりません。

家族計画と避妊を先に教えるべきです。薬を買って上げるほうが、楽で喜ばれます。でも、間違えています夫婦で産む子供は2人までにするべきです。これ以上産めば確実に人口が増えます。貧困な家族が2人以上の子供を作れば確実に環境破壊が進むのです。

おそらく、家族計画は良いけど、避妊は宗教家が反対するでしょう。でも、環境問題と人口問題を考えれば、避妊は現実的な解でしょう。

ユニセフが良いことをしようとしているのは分かりますが、優先順位を間違えています

聖書神様は、産めよ増えよ地に満ちよと言いました。しかしもう我々は産んで増えて地に満ちたのです。これ以上増えたらまずいんです。

避妊をせずに薬を配るのは環境破壊を促進するので、望んでいない偽善行為になってしまうのです。

これをはっきり言う事が今の時代必要なのです。

ハッキリ言わないのが人類のバグであり環境破壊をもたらしているのです。

2014-07-08 OCamlでスタックマシン

[]スタックマシン

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
C12+3 *

Cに1があったら、Sに入れます

S1
C2+3 *

Cに2があったら、Sに入れます

S12
C+3 *

Cに+があったら、Sから値を2つ取り出して1と2を足し合わせた3をSに入れます

S3
C3 *

Cの3をSに入れます

S33
C *

Cに*があったので、Sから値を2つ取り出して、3と3をかけた9をSに入れます

S9
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

http://www.cs.cmu.edu/~crary/819-f09/Landin64.pdf

2014-06-22

[][]Yet Another LLVM IR Compiler to X86_64

https://bitbucket.org/h_sakurai/yallc/src

llcmlで書いてみました。

LLVMには依存してなくて、パーサとコンパイラがあるだけです。

出来る事は、四則演算しかないんですけど、これを拡張していけば、

バッグエンドの仕組みが分かるはず。

現状は、スタックマシンJIT結果を吐き出したような形になってますけど、

レジスタアロケーションすればもっと速くなるでしょう。

例えば、mincamlのemitが分かればきっと簡単なはずです。

2014-06-17 [Scala]ScalaのArrayとArrayBuffer

[]ScalaのArrayとArrayBuffer

SwiftのArrayがおかしいって話があったので、たぶん、Scalaなら美しいだろうと思って調べてみました。

package s

object main extends App {
  val a = Array(1,2,3)
  var b = a
  a(1) = 33
  b(0) = 55
  b = b :+ 2
  var b2 = b :+ 2
  println(a.mkString(" . "))
  println(b.mkString(" . "))
  println(b2.mkString(" . "))

  val c = new scala.collection.mutable.ArrayBuffer[Int](1)
  c += 1
  var d = c
  d += 2
  println(c)
  println(d)
}

結果はこんな感じ。

55 . 33 . 3
55 . 33 . 3 . 2
55 . 33 . 3 . 2 . 2
ArrayBuffer(1, 2)
ArrayBuffer(1, 2)

ScalaのArrayはimmutableな変数でも値を代入出来ます

で、追加する時は :+を使って追加しますが、元の配列そのものは変わりません。

なので、中身が変わったおかしいってことはない。

ArrayBufferは完全に中身を共有しているので、

サイズが1としてあって、内部でリアロケーションが起こっても、共有され続ける。

どちらも、訳の分からない事にはならないので、うまく出来てます

import  core.stdc.stdio;
void main() {
  immutable int[] a = [1];
  int[] b = cast(int[])a;
  b[0] = 222;
  b ~= 333;
  printf("%d %d %d %d\n", a[0], b[0], a.length, b.length);
}

結果

222 222 1 2

DMD64 D Compiler v2.060だと、bの長さが変わると、中身もかわるかもしれないが、配列への追加は必ずコピーを行うとは限りません。と仕様にある。

immutableなリストは一部書き換えは出来ないので、変わらないけど、bを書き換えるとaも変わる。bの長さが変わるとリアロケーションされて、書き換えてもaは変わらない。

仕様もそうなっている。

OCaml配列も書き換え可能だ。

MLScalaでは配列は書き換え可能だ。immutableなのは変数そのもので、中身のことではない。

Dのようなネイティブよりの言語はimmutableなリストがないので、immutableな配列は中身も書き換えられないとしているのではあるけど、castして無理矢理取り出せば書き換えられる。という事なのでした。

内部の実装を考えると、immutableってSSA最適化をする場合の書き換えられないレジスタ相当で、書き換え可能名変数はload,storeをする変数と考えるのが実装がシンプルでかつ、最適化するにもやりやすい。

配列の中身を書き換えられないようにする必要性ってあまりないのかなと。配列を使うという事は高速性を求めているということであるし、immutableなデータとしては、ListかMapか、Setを使えば大体事足りるはずだ。

最適化まで考えて仕様を考えれば結構普通なんじゃないのかなとそんな風に思う。

ArrayBufferは良さそうと思うかもしれないけども、ポインタポインタと2段階のアクセスをするのは高速さを求める場合は若干だが遅くなる。だけど、実際のアロケートされている配列サイズは大きく取っておけるので、リアロケーションはたまにしか起こらないから速い。追加操作があると便利だという事もあるのだけど、普通つけない機能だろ。っていう感じだ。