Hatena::ブログ(Diary)

hogeなlog

プロフィール

hogelog

hogelog

小室 直(こむろ すなお)。電気通信大学2003年入学。2010年修士卒業。プログラミングとかしてます。

カレンダー
1984 | 01 |
2006 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
2010 | 01 | 06 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 12 |
2012 | 01 | 04 | 06 |

August 28(Tue), 2007

[] makefile

higeponさんのlibcontのMakefileの

TARGET  = ./cont

SOURCES = \
main.c \
mysetjmp.c\
cont.c\
jmp_outside_test.c\
jmp_inside_test.c

このSOURCESの書き方いいなーと思った。今度からたぶん真似する。あと俺は継続の前にsetjmpがよくわかんねえやと気付いた。

トラックバック - http://d.hatena.ne.jp/hogelog/20070828

August 26(Sun), 2007

[][] いいかげんなLisp処理系ぽいの(3)

内部で引数の処理がとてつもなくいいかげんだったのを、かなりいいかげんくらいにした。あとlambdaできるようにしてみた。たぶん。ああ、でも可変長引数はできるようにしてない。(lambda x ...), (lambda (x y . z) ...) みたいの。

> (define fact (lambda (x) (if (zero? x) 1 (* x (fact (- x 1))))))
#closure
> (fact 5)
120
> ((lambda (f x) (f f x)) (lambda (f x) (if (zero? x) 1 (* x (f f (- x 1))))) 5)
120
> ((lambda (f x) (f f x)) (lambda (f x) (if (zero? x) 1 (* x (f f (- x 1))))) (+ 1 2 3))
720

おー。自分で書いておーも何も無いけど。「=」は内部でどういう名前にする名前にするか思いつかんかったのでとりあえずzero?とか追加してlambdaのテスト。今考えるとeqdigitpとかその辺で良かったかな。pってなんの略だっけ。predicateか。

いやあ、趣味グラムはプログラムの内部構成とか好き勝手できまくって楽しいなあ。あと俺Dを本当にbetter Cとしてしか使ってねなと思った。まあそんな人のための言語でもあるよなー。いいかげんにだけど実装してみて感じたが、lambdaは素敵だ。

ソースコード http://konbu.s13.xrea.com/lib/scm/istsp.d

http://www.ice.nuie.nagoya-u.ac.jp/~h003149b/lang/lambda.html 参考にラムダ計算。

> (define _cons
  (lambda (x y)
    (lambda (z)
      (z x y))))
#closure
> (define _car
  (lambda (z)
    (z (lambda (x y) x))))
#closure
> (define _cdr
  (lambda (z)
    (z (lambda (x y) y))))
#closure
> (_car (_cons 1 2))
1
> (_cdr (_cons 1 2))
2

ラムダおもしれー。

トラックバック - http://d.hatena.ne.jp/hogelog/20070826

August 21(Tue), 2007

[] めも。

リビジョン管理ソフトは偉大。CVSはローカルでも普通に使えて便利。

おもしろそう。

http://www.cc.uec.ac.jp/~kazutaka/ptt/index-j.html

* 日程:2007年 9月27日(木)18:30〜

* 場所:慶應義塾大学 矢上キャンパス

* 話者:孝壽 俊彦(慶應義塾大学大学院 高田研究室 後期博士課程3年)

* 題名:仮想マシンを利用したプログラム実行の監視と, そのデバッガへの応用

あと数値計算第二のレポ締切は8/30前後。

トラックバック - http://d.hatena.ne.jp/hogelog/20070821

August 20(Mon), 2007

[] インターンシップ初日した。

漬物会社に研修に。べったら漬け部門にお世話になることになりました。そこではなんとも不可思議な方法で精妙なるべったら味を出していたのですが、しゅひぎむがあるからネットなんかに書くことはできません。

あと昨日あんまし眠れてなかったので、今日はすこししんどかった。会社いて気ー張ってるうちは良かったけど、帰宅がちょうしんどい。途中の駅のベンチで電車2本くらい逃した。

本当はイルカ養殖場の環境管理システムの開発をしてる会社に研修に来てます。社食ではイルカの刺身が食い放題なので毎日楽しみです。

俺が「しゅひぎむ」を気にしつつ日記を書くと、どうやらこういう頭悪い日記になるらしい。インターンシップについては日記を自重する方向性で。

トラックバック - http://d.hatena.ne.jp/hogelog/20070820

August 19(Sun), 2007

[][] lisp処理系ぽいの書いてみたり

間違ってもScheme処理系ではありません。適当に書いてるので、たぶん色々適当です。わりと面白い。

