言語の妄想

長らく言語について妄想をしているので,とりあえず公開状態で書きとめておく.定期的に追記.

Web サーバーとしての機能

超軽量スレッド
プログラムは自前のスレッドで動かし,I/O 待ちや Time.Sleep による待ちで切り替える.必要に応じて時間によっても切り替える.また実行時間を取ることによりそのタスクが処理した正確な時間を取得することにより,昔の Google App Engine のような課金体制 (つまり実行した時間分だけ課金がされる体制) を取ることができるようにする.
メモリ管理の精密化
大量の軽量スレッドを保持できるようにするということはメモリがかなり細分化されるということを意味するので細かな管理を行う.自前のページング機能を実装し長い文字列は分割して持つなどしながら無駄がなるべく無いようにする.

言語としての機能

機能別のネームスペース
System, sys, os 等のわかりにくいものを使わず,ファイル系の処理であれば File,配列系であれば Array クラスの下に置く.名前は基本的に冗長に書く.
部分的に型を導入
引数や変数に型を導入し自動的なチェック機構を入れる.(e.g. function Test(input: String): String {})
最近の LL にある機能の導入
継続,タプル,ラムダ等の導入
プロトタイプチェーンの採用
継承はプロトタイプチェーンで実装し,多重継承は mixin によって行う.
NULL 値の選択
型の最後に ? をつけると NULL を許し,型の最後に ! をつけると暗黙の型変換を許さない.
for/then/else/finally, try/then/catch(exception)/finally 構文の追加
for 文の場合,一度以上回った場合は then,回らなければ else,そして最終的には finally を実行する.try 文の場合はつつがなく終わりまでいった場合は then (ここで発生した例外はこの try では受け取らない),catch(exception) は例外を検出した場合,そして最終的には finally を実行する.
グローバル変数に関して宣言を要求
代入や参照を行う場合,globalで予め宣言するか別の方法で取得する.
constant function
並列化の支援のため,外部変数をいじらない関数を用意する.

データー構造

順序を保持した Dictionary の導入
挿入された順序を持ち続ける Dictionary の導入.
文字列(+immutableな型)のハッシュ化
文字列は必ずハッシュ化して保存する.ハッシュの長さは 64 ビット程度で衝突した場合も想定する.これにより文字列の等価比較が O(1) になり,同じ文字列を大量に生成する場合に効率化される.

FanControl を 64 ビット Lion に対応させてみる

Core i7 が載った MacBook Air を買ったは良いけど,一世代前の MacBook Air に比べて異常にファンの回転数が高くうるさいので急遽 FanControl を入れてみた.が,一向に効果を見せない.32 ビットで実行しているのが悪いのかと思い,コンパイルしなおしてみたがある部分がエラーを吐いて進まない.

どうやらある時から SDK の仕様が変わっているようで,ファンの回転速度: Apple サポートコミュニティBuilding a 64-bit prefpane - Suffix を参考に書き換えてビルドしたところ,どうにか回転数に影響が出るようになった(指定した回転数にはならないけれど…).

実際にビルドしたものとそのソースコードを DropBox に置いたので,必要な方はこちらからダウンロードできるようにしました.インストールはターミナルを開いて sudo make install をした後に再起動すれば成功しているはずです(アンインストールは sudo make uninstall をした後に,元の FanControl 同様に SMC のリセットを行ってください).


ないんたんの予報の読み方

卒業論文では天気予報の研究をしており,独自のアルゴリズムを用いることにより気象庁が発表しているナウキャストと呼ばれる予報よりも 1 時間先の未来まではより高い精度で予報ができることを示した.

大学院に上がり研究室が変わったが,現在も個人的に天気予報の研究を継続している.採用しているアルゴリズムは 1 分単位の細かな予報も可能であり,その実証実験を兼ね,この度 6 月から『ないんたんの予報』を実験的に公開した.梅雨に突入したこともあり,今のところ精度については「@sumi_eee: 最近ないんたん予報あたりすぎてないんたんが雨降らせてるんじゃないかという疑惑」と言われる程度には好評である.

ないんたんの予報は以下の各地域について Twitter Bot とグラフの 2 つを公開している.現在のところ,各地域の主要な大学のキャンパスについてのピンポイント予報を行っている.