% ./istsp
> (* 10 (/ 9 3) (+ 1 2))
90
> (null? nil)
#t
> (not #f)
#t
> (eof? (read))
322
#f
> (eof? (read))
^D#t
> (cons "hoge" "moge")
("hoge" . "moge")
> (cons "hoge" nil)
("hoge")
> (list 1 2 3)
(1 2 3)
> (append (list 1 2 3) (list 4 5 6))
(1 2 3 4 5 6)
> (print (read))
(+ 3 2 4) 
(#proc 3 2 4)
#undef
> (define "a" (+ 100 200 (* 10 3)))
330
> a
330
> ^DGood-bye

そういえばistspってのはたしか「3分でできるインスタントLisp風味処理系」の略です。3分ではできませんでした。

defineに渡してるものがおかしいですね。びっくりなことにlambdaもありません。そんなもんLispじゃねえ! S式読めるようになったわーい、とかそんなレベルです。ちゃんとした言語の処理系を作ってる人はえらいなあと思いました。あと俺はもっとちゃんとしたプログラムを読んだ方が良いなと思った。

以下ソース。700行くらいだけど、だいじょぶだよねはてなさん。

700行あるコード貼るとうざかったので削除。ソースこっち http://konbu.s13.xrea.com/lib/scm/istsp.d

Machineとか書いてんのは、少しMiniSchemeをイメージした。イメージだけ。codeとか使ってないし。argsとかスタックなんだけど、何故かshift/unshiftでやってたり。あちこちでnewしてるのはなんか嫌だなあとか。まあ冒頭で書いたとおり、適当に書き散らしてるところです。

[][] lisp処理系ぽいの書いてみたり(その2くらい)

Schemeタグ付けるようなもんかよと思いつつ。syntaxぽいのもできるようにしてみた。ユーザ側から関数とかsyntax定義できないから意味無いけど。

ソースこのへん http://konbu.s13.xrea.com/lib/scm/istsp.d

> (define a (+ 10 20 (* 3 8) (/ 9 3)))
57
> a
57
> (if (not #f) (print 100) (print 200))
100
#undef
> (if (not #t) (print 100) (print 200))     
200
#undef
> ((if #f + *) 3 4)
12

処理系書いてて気付いた。

gosh> (+ . ())
0
gosh> (+ 3 4 . ())
7

なるほど。S式はリストでコンスセルなんだよなやっぱり。Schemeを触り初めたとき '(3 4) がリストになったり、'(3 . 5) がコンスセルになったりするのは (list 3 4) とか (cons 3 5) の略記法なのかと思ってたけどそうじゃない。評価してないだけなんだなホント。

null?の実体はop_nullp、consの実体がop_consだったりするんだけど、今は関数の形を

Cell op_nullp();

な形で、引数はMachineのargsスタックから取って、op_consの結果はreturnで返すとかやってる。なんつか歪だ。たぶん全部argsスタックの中に閉じこめて値のやりとりをするようにした方が、後々楽になる気がする。全部

void op_nullp();

な形に書き換えよう。

トラックバック - http://d.hatena.ne.jp/hogelog/20070819

August 18(Sat), 2007

[] lisp処理系ぽいの書いてみてる

なんかまあ割と書けるもんだなあと思った。

% ./istsp
> (+ 32 -40 10)
2
> (cons "hoge" "moge")
("hoge" . "moge")
> (not #f)
#t
> (null? ())
#t
>

ただ、まあ

> (+ 32 22 (- 11 10))
-1211785530
> (cons "hoge" (cons "fuga" "moge"))
("hoge" #proc "fuga" "moge")

全然出鱈目なんですけどね。S式とかそのままリストじゃんーとか思って適当に書いてて、そういやリストと式を見わける方法考えてなかったわぎゃー、とか思った。実装はMiniSchemeを参考にしてるんだかしてないんだか、classとか使ってるけどOOPとかへの無理解具合は何それおいしいの? レベルだしほげほげ。

switch使えて楽かなー思って

enum Type
{
  T_NONE,
  T_STRING,
  T_INTEGER,
  T_CONS,
  T_PROC,
  T_SYMBOL,
}

みたいなことやったけど、例えばT_SYNTAX | T_SYMBOLみたいな複数属性持ちを表わすの楽だから

const T_STRING =         1; /* 0000000000000001 */
const T_NUMBER =         2; /* 0000000000000010 */
const T_SYMBOL =         4; /* 0000000000000100 */
const T_SYNTAX =         8; /* 0000000000001000 */
const T_PROC =          16; /* 0000000000010000 */
const T_PAIR =          32; /* 0000000000100000 */
const T_CLOSURE =       64; /* 0000000001000000 */
const T_CONTINUATION = 128; /* 0000000010000000 */
const T_MACRO =        256; /* 0000000100000000 */
const T_PROMISE =      512; /* 0000001000000000 */

こーいうの用意した方がいいのかなあと思ったけどそれってたぶんOOPじゃねえな。つーか真面目にMiniScheme読んでみるか。長くないんだし。

トラックバック - http://d.hatena.ne.jp/hogelog/20070818

August 17(Fri), 2007

[] FSWikiに自動ログインすんのとメニュー追加するスクリプト

http://konbu.s13.xrea.com/wiki/ 以下のページにアクセスするたびに、ログインアクションを送る。idとパスワードはスクリプト内にベタ書き。こーいうの手軽に自分で書けるのがGreaseMonkeyのいいところだと思う。今更な発言。

// ==UserScript==
// @name           adminmenu
// @namespace      adminmenu
// @description    admin menu@konbu.s13.xrea.com
// @include        http://konbu.s13.xrea.com/wiki/*
// ==/UserScript==

GM_xmlhttpRequest({
  method: 'POST',
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  url: "http://konbu.s13.xrea.com/wiki/index.cgi",
  data: "id=hogeid&pass=hogepass&action=LOGIN",
  onload: function(res){}
});
adminmenu = document.getElementById("admin_menu");
menu =
['<a href="index.cgi?action=NEW" rel="nofollow">New</a> ',
  '<a href="index.cgi?action=LIST">List</a> ',
  '<a href="index.cgi?action=SEARCH" rel="nofollow">Search</a> ',
  '<a href="'+location.href+'&action=EDIT">Edit</a> ',
  '<a href="index.cgi?page=Help">Help</a> ',
  '<a href="index.cgi?action=RSS" rel="nofollow">RSS</a> ',
  '<a href="index.cgi?action=LOGIN">Admin Menu</a> '];
for(index in menu) adminmenu.innerHTML += menu[index];

[] 正しいトイレの使い方

いたす前にトイレットペーパーを敷いておくと、こびりつく可能性が大幅ダウンするよ。

あと8/20からインターンシップいってきます。嘘ですけどマイクロソフト行ってきます。

トラックバック - http://d.hatena.ne.jp/hogelog/20070817

August 15(Wed), 2007

[][] MiniSchemeをD言語で書いてみたよ、と。

ちょーみじかいScheme処理系として有名なMiniSchemeをDに移植した。たぶん動く。

http://konbu.s13.xrea.com/lib/scm/miniscm-d-20070815.tar.bz2

ほとんどそのまま移しただけ。やったのは、先日の日記に書いたScheme関数に対応する関数を書いたことと、GCまわりのコードをばっさり削ったのと、char*でほげほげしてた部分をchar[]でほげほげするようにした、くらい。ああ、あとバグをたくさん仕込んだんじゃないかなきっと。

% ./dminiscm
Mini-Scheme Interpreter written by D Version pre alpha1
loading init.scm
nil
t
caar
cadr
cdar
cddr
caaar
caadr
cadar
caddr
cdaar
cdadr
cddar
cdddr
call/cc
list
map
for-each
list-tail
list-ref
last-pair
head
tail
quasiquote
atom?
memq
equal?
do
> (define (fact x) (if (= x 0) 1 (* x (fact (- x 1)))))
fact
> (fact 5)
120
> (define (f)
    (call/cc (lambda (escape)
        (begin (display 1) (newline)
               (display 2) (newline)
               (escape 10)
               (display 3) (newline)))))
f
> (f)
1
2
10
>

call/ccもできてるわーすごい。どうやって実装してんのかは全然理解してないんですけど。あともちろん

> 3.0
Error: Unbounded variable 3.0

>

浮動小数点数はサポートしていません。ほんとにMiniSchemeをそのままDで書いただけ。

Dのプログラムとしては、たぶんおもしろいことはなんもしてません。どっちかっつーと、MiniSchemeのコードの理解を深めるためにやった。D的なコードへの書き換えとか、機能の追加とかはこれから。たぶんやる。

[] 驚異の情報科学若手の会効果

「情報科学の人が集まるような所に行くんだから、恥ずかしくないようになんかしなきゃ!」と焦ったおかげでMiniSchemeのDへの移植速度が倍増した。これで「Schemeの処理系を書いたこととかあります」とかハッタリを言えます。ほとんど嘘ですけど。やったのは、プログラムによる自動変換レベルのC->D移植。

それにしても、参加する前から効果があるなんてびっくりですね!

はやみずさんに感謝します。会場ではsuu-gさんとはやみずさん礼賛でもしてようかなと思います。

俺が参加を躊躇う理由はsuu-gさんの後者の理由ですね。「俺なんかが参加してどこかの有能な人とか、将来有望な若者が参加できなくなったりしたら申し分けないじゃないか」と。「実力不足が恥ずかしい」は、たぶん無いかな。俺が実力不足で学力も努力も不足してるなんてのは、自明のことだから、今さら恥ずかしがるとかねーかなー、みてーな。留年したりほげしたりぴよしたりする過程で、「ひらきなおる」ということを憶えました。

なんか発表とかもしたいけど、発表することとか思いつかねえなあ。少しでもネタになりそうな俺の中にある知識っつったら、Java2D->Postscript変換とか、MiniSchemeのこととかくらいだろか。「3分でできるLisp処理系」とかそういうのやろうか。できねえよ。

h_sakuraih_sakurai 2007/08/15 20:24 SECDマシンの変形らしいです。
このMiniScheme使って、パーサ作ってS式に変換して、俺MLisp作ったりしたよ。

suu-gsuu-g 2007/08/15 21:59 suu-gです。やー何かとお恥ずかしいです。
結果としては人数は7月中には埋まらなかったようで、二つめの理由は杞憂だったみたいですね。
当日はよろしくお願いしますね。やる気出てきたー!

hogeloghogelog 2007/08/15 23:04 >sakuraiさん
なんとはなしに微妙に聞き覚えありましたが、これが miniscm.c だと args, envir, code, dump と名付けられてるやつですね。そう考えるとかなり読みやすくなりそうです。正直「なんだこの変な処理の仕方! 読みにくい!!」とかアンポンタンなこと思ってました。情報あざす。
http://ja.wikipedia.org/wiki/SECD%E3%83%9E%E3%82%B7%E3%83%B3
今ためしにちっちゃいLisp処理系書いてみたりしてるんですけど、やっぱ動く処理系のコード読んだ後だと、以前何度か挫折したときに比べてかなり楽に書けます。

>suu-gさん
ええ、正直安心してしまいました。当日はおもいっきり恥でもかくことを目標に、それまでせいぜいネタでも探しときます。

hogeloghogelog 2007/08/15 23:21 あがー。
s/これが miniscm.c だと/これがSECDマシンとやらですか。miniscm.cだと/

August 14(Tue), 2007

[] MiniScheme 読んだり書きかえたり

miniscm.cを書き換えたりしてた。

miniscm.cをGNU GLOBALでHTML化したものオリジナルのminiscm.c

オリジナルのMinischemeでは各種Scheme関数をswitch-caseで呼んでいる。それぞれのScheme関数はopexe_0関数からopexe_6関数のどれかに属する。

オリジナルminiscm.cのScheme関数呼び出しの流れ

  • 各種Scheme関数のユニークなshort値operatorを用いて、dispatch_table[operator]でまずopexe_?関数のアドレスを得る。
  • opexe_?(operator)呼び出し
  • opexe_?内でswitch(operator){case ???: ... }でScheme関数に相当するコードを実行

opexe_0からopexe_6までに分けてるのは、たぶんswitch-caseのcaseが大量になると効率が下がるからかなと思える。でもそれなら、Scheme関数に対応するCの関数書いて、ユニーク値と関数アドレスを対応付けたテーブル作ればいいんじゃねの? と思ったので安易にそうしたりした。miniscm.cのop_hogehogeな関数がそれ。挙動はたぶん変わってない。

オリジナルのコードがそうなってないのはきっと昔は実行効率のためにgotoで飛びまくるコードだったからだろな、と。元々のコードは1989年のものだし。

よくわかってないとこ

gcまわり
読む気無し。
入力解析あたり
tokenとかから始まる、parseの流れがよくわかってない。これは今から読む。
inchar内のstrcpy
無くても挙動変わらんような……
トラックバック - http://d.hatena.ne.jp/hogelog/20070814

August 10(Fri), 2007

[][] X11 bindings for D いじり。

誰か既に書いてておかしくない気もするのだが、何故か見あたらないので書いた。D言語使いの人って Windows ユーザに多いからだろか。

一応まとめてアップ。tinywm.d も同梱。

http://konbu.s13.xrea.com/lib/d/libdx11-20070810.tar.bz2

import Xlib;してる hoge.d をコンパイルするには

% dmd Xlib*.d hoge.d -L-lX11 -L-L/usr/X11R6/lib

と。たぶんそれが無難かなーと思う。

ごちゃごちゃしてたのでいくつかに切り分けた。

Xlib.d (ライブラリのトップレベル、あといくつかDから呼ぶのに便利めな関数を定義したり), Xlib_types.d (型定義), Xlib_define.d (定数定義), Xlib_funcs.d (関数定義)。

試しにライブラリ化してみた。DMD_HOME/src/phobos/linux.mak など参考に。

% dmd -c -w Xlib.d
% dmd -c -w Xlib_define.d
% dmd -c -w Xlib_funcs.d
% dmd -c -w Xlib_types.d
% ar rv libdx11.a Xlib.o Xlib_define.o Xlib_funcs.o Xlib_types.o
ar: libdx11.a を作成します
a - Xlib.o
a - Xlib_define.o
a - Xlib_funcs.o
a - Xlib_types.o
%

一応 tinywm.d をコンパイルできることは確認。

% dmd tinywm.d -L-lX11 -L-L/usr/X11R6/lib -L-ldx11 -L-L.
gcc tinywm.o -o tinywm -m32 -lX11 -Xlinker -L/usr/X11R6/lib -ldx11 -Xlinker -L. -lphobos -lpthread -lm
%

ただまあ問題があって、-ldx11 を tinywm.o の前にもってくるとコンパイルできない。

% gcc -ldx11 tinywm.o -o tinywm -lX11 -L/usr/X11R6/lib -L. -m32 -lphobos -lpthread -lm
tinywm.o(.data+0x30): undefined reference to `_D4Xlib12__ModuleInfoZ'
tinywm.o(.gnu.linkonce.t_Dmain+0x49): In function `_Dmain':
: undefined reference to `_D4Xlib13DXOpenDisplayFAaZPS10Xlib_types9_XDisplay'
tinywm.o(.gnu.linkonce.t_Dmain+0x68): In function `_Dmain':
: undefined reference to `_D10Xlib_funcs17DefaultRootWindowFPS10Xlib_types9_XDisplayZk'
tinywm.o(.gnu.linkonce.t_Dmain+0x88): In function `_Dmain':
: undefined reference to `_D4Xlib16DXStringToKeysymFAaZk'
collect2: ld はステータス 1 で終了しました
%

libdx11.a 内に定義がある関数が見えないとか言う。なんだろうこれ。-lX11, -lphobos なんかはもちろん、順序を変えてもコンパイル通る。

なんかよくわからんけど、ライブラリファイルの作り方を間違えてるみたいだ。まあ、別にライブラリ書きたいわけじゃなくて X11 いじりたいだけなんだから、dmd Xlib*.d hoge.dでいいやという気分になってきた。ライブラリっぽくしたとしても、-L-ldx11とか書かなきゃいけないんだし似たようなもんだ。どうせ基本 make だし。

とりあえず、ちまちま修正しながら使う程度にはできたかなあと思った。さて。ウィンドウマネージャーを書こうか。書かないかも。

トラックバック - http://d.hatena.ne.jp/hogelog/20070810

August 09(Thu), 2007

[][] AutoPagerize べんりだ。

はてなで言う前の5日とかをいちいちクリックしなくてよくなる。

トラックバック - http://d.hatena.ne.jp/hogelog/20070809

August 08(Wed), 2007

[] 末尾再帰

俺は「末尾再帰」という言葉を知ってからもしばらく意味がわからんかった。でも「末尾呼び出し」という言葉を知って、簡単に理解できた。

int fact(int x){
  if(x == 0) return 1;
  else return x * fact(x - 1);
}

x == 1 じゃなかったときの最後の命令は「*」。fact は末尾呼び出しじゃない。

int fact(int x){
  return fact_tail(1, x);
}
int fact_tail(int a, int x){
  if(x == 0) return a;
  // else return fact(a*x, x - 1); コード間違ってた。正しくは以下。
  else return fact_tail(a*x, x - 1);
}

の fact_tail で x == 0 だったときの最後の命令は fact 呼び出し。これは末尾呼び出し。ちなみに末尾呼び出しで自身を呼び出す関数のことを特に末尾再帰と言ったりする。

403 Forbiddenで Shiro さんがちらっとコメントしてるけど、末尾再帰だから最適化できるというか末尾呼び出しだから最適化できる。

普通の関数呼び出し命令っていうのは呼ぶときスタック積んで返すときスタック下ろしてと、オーバーヘッドがかかるわけですね。でも末尾呼び出しはそんな手間のかかる「呼び出し命令」じゃなくてジャンプ命令で関数を呼ぶことができます。以下に例を。

% cat tailcall.c
#include <stdio.h>
void fuga(){
  puts("Hello!");
}
void hoge(){
  fuga();
  fuga();
}
int main(){
  hoge();
  return 0;
}
% gcc -S tailcall.c
% cat tailcall.s
        .file   "tailcall.c"
        .section        .rodata
.LC0:
        .string "Hello!"
        .text
.globl fuga
        .type   fuga, @function
fuga:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        subl    $12, %esp
        pushl   $.LC0
        call    puts
        addl    $16, %esp
        leave
        ret
        .size   fuga, .-fuga
.globl hoge
        .type   hoge, @function
hoge:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        call    fuga
        call    fuga
        leave
        ret
        .size   hoge, .-hoge
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        call    hoge
        movl    $0, %eax
        leave
        ret
        .size   main, .-main
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.3.6 release (Vine Linux 3.3.6-0vl7)"

普通にアセンブルしたら fuga(); は

        call    fuga
        call    fuga

となってますね。ほんじゃ gcc さんにちょっと頑張ってもらって、

% gcc -S -O2 tailcall.c
% cat tailcall.s
        .file   "tailcall.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "Hello!"
        .text
        .p2align 2,,3
.globl fuga
        .type   fuga, @function
fuga:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $20, %esp
        pushl   $.LC0
        call    puts
        leave
        ret
        .size   fuga, .-fuga
        .p2align 2,,3
.globl hoge
        .type   hoge, @function
hoge:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        call    fuga
        leave
        jmp     fuga
        .size   hoge, .-hoge
        .p2align 2,,3
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        call    hoge
        xorl    %eax, %eax
        leave
        ret
        .size   main, .-main
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.3.6 release (Vine Linux 3.3.6-0vl7)"

なんと末尾呼び出しの fuga() が jmp 命令に置き換わってますね。

        call    fuga
        leave
        jmp     fuga

そんなわけで関数呼び出しのコストが減ってうれしいなあと。

ほんで末尾呼び出しがジャンプ命令になるならば、末尾再帰は単純なループになるっていうのは自明なことですね。

fuga の puts も末尾呼び出しだけど、あっちはもう puts の実体が「スタックから引数下ろしてきてコード実行!」みたいになってるからジャンプ命令には置き換わりません。


たぶんこんなかんじ。

[][] uBLAS べんりだ。

std::cin から行列、ベクトルへの入力も用意されてる。

% cat helloublas.cpp
#include <iostream>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

int main()
{
  using namespace boost::numeric::ublas;

  matrix<int> a;
  vector<int> v;
  std::cin >> a >> v;
  std::cout << "a = " << a << std::endl << "v = " << v << std::endl;

  return 0;
}
% g++ helloublas.cpp
% ./a.out
[2,3]((1,2,3),(4,5,6))
[5](1,2,3,4,5)
a = [2,3]((1,2,3),(4,5,6))
v = [5](1,2,3,4,5)

C++ の stream とかどうなんだろうなあと思ってたけど、この辺は便利。この辺までやらんと stdio のが便利な気するけど。

ついでにこの辺使ったガウス消去とかも書いた。

% cat in_gauss_elim1
[3,3]((8,2,1),(3,5,4),(4,1,7))
[3](4,8,0)
% ./gauss_elim <in_gauss_elim1
[3,3]((8,2,1),(3,5,4),(4,1,7))x = [3](4,8,0)
x = [3](0.0904977,1.79186,-0.307692)

ちゃんとできてる。

以下コード。

続きを読む

トラックバック - http://d.hatena.ne.jp/hogelog/20070808

August 07(Tue), 2007

[] ややこしいヤコビ法

ヤコビ法と呼ばれるものには行列の固有値および固有ベクトルを求めるものと、連立方程式を反復法で解くものがある。

日本語におとしこむ際にどっちも同じ名前になっちゃったというわけではなく、どっちも「Jacobi method」と呼ぶようだ。Wikipedia では違う名前で登録されてるけど。ちなみに日本語 Wikipedia だと後者しか無い。(ja.wikipedia:ヤコビ法) 前者は長くて大変そうだからかな。

いやちげーな。

後者は前者を削ぎ落として連立方程式を解くアルゴリズムとして簡単化したものってことか。en.wikipedia:Jacobi methodの方に

This algorithm is a stripped-down version of the Jacobi transformation method of matrix diagonalization.

って書いてあった。

トラックバック - http://d.hatena.ne.jp/hogelog/20070807

August 06(Mon), 2007

[][][] こんにちは uBLAS

大学のレポートでほげほげな数値計算してねー、とかいうのがあった。そんな課題がある度に毎回 C言語でうさんくさい行列計算ライブラリみたいの作ったりしてたけど、もうそんな無駄はやめよう。boost::numeric::ublas を使うことに。当該講義の教官は「うちの研究室では今 Boost のライブラリ使ってる」と言ってんで、読みなれてるでしょうし。C++ ってほとんど使ったこと無いけど、まあなんとかなんべ。

参考。

とりあえず単純なガウス消去(ピボット選択とかしないやつ)でも試してみる。

#include <iostream>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

using namespace boost::numeric::ublas;

vector<double> gauss(matrix<double> a, vector<double> v)
{
  vector<double> result(3);
  for(int i=0;i<a.size1();++i){
    for(int j=0;j<a.size1();++j){
      if(i==j) continue;
      double mj = a(j,i)/a(i,i);
      for(int k=0;k<a.size2();++k){
        a(j,k) -= mj*a(i,k);
      }
      v(j) -= mj*v(i);
    }
  }
  for(int i=0;i<v.size();++i)
    result(i) = v(i)/a(i,i);
  return result;
}
int main()
{

  // 行列 (8 2 1)
  //    (3 5 4)
  //    (4 1 7)
  matrix<double> a( 3, 3 );
  a(0,0) = 8;
  a(0,1) = 2;
  a(0,2) = 1;
  a(1,0) = 3;
  a(1,1) = 5;
  a(1,2) = 4;
  a(2,0) = 4;
  a(2,1) = 1;
  a(2,2) = 7;

  // ベクトル (4 8 0)
  vector<double> v(3);
  v(0) = 4;
  v(1) = 8;
  v(2) = 0;

  std::cout << a << "x = " << v << std::endl;
  vector<double> x = gauss(a, v);
  std::cout << "x = " << x << std::endl;

  return 0;
}

出力

[3,3]((8,2,1),(3,5,4),(4,1,7))x = [3](4,8,0)
x = [3](0.0904977,1.79186,-0.307692)

えーと?

gosh> (define (f x1 x2 x3) (+ (* x1 .0904977) (* x2 1.79186) (* x3 -0.307692)))
f
gosh> (f 8 2 1)
4.000009599999999
gosh> (f 3 5 4)
8.000025100000002
gosh> (f 4 1 7)
6.799999999529405e-6

正しいみたいだ。よーし良かったー。

ではない。uBLAS を使ってレポートにとりくむのが目的だった。さて。LDV分解とかちまちま書くか。

トラックバック - http://d.hatena.ne.jp/hogelog/20070806

August 04(Sat), 2007

[] いきおいで

申し込んでしまった。

http://wakate.aitea.net/2007/

もう受け付けされたよ。これはもう観念して楽しみにするしか無い。インターンシップ終えた翌日からですが。やあ、楽しい夏休みだね。

[] LLSpirit行ってきたレポ。

色々正確ではありません。なんかメタメタですけどもう投稿します。一部創作ですたぶん。

先に感想

おもしろかったすよ。思ったより普通の話をするイベントだった。

至会場

俺は迷ったけど、事前に場所を調べておけばわりとわかりやすい場所にあったと思う。来年は中野ZERO らしいんで、かなりわかりやすいと思う。

基調講演 (和田 英一)

迷ってちょっと遅刻したんで初めの方はわからない。ハードウェアの話として楕円を描く機械とか微分する機械の話をしたりしてくれました。が、俺は未だ微積分がよくわからない大学生なもんで、「ストアドプログラム方式の世界で活動してて良かった俺」などと呆けていました。

Language Update

Perl (小飼 弾) http://blog.livedoor.jp/dankogai/

Perl6 のオハナシ主に Perl5.10 の話。Perl6は宇宙人に任せておいて、凡人向けに Perl5.10 を紹介します。

feature プラグマで一部 Perl6 の機能が先取りできる!

say は puts より1バイト短かいし素敵!

$==$///$;

とか、より一層謎なコードが書けるようになる!

C の static 相当の state 変数、C の switch 相当の given 〜 when をサポート。この辺普通に便利そうな気がした。

Regexp が trie最適化するように。えーと確か「(とかちつくちて|とかしつくして) を自動で とか(ち|し)つく(ち|し)て にします」とか言ってたような。えーとこれだと後方参照が変わっちゃうから駄目だけど、なんかそんな感じのことを。今時正規表現も最適化しなきゃ! みたいな。弾さんはそんなこと言ってなかったけど。

Io (浜地慎一郎 id:shinichiro_h) http://shinh.skr.jp/m/

シンプルなプレゼン(大きめテキスト)非常に流麗なるマシンガントーク。

Io はシンプルな言語。予約語0個に、BNF は 5行くらい(みたいなもの)。言語仕様とかが尋常じゃなく変わりまくるので楽しくてしょうがないですね! というようなハッカーすぐる発言が印象的。

プレゼン最後に「実はこのプレゼンも Io で書かれてます」と白状するメソッド。

Clean (id:lethevert)

言語としては Haskell とかなり似てる。Haskell と違う点はたくさんあるけど、入出力は一意型というものでおこなう。第一線の研究者が開発してる言語です。とりあえず「速いよ!」。

自作のプリプロセッサ CleanX の紹介。

PHP (Seiji Masugata)

PHP処理系のバグとの戦いは熾烈なもの。「PHP は叩かれる宿命にある!」

R (樋口 千洋)

S言語と Scheme にかなり影響を受けた言語。大きな特徴としては、S言語は動的スコープなのに対し、R は静的スコープ。

Python (柴田 淳)

Pythonはエンタープライズ用途で多用されています。何故か。

Pythonでは「たったひとつの冴えたやりかた」が好まれるとか。後方互換を大事にするとか。思想や仕様、ロードマップが明確だとか。

でも 3.0 では思想優先にして互換性を一部捨てますんで御注意。

Lua (上野 豊)

つまみをクルクルまわすUIが素敵だった。すいません、あと忘れてしまいました。

(Language Update まではリアルタイムでメモ取ってなくて、あとで思い出しながら書いたので)

Ruby (まつもとゆきひろ、笹田耕一)

matzさん嘘つき。ささださんmatzさんをフルボッコ。

matz「VM で Ruby は 2〜500倍速くなる」「俺は lazy をサポートしたぞ Larry!!」「Ruby 2.0 はじまる」

ささだ「嘘つくな」

オレ様言語の作りかた

ひまわり (クジラ飛行机)

主にバッチ処理をする、便利なコマンド集のような言語。プログラミングの敷居を下げること目的。

とある中学生曰く「英語じゃやる気しなかったけど、日本語だからやってみようと思った」。

「作った後にふりかえると、良かった点は日本語プログラミング言語にしたこと。悪かった点は日本語プログラミング言語にしたところ」に会場爆笑。

xtal (石橋 立宜)

主にゲーム製作用途のスクリプト言語。

GCで大きな停止をしないこと、モダンな機能(高階関数、例外、デフォルト引数、fiber、……)、バイトコードへのコンパイル、ネイティブスレッド、OOPなどの特徴あり。ベンチマークも Lua に匹敵するほどけっこう高速。C++との連携(Luabind, Boost.pythonのような)を標準でサポート。

緊張してることがよくわかる発表でしたが、でも発表自体はわかりやすかったですね。緊張しまくってて発表もわかりにくかったら見てる側もアワワな気持ちになるのでしょうが、そこは大丈夫だったんで逆にかなり笑いをとってるスピーチとなってました。

モダンな機能がプリミティブに組み込まれてるってのがDリスペクトだったりするのかなーと思った。

Sukuna (小原 広之)

Forthリスペクト言語。ほぼ Forth とのこと。

「最初はBrainf*ck処理系を参考に書き始めた」!!!

どうでもいいけどターミナルのフォントがみかちゃんフォントだった?

crowbar, Diksam (前橋 和弥)

プログラミング言語の作り方の記事を書く中でのサンプル言語。

言語を作った動機

某作者「好きな女の子に『こんなん作ろうと思ってる』と言ったらすごい感心されたから気を魅こうとして」!!!

それだ!!!!!!

会場が拍手で満たされる。

VM魂

ざっくりいいかげんに。

JRuby (高井 直人)

JRuby最強説。

enebo → はかたラーメン

誰かソードワークスとかいう会社で働いてる → 東京トイボックス?

Jython (西尾 泰和)

Java のオブジェクトを Python から簡単に呼べるよーと、フィボナッチ数列を可聴化してみたり。

IronPython (荒井 省三)

.NET で色々な言語が動くようにするプロジェクト進行中。Python のオブジェクトを JS が使えたりとか、クロスランゲージな色々ができる。もちろん .NET のオブジェクトも全部使える。

Pnuts (戸松 豊和)

小さくシンプルで速く、Java との親和性を重視。JVM で高速に動作させるには様々なコツがある。

Rhino (鈴木 雄介)

元は Javagator のために作られてた。後に Javagator ポシャるも、Rhinoプロジェクトは何故か続けられる。その後も様々な困難に見舞われるが、何故か地道に続けられる。最近は JRuby に脅威を感じたか、プロジェクトが急に活発になってるみたい。Java との連携に難有りとのこと。

キミならどう書く プレゼンソフトを作る

「一般の人が使えるようなプレゼンソフトを作ってください」というお題。

OCaml (小笠原 啓)

ロック機構によるマルチスレッドプログラミングはデッドロックを避けるための苦労がめんどう→チャンネルスタイルのお手軽なマルチスレッドプログラミング

プレゼンソフトユーザの入力は XML で。

JavaScript (天野 仁史)(id:amachang

きれい。DHTML の表現力、および id:amachang さんのデザイン力とか。後者でけえんじゃねという噂もある。

XUL (下田 洋志/Piro)

高橋メソッド in XUL なソフト RETURNS。高橋メソッドの「でっかいフォント」を自動化できる! 楽ちん!

高橋さん曰く「RETURNS は良さそうなんだけど、文字の大きさが足りなかった」。

Java (西本 圭佑)

プレゼンソフト on 3D CMS on Tomcat。

入力は Wiki 記法ぽいの。

Gauche (小黒 直樹)

「一般の人」向けプレゼンソフト R-slide。

「一般の人」を考える。Gauche のインストール? できません。XMLに HTML、Wiki記法? わからんでしょうな。

使い方はかつての OHP を目指す。Gauche インストールはサーバーだけ。入力は画像ファイルです画像ファイル。

「逸般人」向けの機能も搭載。なんと scheme を実行可能。さらには telnet で R-slide に直接接続することもできる。→ 実行した scheme コードがバグってても、コードを走らせながら動的に buggy なコードを書き換えることができる!!

画面でチャットを表示できるように。→ id:otsune さん登場。

一通り終わって質疑応答だのしてる間にもチャットが表示される。otsuneさん活躍。「VIP から来ました」「自重www」「R-slide はじまた」(一部捏造)

hoge

「一般の人」は「テキストファイル」すらわからんのではないかと、俺なんかは思うわけです。まじで。僕らー「テキスト」っていうものがもうプリミティブなものとして感覚的に理解できてるけど、なんかそこわかってないんじゃないかなと思う。「一般の人」(の多く)は。だから R-slide の入力データは画像ってのは仕様に合致してるんじゃないかなと思った。

Lightning Talk

タイムアップ時にドラが鳴る。これは正直言えば嫌だった。大きな音苦手なもんで。

JavaFX script

LLSpirit運営のスルー力に絶望した!

Coq

証明ツール。Coq の入力から ML とかのプログラムを生成。Coq で証明が完了した部分については、バグが入ってないことがはっきりとわかる。

全てを Coq で書くのは大変過ぎるので、一番大切なところだけ Coq で書くといった利用法が考えられる。

ImageFight

PHP を捨てよう!

画像内部に埋め込まれてる PHP スクリプトの危険性。→ 画像をサニタイズしよう!

→ サニタイズ言うな

xbyac

xbyac + Boost.python は速いよ。Psycoと比べてもずっと速い。

通称カリー化も簡単にできる。

ja.doukaku.org

書いて、読んで、また書いて、そのサイクルが力となる。

月姫フォント? とか思った。調べたら甲殻でも使われてるらしい。正確な名称は金文体。

来年

LL2008、中野ZERO 大ホール キャパ 1300名!

ホールの予約とか一年以上前にやらにゃいけんのは知ってるけど、すげえ思いきってるなと思った。

雑多な感想

ごちゃごちゃするので切り分け。

和田先生が発表の最後に幾人かハッカーを紹介していましたが、その中で Knuth先生について「僕はあんまり好きじゃない」と言っていたのが印象に残っている。「もちろんすごい人なんだけど、ソースコードは goto だらけで非常に読みにくいし」などとおっしゃってた。

そういや確かにMinischemeに含まれてる Knuth先生の書いたGCのコードは goto だらけだったなあと思った。リンク先のコードはThe Art of Computer Programming由来だそうで。

和田先生の質疑応答のとき「何故 Postscript という使いにくい言語を使うので云々」という質問があがってたけど、Postscript は全然使いにくい言語ではないと思う。プログラムが生成した ps ファイルなんか見ると、「読めるわけねえ!」と思いますがこの辺 http://partners.adobe.com/public/developer/ps/index_specs.html にある Postscript Language Reference の CHAPTER 3 だけ読んだりすると、プログラミング言語だということがよくわかると思います。そんでもって図形描いたりする機能がプリミティブにあるんだから、他の言語よりずっと簡単に「画像をプログラミングする楽しさ」が味わえるってもんです。

つーかまあ俺も Postscript でまじめにプログラム書いたことあるわけでもないですけど。でも和田センセが描いてたような画像を描くなら Postscript は便利な道具だと思う。

あと俺は個人的に Java2D 、特に java.awt.geom.PathIterator,java.awt.geom.GeneralPath の恩恵を受けてるような人は Postscript を知ってても悪くないと思うんだ。

(本当に Java2D のその辺りが Postscript 由来なのかどうかはよく知らない。両者の相似点を見ると、そうとしか思えないけど。つーか今気付いたけど、それ和田センセに聞きゃよかったかも!)

shinhさんはスピーチもゴルフでかっこよかった。無駄が無い。あと2分とかたしかに欲しい発表だと思った。とかく喋りがうめえです。

ていうか shinhさんて、毎回プレゼンのたびにプレゼンソフトつくってねえか? というくらいプレゼンソフトつくってるような気がする。プレゼン見たのは今回が初めてだけど。

「好きなあの子に振り向いてもらう」というモチベーションの上げかたは素晴しい。これって実は割とメジャーな方法なのと違うかな。Linux とかもたぶんそうだよきっと。「タネンバウムのバカ、バカ! 今度こそ絶対褒めてもらうんだから!!!」みたいな。

VM魂のときに誰か「大きなシステムは脚遅いじゃないですか、象とか」と言ってた。たぶん。象はおよそ時速40kmで走るます

朝10時から夜までずっとだったけど、ずっと楽しめてよかった。せめて shinh さんの顔くらい憶えて帰ろうかと思ったけど不可能だった。人の顔は時間を置いて数回見ないと憶えれない。

昼飯→マグロ丼うめえ。晩飯→なんとかマグロ丼うめえ。

えーとこんな感じで。何故か非常にアレなレポになりましたが、推敲とかしたくないんでそのまま投稿します。うーん。ひどい。

トラックバック - http://d.hatena.ne.jp/hogelog/20070804

August 03(Fri), 2007

[] 明日Lightweight Language Spirit

まあ一人で行く。場所はわからんけど神保町とかいうあたり。行きゃ行けるべな。ところでいなばせんせーちょうかっこええ!

俺の k.inaba さんミーハーっぷりは普通にネットホモストーカーじゃねえのとかいうレベルのような気がしてるから詳しく語るのはやめとく。いやホモじゃねえ。

うーん。人が人を尊敬するシステムってどうなってんだろうな。なんつーか勝手にそこに理想を見出してるとかなんとか。

でもやっぱり高校生時代に書いた日記を残しておけるいなばさんの精神性は化物違うかなどと、僕は思うわけです。

[] コード読み

ちっちゃな Scheme インタプリタMinischemeのコードをちょこちょこ読んでる。

いちおうひらメソッドの練習がてら。http://konbu.s13.xrea.com/wiki/index.cgi あんまし真面目にやってないけど。

k.inabak.inaba 2007/08/04 00:15 さすがに自分では恥ずかしくて直視できないですが>古い日記。まあ他人が読んで微妙な気分になる分には知ったこっちゃない的な。

hogeloghogelog 2007/08/04 00:58 おかげさまでしばしば微妙な気分を楽しませていただいております。
なんか長い日記というのはそれだけで価値のあるもののような気がしてならないので、自分もそうしようと思ってたはずががが

トラックバック - http://d.hatena.ne.jp/hogelog/20070803

August 01(Wed), 2007

[] D言語であそぼう シェルとかつくってみる編。

なんか C で簡単なシェルつくってて、「あーハッシュテーブルでシンボルテーブルつくった方がいいよなあ、でもめんどくせー」と思ったので D で書いてみた。

とりあえず import std.c.linux.linux とかしたり色々すればできんだろー、と思ったら std.c.* のアレコレがまあ conflict しまくる。なので最低限使うのだけ宣言。

extern (C){
  int fork();
  int wait(int*);
  char* getenv(char*);
  void exit(int);
  void perror(char *);
}

D 側の関数で対応するものあればいらなくなんだけど。ちゃんと調べてないのであるかもしれない。

D はとにかく C との相性がいいっすね。C言語向けにインターフェースを提供してるライブラリのバインドが簡単ってのは、すごく有利なんだなと。あとはまあ C言語に比べりゃ文字列操作系の処理が超楽ちんですよねー、みたいなー。

以下うんこシェルのソース。「ハッシュテーブルハッシュテーブル!」言ってたのはどうしたかっつーと、まったくもって活用していなかったりする。しょぼいというか習作以外の何物でもない。今後改良したりとかも、特にしないと思う。

続きを読む

トラックバック - http://d.hatena.ne.jp/hogelog/20070801
最近のコメント
Connection: close