Twitter Bot は現在のところ,30 分毎にある程度の降水確率があれば今から先 2 時間半程度について予報を行い降水確率をつぶやくのみである.一方,ないんたんの予報のグラフは,従来の天気予報では見ることのできない雨の強さの確率を用いて表される.そのため,確率に不慣れな人には読むのが難しいという話を聞いた.そこでこの記事は主にグラフの読み方について記述する.

上図は 7 月 7 日 5 時 5 分時点での駒場キャンパスの予報である.ないんたんの予報のグラフは基本的には 50% のラインの色を読み取れば良い.例えばこの図からは,5 時 24 分から 0.1 ミリ時以上の雨が降り始めそうである,ということが読み取ることができる.これは,5 時 24 分の時点では 0.1 ミリ時以上の雨が降っている確率の方が降らない確率より低いのに対して,5 時 25 分の時点ではそれが逆転していることから,5 時 24 分に 0.1 ミリ時以上の雨が降り始めると考えられることによる.

このグラフには 50% のラインの色を読んで得られる情報よりも多くの情報が記述されている.例えば「運が悪ければ 5 ミリ時以上の雨 (緑色) が降る確率が少しあること」や「5 時 59 分から雨が一旦止む予報が出ているが,止む確率は高々 70% 程度しかないこと」が,さらに踏み込んだ情報を読むとすれば「5 時後半に降る雨のピークは 5 時 45 分前後であること」が読み取ることができる.

以上がグラフの読み方であるが,ないんたんの予報を活用する時には以下の点には注意して欲しい.

  • 降水の開始時刻ギリギリを狙わない.多少前後する可能性があるので,10 分程度の余裕を持って行動するのが望ましい.
  • 確率が低いからと言って雨が降らないと思わない.例えば 20% と予報した時は,5 回に 1 度は雨が降る.布団を干している時など,雨が降るとすごく困るような時は行動のしきい値を低めに持つのが望ましい.
  • 短時間 (30 分以下程度) の谷がある場合もそこを狙うことは避ける.谷となっているところは前後に雨が降るということであり,大気が不安定であるということである.大気が不安定な場合は突然雨が降り始めることがあるので,出来る限り一番最初の雨が来る前に行動を起こすことが望ましい.

これらを踏まえた上で,ぜひ『ないんたんの予報』を活用して欲しい

予測不可能は本来灰色で表示されるべきですが,Google Chart API の仕様上,くすんだ赤紫色で表示されることに注意してください.

※ 予報によって起きる損害や不利益に関しては免責とさせていただきます.


~/.ssh/authorized_keys の設定

SSH を使って自動的にトンネルを張ったり,自動的にコマンドを実行させる,ということが非常に多い.その時,自動化する都合で,パスフレーズ無し公開鍵認証を用いることになるのだが,1 つのコンピュータが奪われた時 (物理的にアクセス可能な場合はディスクを直接読み取ることにより漏れる可能性がある),設定に問題があると芋づる式に全てのコンピュータの権限が奪われてしまう.そこで正しく設定をする方法についてのメモ.

特定のポートにフォワードする設定
permitopen="[フォワードするホスト名]:[フォワードするポート番号]",command="/bin/echo",no-X11-forwarding,no-agent-forwarding,no-pty
特定のコマンドのみを実行する設定
command="[実行するコマンド]",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
特定のファイルを書き換える設定
command="/usr/local/bin/scp -t [ターゲットとなるファイルパス]",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty

これらのオプションを (例えば以下のように) authorized_keys の各行の先頭部分で設定を行う.また接続元が決まっている場合は,from オプションを用いることにより安全性は向上させることができる.

from="*.kyoto-u.ac.jp",permitopen="latias.local:3689",command="/bin/echo",no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3Nz...(省略)...R7kw== imos.latias.itunes.port@snorlax


文字化けを起こさず Java コマンドを実行する

Mac OS X にインストールされている Java はお節介にもエラーメッセージを日本語で出し,ターミナルの設定が UTF-8 になっているために文字化けを起こす.その対策のメモ.

alias javac='javac -J-Dfile.encoding=UTF-8'
alias java='java -Dfile.encoding=UTF-8'

上記設定を .bashrc なり /etc/bashrc なりに書きこんでおくと,エラーメッセージを強制的に UTF-8 で出力させることができる.


高解像度デスクトップ画像の作り方

Apple は最近,2560 × 1440 のディスプレイ (27 インチ iMac や 27 インチ Cinema ディスプレイ等) を出している.しかし困ったことに,フルHD (幅 1920 ピクセル) のデスクトップ用画像でさえあまり世の中には存在せず,幅 2560 ピクセルもあるようなデスクトップ用画像などほとんど存在しない.そこで,低解像度向けのデスクトップ用画像をどうにかして高解像度向けに変換できないかと考えた.

Photoshop を使い下記のような手順で画像(左)を処理をすることにより,画像(右)に示すような画像を得ることに成功した.

  1. 元画像を 800% に拡大した画像を得る.(環境設定で画像補間法を「バイキュービック法 - 滑らか」に設定するのが望ましい.)
  2. メニューの「フィルター」の中にある「スマートシャープ」を行う.精細にチェックを入れ,除去方法は「ぼかし (レンズ)」に設定.量や半径は画像によって適切な値を決める.(「200% 5px」や「50% 10px」等を試すと良い.画像(右)は「50% 10px」の設定により得られる.)
  3. 処理した画像を 25% に縮小を行う.(環境設定で画像補間法を「バイキュービック法 - シャープ」に設定するのが望ましい.)

このような用途だけではなく,「スマートシャープ」フィルターは,スキャナーでスキャンした画像をより綺麗にするのにも非常に有効に使えるフィルターでもある.スキャナーの能力を超えた高解像度な画像が得られることが多い.機会があれば試してみては.


2011 年 ICPC 国内予選

今日は ICPC の国内予選がありました.というわけで今年も,ICPC 国内予選結果表を作りました.我らがチーム Flat35 は (おそらく) 無事予選を通過することができました.

チームメンバーは @ir5, @cos65535, @imos です.今回はコーディングは完全に @ir5 君にまかせる形となりましたが,コーディング力はおそらく彼が最も高いので比較的計画通りと言ったところです.しかし,結果表を見てもらえばわかるとおり,上位 4 チームが東京大学で占められてしまったのが多少心残りです.(個人的に,元在学校である大阪大学から,自分が退いた後もアジア地区予選に進出するチームがいるというのは非常に喜ばしいことです.)

次のアジア地区予選以降も頑張りたいところです.


ないんたんと Prolog

ないんたんを Prolog で書き換えようという計画が出ている.

現状,ないんたんは正規表現の塊として書かれている.しかし,文章を解析するには正規表現では少々非力である.そこで,独自の解釈系を書こうと思っていた.そんなところに研究室の輪講で Prolog を用いて「自然言語で書かれたコマンドを DOS コマンド (本の時代の古さが出ている) に変換して実行しよう」という話があった.ないんたんも似たルールで書けるのではないかと思い,実際に書いてみるとあら不思議さらさら書けるではないか.正規表現を書くかのように,文脈自由文法でのルールが書ける

現状,例えば以下のような解釈ができるようになった.

今日のにじゅうに時の天気は何?

→ 天気 ( 時間: ( 日: 今日 ) ( 時: ( 数式: ( 2 ) *10+ 2 ) ) )

「にじゅうに」がひらがなになっているのは実験のためである.当然のことながら 22 でも二十二でも何でも解釈できる.ここまで変換できれば,ないんたんが機械的に処理するのも容易なもの.次のないんたん本体のアップデートに期待がかかるところである.

ただ,ルールが増えたときの実行時間が気がかりなのだが…


#include <vector>
#include <cstdio>
using namespace std;

vector<int> x;

int hoge() {
	for (int i = 0; i < 4; i++) x.push_back(i);
	return 4;
}

int main() {
	x.push_back(2);
	x[0] = hoge();
	printf("%d\n", x[0]);
	return 0;
}

このソースコードの出力結果は実は不定である.gcc でコンパイルし実行した場合の多くは,プログラマーの直感に反して 2 が出力される.これは vector が可変長の配列変数であることに起因する.

可変長変数の実現には内部的には realloc (またはその類の関数) を用いているため,状況によってはメモリの再配置が行う必要が生まれる.gcc では代入演算子 “=” は左側を先に評価する.そのため,代入するメモリ位置を決定した後に,hoge 関数の評価を行う.しかし,hoge 関数内では x に対して push_back が行われ,メモリの再配置が起きるため,再配置前の x[0] のメモリ位置に 4 を代入することとなり,2 が出力される結果となる.

(出典: twitter.com)