Syntax highlighter

2010-09-13

英語の発音について

英語の発音で日ごろ理不尽に感じてることをちょっと書いてみる。
(なんで今更こんなことをとか自分で突っ込み)

同スペル、異発音
Houston:
/ˈhjuːstən/ ≒ ひゅーすとん と発音すればテキサス州の都市(が有名、ほかにもある)
/ˈhaʊstən/ ≒ はうすとん と発音すればニューヨーク市の通りの名前(が有名、ほかにもある)

読みにくい系
simultaneously:
/ˌsī-məl-ˈtā-nē-əs-ly/ ≒ さいみゅるてにあうすりぃ。
ちなみにsimulateは/ˈsim-yə-ˌlāt/ ≒ しみゅれいと だったりする。(個人的に前者は米語だと思ってる)。

cupboard:
/ˈkʌbərd/ ≒ かばーど。知らなきゃ読めない。
ちなみに、boardは/bord/ ≒ ぼーど なので、後半だけ見ると同スペル、異発音かも。

nature:
/ˈnā-chər/ ≒ ねいちゃー。でもこれ、naturalになると/ˈna-chə-rəl/ ≒ なちゅらる になる。

英語と米語で発音が違う系
tomato:
「これが、"とめいと"だと!」と中学に入ってまず間違いなくショックを受けた言葉の一つだと思う。でも、英語(イギリス系)だと"とまーと"と発音したりする。ちなみに、tamagoは「ためいご」ではないのであしからず。

あんまりぱっと思いつかなかった。
この手のねたは需要があるかテストもかねて投稿してみたり。

2010-09-03

Java: Preferenceクラス

Javaのことを書くなんて本当はしたくないがあまりにネタがないので。
(Schemeの方は遅々として進まん・・・orz)

仕事は当然Javaを使うのだが、APIではまった話。
Preferenceというクラスがあるのだが、こいつは設定とか値をプラットフォーム固有の方法で永続化して使いまわせる便利なもの(のはず)
っで、今のプロジェクトでこいつを使っているのだが、なんか値がおかしい。
Windowsなので、レジストリに登録されるのだが、どうも1個しか値が存在してない。
っで調べてみた。

JavaDocによると、こいつはノードを取得する際にクラスを要求するくせに、値の保存はパッケージごとに行われるということ。クラスを要求するのは、パッケージ名を取得するためだけみたい。
つまり、
foo.bar.Hogeと、foo.bar.FugaっていうクラスでPreferenceを使うと値が共有されるらしい。
この方がありがたい人もいれば、そうじゃない人もいるだろう。僕は後者なわけだが・・・

foo.bar.configなんてパッケージを作ってその下にいくつかの設定値クラスなんかを作った場合問題になる、というか僕の問題はまさにこれ。
パッケージごとに一個の永続値って需要があるのだろうか?
ドキュメントをしっかり読めば早期発見できた問題ではあるが・・・

2010-08-15

前回から1ヶ月くらい離れてるなぁ・・・

日本にいたときは便利だったなぁという話。

スーパーとかなら切り身で売ってるけど、
マーケットで魚を買うとあまり魚はきれいになっていない。
頭、内臓、鱗のことだけど。
鮮度とか安さとかならきっと上なんだと思うけど、よくて内臓くらいまでか、さばいてくれるの?
しょうがないので、包丁で鱗を落とすし、三枚にもおろす。
(身が骨の方にたくさんつくときもあるが)

この辺のサービスは絶対的に日本の方がいい気がする。
しても、追加料金取るとかざらだし。
こっちの人たちあんまり客を大切にしないイメージ。

日本が過剰サービス過ぎなのか?

2010-07-16

どれが正しいんだ?

Schemeでdefine-syntaxの実装をしないといけないことに気づき、ちょっと調査。
単にマクロ展開のタイミングの話なのかな?

(import (rnrs))
(define (print x)
  (display x)
  (newline))

(define x 1)
(define (incf x . i)
  (if (pair? i)
      (begin (set! x (+ x (car i)))
      (print "procedure")
      x)
      (begin (set! x (+ x 1))
      (print "procedure")
      x)))
(print (incf x 2))

(define (test x i)
  (print (incf x i)))
(test x 1)

(print "define incf as define-syntax!")

(set! x 1)
(define-syntax incf
  (syntax-rules ()
    ((_ x) (begin (set! x (+ x 1)) x))
    ((_ x i) (begin (set! x (+ x i)) x))))
(print (incf x 2))
(test x 1)
こんなコードを、Chez(7.9.4)、Ypsilon(0.9.6-update3)、Mosh(0.2.5)に食わせてみる。

結果。
Chezは正常終了。最後の(test x 1)で展開されると思われてincfマクロは展開されず。
Ypisilonは最後の(test x 1)でincfの定義がない(多分、マクロで上書きされたから?)と怒る。
Moshはincfが複数定義されたといって例外。

それぞれの結果はこれ。
Chez
------------
procedure
3
procedure
2
define incf as define-syntax!
3
procedure
4
------------

Ypsilon
------------
procedure
3
procedure
2
define incf as define-syntax!
3

error: unbound variable incf

backtrace:
0 (incf x i)
..."D:/home/t.kato/test.scm" line 18
1 (test x 1)
..."D:/home/t.kato/test.scm" line 29
------------

mosh
------------
Condition components:
1. &who who: incf
2. &message message: "multiple definitions of identifier"
3. &syntax form: incf
subform: #f

Exception:
error in raise: returned from non-continuable exception

Stack trace:
1. throw:
2. (raise c): baselib.scm:943
3. apply:
------------

これだけバラバラだとどれが正しいのかわからない・・・

2010-07-09

英語で仕事をするということ

最近、楽天の社長が社内公用語を英語にするという記事を読んだのと、
それに反応してソニーかどこかの人がTwitterで、そんなことするくらいなら公用語をC言語にする、などといったのを読んだので無駄に反応してみた。

個人的な意見。
まったく無駄だと思います。
日本に本社があって、社長も日本人で、働いてる人の95%以上が日本人の環境で、英語にする意味がない。こっちで働いていて、使用言語はオランダ語ではなく英語なわけだが、オランダ人同士が会議している場所だと当然オランダ語。
そもそも、怪しい英語で会議しても意味なくね?英語が喋れることが最重要事項な会社って、翻訳会社か何かだと思う。楽天はそっち系に変わるのかね?

できることなら日本語環境がいいなぁと思う人の独り言・・・

2010-07-02

街が揺れた日

その日は暑い夏の日だった。仕事帰りの私はいつもと同じ道を歩いていた。
突如凄まじい轟音とともに街が一瞬揺れた!

えぇ、その瞬間がオランダがブラジルを下したことが決定した瞬間です。
正直、1点とったのかなと思ったんだけど、勝ってました。
ブラジルにですよ。信じられん。

ブラジルに勝てたということはそのまま優勝ということもありえるなぁ。

2010-06-30

C++で書き始めた

Scheme処理系をC++で書き始めた。
(実際は片付いてない問題が多々あるのだが・・・)

とりあえず、コードがVectorで構成されているのでVectorを。あと物が動くとやはりうれしいので、Fixnumなクラスを作成。
xyzzyの参考に(パチッてとも言う)、クラスのタグ付けとか、即値の判定とか作成。
っで、適当にごにょごにょして動かす。

(+ 1 2 3)をコンパイルした結果をC++のオブジェクトに置き換えたものが動いた。
説明が長い・・・

気になる点としては、現状だとコードはベクターの中にベクターが入れ子になるように作ってあるのだが、これだとメモリー効率が激しく悪い気がする。
Schemeで書いてるときは気にしなかったのだが、C++で書いてみると一つのコードを書くのにベクターの割り当てが激しく出てくる感じ。
コンパイラを書き換えて全部フラットにするべきだろうか・・・するべきなんだろうなぁ・・・

2010-06-24

ワールドカップ

日本が3-1でデンマークに勝った!!
何が起きてるんだろう?天変地異の前触れか?

どうでもいいが、ここオランダではサッカーがあるとえらいことになる。
僕の住んでるライデンにはちょっとした広場が街の中央にあるのだが、そこにパブリックビューがあって結構な人が集まっていた。
酒が飲めればいいのか、騒げればいいのか、純粋にサッカーが好きなのかどれなのかは分からないが、街中がやかましい。
噂によると、サッカーの観戦をするために仕事を病欠する人がいるそうだ。
そんな国。

2010-06-22

letのフレーム

A正規化の話だったりする。
たとえばこんなコード(変な数字が入ってるのはα変換後だから)
(define
 tarai
 (lambda
  (x.1 y.2 z.3)
  (if
   (not (< y.2 x.1))
   y.2
   (tarai
    (tarai (- x.1 1) y.2 z.3)
    (tarai (- y.2 1) z.3 x.1)
    (tarai (- z.3 1) x.1 y.2))))
こいつをA正規形にするとこうなる
(define
 tarai
 (lambda
  (x.1 y.2 z.3)
  (let
   ((#:G267 (< y.2 x.1)))
   (let
    ((#:G268 (not #:G267)))
    (if
     #:G268
     y.2
     (let
      ((#:G269 (- x.1 1)))
      (let
       ((#:G270 (tarai #:G269 y.2 z.3)))
       (let
        ((#:G271 (- y.2 1)))
        (let
         ((#:G272 (tarai #:G271 z.3 x.1)))
         (let
          ((#:G273 (- z.3 1)))
          (let
           ((#:G274 (tarai #:G273 x.1 y.2)))
           (tarai #:G270 #:G272 #:G274)))))))))))
見てのとおりコードが増大。それだけならまだいいのだが(よくないが)、問題はコードの増大に伴ってletが出現していること。
前回、継続周りで不具合が起きることを踏まえて、letが現れたらフレームを作るようにコンパイラとVMを修正したのだが、その影響で単なるたらいまわし関数がスタックオーバーフローを起こすようになった。
原因は、この大量のlet。これだけコードが増大すれば当然VMのインストラクションも増大する。どれだけ影響があるかスタックを1000から10000にして上記の関数でベンチマークをとってみた。
4秒が14秒に・・・orz

後の最適化がしやすいようにと思ってのA正規化だが、ちょっとないなぁ・・・
今のところこいつの恩恵って、変数の寿命がわかりやすいことだけだし・・・
どうしよう。

2010-06-18

スタックポインタ、フレームポインタ

Schemeのコンパイラの話。
3impという論文のコンパイラを参考に作っているわけだが、スタックポインタとフレームポインタではまった。
(ってか、今でも解決してない)

ここにあるスタックとフレームの関係を参考にして、letのコンパイルをしたのだが、上手くいかない。
原因は分かっている。本来はletごとにフレームを作成して自由変数とかの解決をしないといけないのに、フレームを作るコストを嫌って、letが続く限り一つのローカルフレームのようにしたから。
そもそも、letではフレームを作ってないので、フレーム情報があることを前提にしているVMインストラクションでおかしなことが起きる。

どうしよう。
とりあえず、Gaucheがletをどう処理してるのかdisasmしてみた。
...
let毎にフレーム作ってる・・・
やっぱりそうするべきかなぁ?でもA正規化後ってあほかと思うほどletが増えるんだよなぁ・・・
その辺も踏まえてどうしよう。

2010-06-15

コンパイル

いろいろ弄って、letをコンパイルできるようにした。
意外と上手くいくもんだ。四苦八苦したけど・・・

っで、たらいまわし関数を動かしてみたら、10,5,0の引数で36秒かかる・・・
まぁ、schemeをscheme上で動かしてるのでオーバーヘッドとかもあるだろう。っがあまりに遅いのでできそうな高速化を施すことに。
現状リストでVMのインストラクションを書いていたが、全部ベクターに変更。でも、面倒くさがりなので、
ベクターの中にベクターを入れるといういんちき(?)をして、データ構造は特に変更しない。
勢いあまってVMにプログラムカウンタをつけてみたけど、要らん気がする。まぁいいや。

これで、一時的に5倍くらい早くなった。
次にインストラクションを今後のために数値に変更。これは逆に遅くなった。
考えられそうな理由は現状プリミティブの実装がかなり適当で、シンボルと数値の比較が一つのcond文に混在している。なので、シンボルの比較を先にしないと、Gaucheに怒られた。っで先に回したら鈍足に・・・
比較の分だけ遅くなるわね。
逆に言えば、よく使われるインストラクションは前の方に持ってくると幸せになれるか?

っで、とりあえずプリミティブをいんちきせずにコンパイルするようにしている最中。
物が動いてくるとやはり楽しい。

2010-06-14

カメルーンに勝った

ワールドカップの話。
職場が半日だれも仕事しないくらいオランダはサッカーが熱い(個人的にはどうでもいいが)
職場で点が入るたびに雄たけびが聞こえてくるくらい。

っで、それのあおりで日本VSカメルーンを少し見た。
あれ?勝ってる?
1-0で日本が勝った・・・

とりあえず、前評判を的確に表していたであろうコピペ。
A                              B 
南アフリカ「ガチ抽選をした結果がこれだよ!」   アルゼンチン「なんだ楽勝じゃん」
メキシコ「南アフリカ乙」                 ナイジェリア「2位ならなんとか」
ウルグアイ「南アフリカ乙」               韓国「\( ^o^)/」
フランス「実質シードワロスww」             ギリシャ「2位ならなんとか」

C                              D 
イングランド「アジアとやらせろよ」           ドイツ「そこそこの組み合わせかな」
アメリカ「微妙・・・」                    オーストラリア「2位いけるな」
アルジェリア「無理くさい」                セルビア「2位いけるな」
スロベニア「微妙・・・」                  ガーナ 「2位いけるな」

E                              F
オランダ「まぁ、おk」                   イタリア「楽勝www」
デンマーク「日本には勝つとして・・・」         パラグアイ「ニュージーには勝つ」
日本「なかなかいい組み合わせだな(キリッ」      ニュージーランド「なにこの無理ゲー?」
カメルーン「日本には勝つとして・・・」         スロバキア 「ニュージーには勝つ」

G                              H
ブラジル「1位通過するよ」               スペイン「楽勝すぐるww」
北朝鮮「どうしてこうなった!」             スイス「ホンジュラスには勝つ」
コートジボワール「1位通過するよ」          ホンジュラス「まぁ、がんばる」
ポルトガル「1位通過するよ」              チリ 「ホンジュラスには勝つ」 

う~ん、何が起きたんだろう?

ミーはおフランス帰りざんす

ということで、パリに行ってきました。
パッケージツアーというのは今までの人生でほとんど経験がないので(修学旅行等除く)それなりにいい経験になったかなと。
言葉の壁さえ考えなければ、交通費、朝食、夕食、セーヌ川のボートツアー、その他いろいろ混みで150ユーロは安いのではないかな。

パリの街は思っていた以上になじむなぁとちょっと感じた。
そこらじゅうで言われていた、犬の糞の問題は特になく、きれいだったし。

っが、街はきれいでも人は・・・
パリで運転する必要がある人はかなりの胆力が必要になるだろうなぁと。

時間がないので適当。

2010-06-09

やっつけA正規形拡張

とりあえず、オリジナルのA正規形で問題かなと思ったのが以下の点。
  1. letが引数一つ
  2. cond、letrec等の必要そうな構文がない(condはif文で書きかえれるけど・・・)
  3. quoteしたものも正規化する
ということでちょいちょい変更。

1. letが変数一つって扱い難いので複数取るように変更。(let (<binds>) <body>)というが普通のletなのでこれを取るようにし、<binds>の(変数 値)という式を一つずつ正規化後letを再構築。

2. condは
(cond (<pred1> <then1>)
      (<pred2> <then2>)
      (else <then>)
という式なので、pred1 ... pred2をこんな感じに
(let ((p1 (normalize <pred1>)))
   ; 以下predの数だけ
っでthenを正規化してcondを再構築。
letrecとletrec*はバインド変数だけ正規化してそのまま放置。とりあえずこれでいいか?

3. オリジナルは(display 'a)というのが(let ((r 'a)) (display r))ってなってたので、さすがにあほらしいかと思い、quoteは正規化しないことにした。

っで、とりあえず3impのコンパイラでコンパイルしてみた。
おぉ、コンパイルできた。
っが、コンパイラにletをコンパイルする記述はない・・・さて、考えるか・・・

2010-06-08

A正規形に切り替える

CPS変換がどうにも上手くいかない。
なんとかなるんだろうけど、涙が出そうになってきたので断念。
一応、それ以外の理由として、
  1. コードの肥大化がすさまじい
  2. 変換することによって、関数のシグネチャが変わる(継続を渡すように変更するため)
  3. ベンチマークで脅威の低速を叩き出してる
この辺がそれ以外の理由。まぁ、3番目はVMの最適化次第だと思うけど・・・
(Gauche上で動かしてるのでしょうがない)

ということで、A正規形に切り替えることにする。
A正規形はCPS変換後逆CPS変換した形に極めて近い気がする。すべての継続の結果を変数として確保するので、スタックの肥大化が問題かな?
ここが詳しい。別に論文も読むといいと思う。
論文の最後にアルゴリズムをschemeで実装した例がある。
問題はこいつはCore SchemeというSchemeのサブセットを対象としているので、いろんな部分で限定的。(letrecとかないし・・・condとかどうするんだろう?)
その辺りを自前で拡張することができればよさそうだ。できるかな?

2010-06-07

コメントの仕方

コメントの仕方が分からないという指摘が累計2件ほどたまったので(少ない)
蛇足ではあると思うけど書いてみる。

コメントしたいと思う投稿の一番下にある、数字 + コメントという(このブログだと緑)のリンクをクリックする。
するとなんとも味気ないコメント投稿画面が現れるので、大き目のテキストエリアにコメントを書き込む。
スパム防止機能があるので、コメントのテキストエリアの下にあるフィールドに画像の英数字を入力。
投稿者のIDを選択。OpenIDはよく分かっていないが、Googleアカウントがあればそれでもいいし、そんなもの無いなら名前/URLを選択し名前を入力。もちろん匿名でも構わない。
最後に投稿ボタンを押せば完了。
bloggerのコメントはきっと共通だと思うので、これで他のbloggerにもコメントができる!

さぁ、早速この投稿にコメントして練習だ!

2010-06-03

ぬか喜びだった件・・・

前述のベンチマークだが、手動CPS変換が間違っていた。
正しくはこう
(define (<=/cps x y k) (k (<= x y)))
(define (-/cps x y k) (k (- x y)))
(define tarai-cps  
  (lambda (x y z k)
    (<=/cps x y
     (lambda (b)
       (if b
    ;ここが違う
    (k y)
    (-/cps x 1 
    (lambda (x2)
      (tarai-cps x2 y z
          (lambda (t1)
     (-/cps y 1 
     (lambda (y2)
       (tarai-cps y2 z x
           (lambda (t2)
             (-/cps z 1
             (lambda (z2)
        (tarai-cps z2 x y
            (lambda (t3)
              ;ここも
              (tarai-cps t1 t2 t3 k))))))))))))))))))
(time (tarai-cps 10 5 0 (lambda (x) x)))
っで、ベンチマークの結果。
Petite Chez Scheme 7.9.4
(time (tarai-org 10 ...))
    no collections
    16 ms elapsed cpu time
    0 ms elapsed real time
    0 bytes allocated
(time (tarai-cps 10 ...))
    10 collections
    125 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    44600752 bytes allocated, including 42111448 bytes reclaimed
(time (tarai-anf 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505120 bytes allocated, including 29499488 bytes reclaimed
(time (tarai-lambda 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505120 bytes allocated, including 29490760 bytes reclaimed

Gauche 0.9
;(time (tarai-org 10 5 0))
; real   0.016
; user   0.015
; sys    0.000
;(time (tarai-cps 10 5 0 (lambda (x) x)))
; real   0.453
; user   0.407
; sys    0.047
;(time (tarai-anf 10 5 0))
; real   0.031
; user   0.031
; sys    0.000
;(time (tarai-lambda 10 5 0))
; real   0.422
; user   0.375
; sys    0.047
圧倒的じゃないか。。。orz
どう考えてもなしの方向っぽいです、本当に(ry

ベンチマーク

CPS変換の勉強中にANF(A-normal form)との共通点を見つけて、
ひょっとしてCPS変換しなくてもA正規化すればいいのでは?
という誘惑にかられたことから、ちょっとベンチマークとってみた。
(どっちが速度が出るか比較したかった。速い方がいいじゃん!)

使用したコードは以下
(define tarai-org
  (lambda (x y z)
    (if (<= x y)
 y
 (tarai-org (tarai-org (- x 1) y z)
     (tarai-org (- y 1) z x)
     (tarai-org (- z 1) x y)))))
(time (tarai-org 10 5 0))

(define (<=/cps x y k) (k (<= x y)))
(define (-/cps x y k) (k (- x y)))
(define tarai-cps  
  (lambda (x y z k)
    (<=/cps 
     x y
     (lambda (b)
       (if b
    y
    (-/cps
     x 1 
     (lambda (x2)
       (tarai-cps 
        x2 y z
        (lambda (t1)
   (-/cps
    y 1 
    (lambda (y2)
      (tarai-cps
       y2 z x
       (lambda (t2)
         (-/cps
   z 1
   (lambda (z2)
     (tarai-cps
      z2 x y
      (lambda (t3)
        (k (tarai-cps t1 t2 t3)))))))))))))))))))
(time (tarai-cps 10 5 0 (lambda (x) x)))

(define tarai-anf
  (lambda (x y z)
    (let ((G139 (<= x y)))
      (if G139
   y
       (let ((G140 (- x 1)))
  (let ((G141 (tarai-anf G140 y z)))
    (let ((G142 (- y 1)))
      (let ((G143 (tarai-anf G142 z x)))
        (let ((G144 (- z 1)))
   (let ((G145 (tarai-anf G144 x y)))
     (tarai-anf G141 G143 G145)))))))))))
(time (tarai-anf 10 5 0))

(define tarai-lambda
 (lambda (x y z)
  ((lambda (G143)
     (if G143
  y
  ((lambda (G144)
     ((lambda (G145)
        ((lambda (G146)
    ((lambda (G147)
       ((lambda (G148)
   ((lambda (G149)
      (tarai-lambda G145 G147 G149))
    (tarai-lambda G148 x y)))
        (- z 1)))
     (tarai-lambda G146 z x)))
  (- y 1)))
      (tarai-lambda G144 y z)))
   (- x 1))))
   (<= x y))))
(time (tarai-lambda 10 5 0))
tarai-orgが元のたらいまわし関数。以下、-cps、-anf、-lambdaと続くが、順に元の関数のお手製CPS変換、A正規化、A正規化後letをlambdaに変換したものとなっている。 っで、以下がベンチマーク結果
Petite Chez Scheme 7.9.4
(time (tarai-org 10 ...))
    no collections
    16 ms elapsed cpu time
    0 ms elapsed real time
    0 bytes allocated
(time (tarai-cps 10 ...))
    no collections
    0 ms elapsed cpu time
    0 ms elapsed real time
    840 bytes allocated
(time (tarai-anf 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505472 bytes allocated, including 29469704 bytes reclaimed
(time (tarai-lambda 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505120 bytes allocated, including 29489216 bytes reclaimed

Gauche 0.9
;(time (tarai-org 10 5 0))
; real   0.016
; user   0.016
; sys    0.000
;(time (tarai-cps 10 5 0 (lambda (x) x)))
; real   0.000
; user   0.000
; sys    0.000
;(time (tarai-anf 10 5 0))
; real   0.031
; user   0.031
; sys    0.000
;(time (tarai-lambda 10 5 0))
; real   0.437
; user   0.359
; sys    0.078
個人的には超意外にもCPSが一番早かった!!
Gaucheのdisasm関数でコンパイル結果を見てみたが、末尾最適化が効いてるのかな?
Chez Schemeの結果からアロケーションが結構発生するみたいだけど、それを踏まえてもありと思わせる結果である。

でも、これってこれらのVMがCPS変換されたコードを速く走らせるのであって、CPS変換されたコードが無条件で速くなるわけではないんだよなぁ・・・
う~ん・・・

2010-06-01

CPS変換

とりあえず基本的なことを勉強してみた。
とにかく、すべてのλ抽象は次に計算される継続を持てばいいみたいで、こんな感じに変換される。
(この辺は知っていた・・・つもり)
; 変換前
(define (pyth x y)
  (sqrt (+ (* x x) (* y y))))
; 変換後
(define (pyth x y k)
  (* x x (lambda (x2)
    (* y y (lambda (y2)
      (+ x2 y2 (lambda (x2py2)
          (sqrt x2py2 k))))))))
CPS変換するとこうなる。プログラムは継続渡しスタイルなので、「*」、「+」といったプリミティブでさえ、引数に継続を取る。
ということは、継続を取る引数を定義しないといけない・・・
こんな感じ。
(define (cps/* x y k) (k (* x y)))
(define (cps/+ x y k) (k (+ x y)))
(define (cps/sqrt x k) (k (sqrt x)))
上記のプログラムの*、+及びsqrtをCPSなプリミティブに置き換えれば動く。面倒・・・

っで、これ見ると分かるのだが、継続渡しのプログラムは戻り値を次の継続に渡すので必然的に渡される継続の引数は1つに固定される。
引数を一つに固定して、あだこだするというと、カリー化が思い浮かぶが、やらにゃならんのだろうか・・・

とりあえず、用事ができたのでここまで。続きは帰ってきてから。

-----------------
帰ってきた。

引数を一つに固定したくないという思いをいただいたので(誰からだよ!)
継続の戻り値が多値なら問題ないかと。とりあえず、実験。
(define (cps/+ k . arg)(k (apply + arg)))
(call-with-values (lambda () (values (lambda (k) k) 1 2 3)) cps/+)
call-with-valuesが内部で何してるのか実はよく分かっていないが、動きから第二引数に第一引数の戻り値をapplyしてるのではないかと・・・
まぁ、どうでもいいや。
こう書けば一応複数の引数を何とかできそうだが、いいのか?
とりあえず、最初のプログラムを手動CPS変換してみる。

と思ったが、CPS変換で生じたλ抽象って、この場合だと(* x y)の戻り値を引数にするのだから、1つ固定でも問題ない気がする。もちろん、 (values 1 2)見たいな多値を返すんだとしたら問題かもしれないが、Schemeは多値をそのままでは扱えないので、やっぱり問題ない気がする。

例みたいな、defineをCPS変換する際には関係ないのだろう、きっと・・・

2010-05-30

ラムダ計算 入門

SchemeでSchemeのコンパイラを作っているのだが、いろいろやるに当たって必要になったので勉強中。
(泥縄とかそういう突っ込みはいらない)

ラムダ計算入門のPDFが分かりやすかったのでこれを元に入門編を勉強。

とりあえずラムダ計算の定義。
e(λ式) ::= x     (変数)
          | λx.e (λ抽象)
          | e1e2  (関数適用)
この辺は余裕。
Schemeで変数を定義するときにlet式を使うが、let式もlambdaに変換できる。
(SICPで出たが復習)
(let ((x 1)) <body>) -> ((lambda (x) <body>) 1)
λ式に対して関数適用をするといった感じ?

β簡約
いくつかやり方があるらしい。とりあえず資料にあったのは、R-Beta、R-App1、R-App2とR-Absの4つ。
R-Beta:
--------------------------
  (λx.e1)e2 -> [e2/x]e1
例: 
(λx.x)y -> y
(λx.λy.x)z -> λy.z
[e2/x]e1はe1の変数xにe2を代入したという意味。
R-App1:
     e1 -> e1'
-----------------
  e1e2 -> e1'e2
例:
(λa.b)cd -> bd
λ式は左結合なので、(λa.b)cdは実際は((λa.b)c)dとなる。R-Betaで(λa.b)cが[c/a]bになって、このbに対してdを適用するということ。
じゃあ、正確には[c/a]bdじゃないのだろうかと、ちと疑問。
R-App2:
    e2 -> e2'
-----------------
  e1e2 -> e1e2'
例:
a((λx.x)b) -> ab
R-App2はR-App1のe2版。つまり引数に対してβ簡約をするということ。
例は資料になかったので自分で考えた。間違い指摘大歓迎!!
R-Abs:
      e -> e'
-------------------
  λx.e -> λx.e'
例:
λx.(λy.y)x -> λx.x
λ抽象に対しての簡約。実行時に関数を評価するMLでは必要ないらしい。でも、簡約=最適化だとすればコンパイル時に評価しなくてもいいので、簡約はしておきたいなぁ。ということでこれも必要としておこう。

α変換
変数名を一意に変換すること。こんな感じ(まんま資料から)。
(λx.λy.xy)y -α変換-> (λx.λy'.xy')y -β簡約-> λy'.yy'
最初の式のyと適用されるyは異なる変数だが同名がつけられている。このまま簡約すると式の意味が変わるので変数名を変えようというだけの話。
仰々しい名前が着いてるけど、変数名の衝突を防ぐだけ・・・

とりあえず、入門の入門としてはこれくらいにする。
1時間の勉強内容としてはこんなもんだろう・・・

最終的にはSabry&WadlerのCPS変換の実装をSchemeでできるまでには習得したい・・・

2010-05-23

New York最終日

書いてる時間がおかしいが、まぁ無事に帰ってきた後ということで^^;

特に何もない、実は(じゃあ書くなよ)
飛行場の近くにあるモールでランチ取っただけという話。

飛行場はNewarkという飛行場。なんとも紛らわしい名前だ。
んでもって、あほかというほど混んでた。
飛行場でいつも気になるのは、清掃のおばちゃんじゃないけど、係員みたいな人は大抵アメリカ人じゃない発音の英語を話すこと。
大抵インド系かスペイン系。
そういえばタクシーの運ちゃんとかバスの運ちゃんもスペイン系が多かったなぁ。
この辺りは移民が着く仕事なんだろうか?

帰りの飛行機は特に問題なく7時間弱で到着。
特に時差ぼけも無く、普通のフライトだった。

どうでもいいが、今回の旅行で分かったことがある。
僕は英語が話せない・・・(T_T)

2010-05-21

New York四日目

四日目もニューヨーク。
今日はツアーバスには乗らずいろいろぶらぶら。
といっても、あんまりどこにも行ってないなぁ。

お茶して、
自由の女神をフェリーから見て、
セントラルパークで(大分遅い)昼食をとって(17時)、
チャイナタウンで買い物して、
終了。

セントラルパークはかなりいい感じの公園だった。
都会の雑踏を完全に忘れることができるというか、まぁそんな感じ。
しかも、やたらでかい!
もう来ることはないと思うが、もし機会があればレンタル自転車で一周してみたいなぁ。

2010-05-20

New York三日目

今日もNew York。
New YorkというかManhattanは基本的に3つの地域(?)から成り立つっぽい。
Uptown、MidtownそれにDowntownの3つ。DowntownにはWall Streetとか経済の中心っぽいところがあり、UptownはHarlemとか居住地っぽい感じ。
個人的にHarlemって聞くとスラム街ってイメージがあったのだが、それは今や昔の話で今は(バスのガイドさんの話によると)完全に安全らしい。
どうでもいいのだがUptownにはコロンビア大学があり、コロンビア大学というとシヴァ、アレクサンドライトなどの漫画が思い浮かぶ。
(浮かぶ人の方が少ないだろう上に、20年近く前の漫画だったりする)
個人的に、あの漫画のManhattan描写はなんだかいろいろ違うような気が今更ながらにしたが、20年くらい前なので当時はそうだったのかもしれない。どうでもいい話。
ちなみに、コロンビア大学はもっとも学費が高い私立大学の一つらしい。っで、同じくManhattanにあるニューヨーク大学は年間5万ドル(500万円くらい?)ほどするらしい。漫画の中の話とは言え、彼らはものすごく金持ちだったのだろう・・・

そんなことを考えながら観光バスのUptownツアーを終了し、タイムズスクエアに戻る。っで、何故か吉野家で昼食。
味はまぁまぁだったのだが、なぜ吉野家に寿司があるんだろう?

その後Downtownツアーのバスに乗り、ナイトツアーでManhattan → Brooklyn → Manhattanと移動。無いとツアーのガイドのおっさんがやたら面白い人だった。

ちょっとだけこの街に慣れてきた気がするが、やはり肌に合わない・・・

2010-05-19

New York二日目

今日は普通の時間に起きたのでそれなりに元気。
ホテルで朝食を取ってシャトルバスでManhattanへ。
あいにくの雨なので適当にぶらぶら。
(セントラルパークとか行ってみたいところはあるのだが、雨だしやめた。明日)

タイムススクエアとかそれっぽいとこを見た感じ。
48時間乗り降り自由の観光バスのチケットを買い、それに乗って時間をつぶす。
雨なので説明を聞いてもそれそのものは見えない・・・
無駄金払った気分orz
明日があるさ!

そんな感じでとりあえず二日目終了。

2010-05-18

New York一日目

無事に飛行機に乗れ、無事にNew Yorkに到着。
実際にはNew Jerseyだったりするが、まぁ主に活動するところはNew Yorkになるので細かいことは気にしない。

とりあえず、今日も4時おきだったりするので、ホテルに到着し次第爆睡・・・
う~ん。

飛行場からホテルまでまぁ距離があって、電車に乗る必要があったのだが、その車窓から覗いた世界がなんだかセピア色だった。
う~ん、とりあえずすでに自分になじまないなぁという雰囲気が漂っている・・・

2010-05-17

Orlandおまけ

Orlandoを出発する予定だったのだが、いろいろあって飛行機に乗れなかった・・・
ということで、おまけの一日。
朝4時起きという超睡眠不足に加えて連日の疲れから何もできなかったけど・・・
とりあえず、シーワールドに行っておしまい。

明日は本当にNew Yorkのはず・・・

2010-05-16

Orland最終日

諸事情により、6日目と7日目はスキップ。

最終日。今日はユニバーサルスタジオに行ってきた。新しいジェットコースターがあったのだが、60分待ちとかだったので断念。
適当に他のを堪能して一日終了。
かなり歩いたので足が痛い。
今日がOrlando最終日。次はニューヨーク。

どうでもいいが、昨日と一昨日で韓国人が嫌いから大嫌いになった。やつらは本当におかしい。

2010-05-13

Orlando五日目

今日はアクアティカで泳いだ。
前回いけなかったウォータースライダーを制覇したので、ちょっと満足。
やはりシーズンより少し早いせいか、人がまばら。いいことだが、ちと(気温的に)寒かった・・・

っで、疲れたので早めに切り上げて、適当に休憩してからIron Man 2を観ることに。
きっとまだ日本では上映されて無いだろうのでネタはばらさない方向で。
(ってか前作は上映されたのか?)
感想。近作はコメディー色が結構だされている感じで、笑いどころが結構あった。
内容的にはまずまず。突っ込みどころも多々あったが、個人的には観て損はないと思えた。
Iron Manの役者とシャーロックホームズの役者が一緒なのだが(名前を失念・・・)、この人いい演技をするなぁと思う。この手の自信過剰で子供っぽさのある役がはまり役なのか、この人自身がすばらしい役者なのか(もしくは両方か)分からんけど。

そういえば、映画館からの帰りにパトカーがIHop(レストラン)に10台くらい停まってるを見た。きっと強盗が入ったのだろう・・・
怖い・・・

2010-05-12

Orlando四日目

今日はブッシュガーデンに行ってきた。
特筆するようなことは実はないのだが、とりあえず人は少なめだった。

どうでもいいのだが、この時期のフロリダは天気が微妙。昼間はあほかと思うほど暑いのに、夜になると冷える。ってか、寒い。
レストランとかバスとかガンガンに冷房が効いてるので、長袖を着ないと寒くてしょうがない。っが外は暑い(昼限定)。

更にどうでもいいのだが、枕が替わったせいか眠りが浅く疲れが取れない。毎日寝不足で太陽の下はきつい・・・

2010-05-11

Orlando三日目

今日はシーワールドに行ってきた。
入園する前に、一悶着あったのでその話と+α
シーワールド、アクアティカ、ブッシュガーデン、その他といくつかのテーマパークは経営者が同じっぽいのでいくつか周るなちょっとお得なチケットがある。
っでそのチケットを買った際に、何を間違ったのか名前のつづりが違った。っで、正しいのにしてくれといったら、
「問題ない」
との一言。どう考えてもおかしい。
チケットに必要に応じてID(大概パスポート)を見せてもらうことがあるなんて注意書きがあって、チケットの名前とIDの名前が食い違ってたら問題にしかならないはずだ。
っが、チケット売り場のおばさんは問題ないの一点張り。しょうがないのでカスタマーサービスへ。
っが、さらにここでも問題ないと言われる。
しょうがないので、ID要求されたらどうなるんだってわざわざ説明したら、その人の判断では決定できないので上司に指示を仰ぐといって中に入ってった。
結論を言えばチケットは無事交換されたのだが、どう考えても手際というかいろいろおかしすぎ。
訴訟大国のくせに、訴えられたらどうするんだって突込みどころが山ほどある気がする。

まだローシーズンなのか、どこもかしももガラガラ。世界的な不景気で旅行者が少ないのかもしれないが、これでは路頭に迷う人がでるんじゃねぇの?ってくらいガラガラ。
実際、去年あったホテルとか、レストランとか結構消えているので路頭に迷っているのだろうが・・・
まぁ、待ち時間が少ないというのはこちらにとってはうれしいことなのでどうでもいいが。

どうでもいい話。
アメリカという国柄なのか、フロリダだからなのかは分からないが、こっちにきて英語を話すことにすごく抵抗を感じる。抵抗というか、(元々そんなに正しくはないが)発音がどうも違うらしい。っで、少しでも発音が違うと理解されない・・・
でも、観光地なんだし旅行者が全員正しい(何をもって正しいというか知らんが)英語が喋れるわけないので、理解しようとする姿勢が必要だと思うのだが、それも見受けられない・・・orz
なので、なんか居心地が悪いというか、そんな感じ。
ちなみに今日通じなかった英語はなんと「hot」!
今まで通じなかったことは無いのだが、こっちで「ホット」という通じない。どちらかと言えば(厳密には違う)「ハット」に近い発音がアメリカ訛り(南部だけかも)っぽい。
waterと同じ感じだわね。
個人的には、「聞き返さないと分からないほどの差はない気がする」のだがどうだろう?
特に「hot tea」って言ったら、少なくとも「tea」の部分は分かるだろうと言いたい。メニューにアイスティーはないんだし。そこも違うかも?それは・・・

2010-05-10

Orlando二日目

ひたすらショッピングな1日であった。ぐったり・・・
ショッピングモールを3つくらいはしごするという地獄のような一日・・・

主にアウトレットなのだが、こっちのアウトレットは結構豪快に(普通なのかもしれないが)値引きをする。今日は母の日ということで50%引きだった。
しかし、それって裏を返せば50%引いても利益がでるってことだよね?
通常価格がどれだけぼられてるのかよく分かる。ブランド名ってつけたもん勝ちだなぁ。

2010-05-09

Orlando一日目

昨日(時差の関係でいつだかもはや分かってないが・・・)飛行機に乗ってアメリカに出発した。
行きの飛行機の中でアイスランドの噴火が見えたのは貴重な体験だったと言えるだろう。
(写真も撮ったけど、いろいろ無いから載せれない。気が向いたら)

まずはNew Yorkでアメリカに入国。なんだか今回の入国審査はえらく人種差別を感じたが、まぁアメリカだしこんなもんだろうと勝手に納得しておく。
(でも、白人は一言交わして他は根掘り葉掘り聞くってさすがにどうよ!)

っで、トランスファーでオーランドへ。
特に何かすることもなく、ウォールマートへ行って飲み物当の買い物。
その後夕食で現在に至る。
一日目だしこんなもんだろう。

時差ぼけはないと思うのだが、旅の疲れでやたら眠い・・・

2010-05-07

出発前夜

なぜか標題の後ろに「の夜」という馬から落馬するみたいな表現にしたくなった。
何故だ?

明日の朝にアメリカに向かって出発。
休暇です。2週間ほど行ってきます。
こっちにきて本当にありがたいなぁと思っているのはこの有給二週間とか普通に取れること!
日本にいたときは1週間でさえ不可能だったのに・・・
(まぁ、その分いろいろサービスは悪いが、24時間のコンビニなんてここではありえん)

アメリカといえば、普天間の問題が深刻化しているようです。
ひっくり返したかと思えば、やっぱり元に戻したいと言ってみたり、そうじゃないとその日のうちに撤回したり。
鳩山由紀夫氏(あえて総理とは呼ばない)は本当に妄言癖がおありのようです。
(正直、今のところ自分とは関係ないので)情報をしっかり選別せず、マスコミの言うなりに民主党に投票した人たち、つまり国民に原因の一端があるので、しっかり苦しんで次回に活かしてもらいたいなぁと。

マスコミは事実を流せばいいんだよ。変な情報操作すんな!
(言いたかっただけ)

口蹄病のこととかもぜんぜん報道されてないみたいだし・・・
どうなってるのかね、日本・・・

2010-04-30

OS: GRUBの続きの続き

前回GRUBでカーネルイメージが読み込めたと思って喜んでいたのだが、VRAM周りのコードが上手く動いていなかった。
GRUBが最初に読み込む部分はアセンブラで書いているのだが、カーネルのコード(になる予定)から戻ってきたときには文字列が表示されるのに、コード内部で表示しようとしたら意図しない文字が表示されていた。
それでもって、自分で作ったVRAM用のクラスを使うとGRUBが再起動しまくりで、大変なことになっていた。

何が原因か分からなかったので、とりあえずデバッグすることに。
qemuのデバッグってどうやるのかとググって見たら、こんなページに遭遇。
-sと-Sオプションをつけるのね。意味は調べてないけど・・・
っで、gdbをカーネルイメージを引数にして起動。
(gdb) target remote localhost:1234
このコマンドでqemuに接続してすれば、普通にブレークポイントとか設定可能。

っで、動かしてみたところ、GRUBはELF形式にしか対応してないことが判明。
Cygwinで作ってるので、PE形式なイメージなわけで、どうしろと?
クロスコンパイラを作るのか?(GCCのターゲット指定でコンパイルだと思う)
と思っていたが、objcopyでバイナリ形式にしたら動いた。
まぁ、とりあえずこれでいいか。GRUB周りで苦しむのは本意ではないし・・・

どうでもいいが、調べている過程でmultiboot.hを覗いたのだが、カーネルに渡す構造体のなかにVBEの情報が入ってた。
まぁ、そのうち対応する予定なので、自前でなんだかやらなくても済んだかもと期待しておこう。
(でも、先にメモリとか割り込みテーブルとかやることは満載・・・)

2010-04-29

歯のクリーニング

今までの人生ではじめての経験であった。
今までそんなものとは無縁で生きてきたのだが、折角保険に入ってるし使わないともったいないとそそのかされて行って来た。

・・・


・・・・・・


・・・・・・・・・


涙が出るほど痛かった。
おかしいだろ!
歯を削るのと同じ機械だと思われるものでがりがり何かを削られて(多分歯石)、そのあとポリッシャーで表面を磨くという工程だったと思うのだが、
30分が永遠に続くんじゃないかと思えたくらい地獄の時間であった。

歯科衛生士さん(でいいのかな?)話によると、少なくとも6ヶ月に1回は行った方いいそうだ。
年に2回もあの地獄を味わうのかと思うと・・・

歯磨きの重要性を思い知った瞬間だった。

2010-04-16

暗いニュースが多いなぁ・・・

日本の政治関連のニュースを読んでいると暗いニュースしかみない。
まぁ、税金は払ってないし個人的にはあまり関係ないのだがやはり読んでいると辛い。

ポーランド大統領の国葬に出席しない総理大臣とか、
オバマ大統領にLoopyと呼ばれる総理大臣とか、
ジミンガーと叫んで自分の責任を放り出す総理大臣とか、
普天間基地の話はマスコミが報道し過ぎたせいで国民が知りすぎたなんて言っちゃう総理大臣とか、
そのくせ桜を見る会は開く総理大臣とか、
会話全文を読んでも質疑応答になってない回答をする総理大臣とか、
そもそも、国会に出ることが嫌いで仕事するのも嫌いそうに見える総理大臣とか

そんな感じの洒落で済むものから洒落にならないレベルのものまでたくさん。
(どれをとっても洒落にはならんが・・・)

ま、それを報道しない(らしい)マスコミも大問題だろうし、傀儡政権の裏でとんでも法案を無理やり通そうとしている民主党幹事長がいるらしいけど・・・

大丈夫なんだろうか、日本・・・

個人的に一番問題だなと思うのは、こんな状態になってもデモ一つ起こさない国民だろうと思ったり・・・
もはや政治家は役に立たないどころか、敵でしかない状態なのだから何か行動を起こす人がいてもよくないか?
(といって自分が起こすわけでもないので、やはり僕も問題な国民の一人・・・)

2010-04-10

OS: GRUBの続き

昨日のエントリーで、いまいち動かないと書いたが、少し前進した。

マルチブートに関してヘッダー等がいるので、GRUBのサイトからmultiboot-0.6.96をダウンロード。その中にboot.Sというファイルとkernel.cというファイルがあるのでコピー。
(とりあえず、動作確認できればいいので・・・)
っで、普通にビルド。
_edataが定義されてないと怒られる。

なんだこれ?

Google先生に聞いてみる。

・・・

・・・・・・

・・・・・・・・・

.dataセクションの終わりを示すポインタらしい。
うわさによるとリンカーが自動で作るものらしいが、CygwinのGCCではなのかGCC 3.4.4ではなのかは知らないが作ってくれないらしい。
とうことで、リンカスクリプトを書く。
というか、ここから拝借。
cygwinではelf-i386はサポートされてない(というかpe-i386しかサポートされてない)ので、OUTPUT_FORMATの行を削除。OUTPUT_ARCHも、まぁいらんかなと思い、削除。
っで、make。
なんか表示された。

激しく文字化けというか、意味不明の文字ばかり見えるが、とりあえず何か表示されているのでよしとしよう。
あとはカーネルっぽくいろいろ作るだか(というかそれが一番大変だと思うが・・・)

2010-04-09

OS: GRUBをCygwinで無理やり使う

ここ3日くらい調べてようやくなんとかなった。

ひょっとして同じところで躓いてる人がいるかもしれないので、メモ。
用意するもの:
Cygwin(当然か)
VFD(ここから)

あらかじめ、fstabに以下を記述。
a: /cygdrive/a vfat binary,posix=0 0 0
っで、ddでFDサイズのファイルを作って、VFDで開いてフォーマットしたら、
grub-installでFDイメージにインストール。このとき、デバイスは/dev/fd0を指定する。

面倒なので、スクリプト書いた。
#!/bin/sh -x
# generate floppy image with grub2.

grub=/lib/grub/i386-pc
file=fd.img
vfd=/cygdrive/d/bin/vfd/vfd
fd0=/cygdrive/a

# create floppy image.
dd if=/dev/zero of=$file bs=1k count=1440
$vfd open $file
# format
$vfd format
# いらないかも・・・
mkdir -p $fd0/boot/grub
# 適当にモジュールを指定しているので、必要なもの不必要なものは調べる。
grub-install --modules="_chain ls pc multiboot gpt fat boot reboot configfile cat help " --root-directory=$fd0 /dev/fd0
# grub.cfgは作ってくれないので、別途コピー
cp grub.cfg $fd0/boot/grub

$vfd save
$vfd close
こんな感じ。
きっと必要に応じて、イメージのdevice.mapとかを編集すればいいはず。とりあえず、GRUBが起動するところまでは確認。

あとは、自前のカーネルを読み込むだけなのだが、grub.cfgの書き方がいまいち分かっていない・・・
それとも、カーネルの方がまずいのかな?
「error: attempt to seek outside of file」
ってエラーだからカーネルかな・・・
調べないと・・・

2010-04-03

小ネタ

あまりに書いてないので小ネタを小出しに・・・
(半分くらい下ネタかも・・・)

日本にいたときのこと。
(こないだの帰省の時です)
栄スカイルのABCマートに靴を買いにいった。ものすごい勢いで地域が特定されているが気にしない・・・
大抵そういう店はBGMが流れているが、そのとき流れていた曲の一部に「ピーナッツ」って言っていると思われる部分があった。
でも、どう聞いても聞こえ方がNGな聞こえ方・・・
「ッツ」が「ス」に聞こえる・・・

どう考えてもアウトだろうと思った瞬間だった。

気合で探してみた。
くるりの愉快なピーナッツという曲みたい。

3:58秒くらいが個人的にはアウト・・・
いい曲だとは思うのだが、そこが印象に残りすぎる・・・

2010-03-19

最終日

明日の朝に日本を発つ。
8時40分の飛行機なので、チェックインは6時半くらいか?
ここ読んでて暇でこのクソ朝早くにこれそうな人は見送りに来てくれるとすごくうれしい、と明に言ってみよう。

最初にオランダに渡ったときは新天地に移動みたいな感じだったので、そうでもなかったが、今回は少し寂しい気がする。
やはりここにはいろいろ残してきたんだなぁと実感した。

涙で前が見えないということはないが、そんな気分。

2010-03-14

定演

行ってきた。

久しぶりに会えた先輩とかもいらっしゃってちょっとした同窓会の気分。
演奏自体は、合同はよかった。
後は、Topが抜きすぎで・・・少人数で大人数の歌い方をしていても映えんだろうと思うのだが・・・

2年後の合同は計画を立てて立つ予定でいこう。

2010-03-11

今更ながら

日本にいます。
先週の土曜日に戻っていました。

現在とりあえず日本を堪能してます。
高速が高い・・・

日本語が話せるっていいなぁ・・・
道とか分からなくてもとりあえずコンビニで聞けるとか便利すぎ!!

一応来週までいます。

2010-02-27

若者の○○離れ

それは無いだろうのある意味究極系。
ずばり、「若者のメンズブラ離れ」!!!
最初から近寄ってねぇし!!!

ちなみにその元となったであろうニュースの一部
ここ
それに対する反応
ここ

ちなみに若者が離れたもののまとめちっくな記事
ここ

いろいろなもの離れたね。
何で離れたかの原因は追求されてないところもポイントかね。

2010-02-26

鞍替え

長年(大学3年の時から)xyzzyを使ってきたが、諸事情によりEmacsを使うことにした。
職場のPCが英語だから文字化けするとか、将来的にLinuxを使う予定があるとか、利用者人口が多いのでスクリプトが充実してるとか、まぁ理由はいろいろ。

xyzzy自体がEmacsのCommonLisp版みたいなものなので鞍替えしてもそんなに違和感はない、っがさすがに個人的な設定とかはしないと些細な違いに戸惑う。
大きなのは、C-hのHelpだろう。
後は今まで使ってきたxyzzy-lispをemacs-lispからみつければ終了。
まぁ時間はそんなにかからない。

個人的にはさくさく動いたxyzzyの方がいいかなぁとも思いながら、Emacsももっさり感を除けばいい感じなので満足。
しばらくは平行して使うことになるかな。
それにしても、xyzzyのフォルダごとグレップとかの昨日ってEmacsにもあるのかな?

2010-02-23

招待状

大学の時に所属していた合唱団から定期演奏会の招待状が届いた。
正直驚き!!
実家の方に届くものだと思っていた。心意気はすばらしい!

ま、呼ばれなくても行くつもりだったけどね。
それはそれと置いておいて、微妙なダメだし。
今日届いても、航空券、有給とうはどう考えても間に合いません。最低2ヶ月はほしいです。

しかし、壮大な曲ばかりで驚いた。
雪花もあるし・・・懐かしい。もう歌えんが・・・
今メンバー何人なんだろう?

2010-02-15

C++: グローバル領域

GCの続き。
スタックからルートを取得する方法は理解したが、グローバル変数はどうするんだろうと調べてみた。
メモリの領域は、スタック、データ、テキストの3つに分かれていて、テキストが実コード、スタックはスタック、っでデータ領域にグローバル変数とかが入るらしい。
じゃあ、これを取得すればいいんじゃん!なんて思ったのだが、調べてもそんなもの頭と底をとる方法がない。普通こんなもん意識しないから、ある意味当たり前か・・・

とりあえず、試してみてだめだったこと。
DSセグメントレジスタを16ビット左シフトした値を頭とし、最初にヒープから取得したアドレスを底として捜査。
→ 無理。よく見るとグローバルなアドレスはヒープよりも下にある。

ちなみに、もう一つ問題があって、こんなコードが不正になる。
int *p = (int*)gc_malloc(sizeof(int) * 4); // とりあえず4つ確保
p[0] = 1;
p[1] = 2;
gc_collect();
// p[0] == 0 !!
コレクターを呼び出さなくても、GCが走れば不正になる。
理由:GCでアドレスが変わるので、例えばpが0x0032fec8を指していて、GC後に0x0033fda8になったとすると、実際に変数pが指している値はそのまま前の値になって不正になる。
スタックポインタの指す値を上書きしてるから大丈夫かと思ったら、甘かった・・・う~ん・・・

2010/02/18追記

実際には上記の不正は違っていて、回収されてはいけない値が回収されていた。
原因はスタックポインタ上にアドレスが無いから。
なぜ?
少し処理を足すとスタックが上書きされたりして、グローバル変数なのに問答無用で回収されたり・・・
なぜだ・・・

2010-02-11

C++: Copy GC

C++ではなくてCの話だが、まぁいいや。
いろいろな理由があってガーベジコレクションの勉強をしている。
BoehmGCを使えばいいのだが、ちょっとした理由からそれができないので・・・

っで、とりあえず保守的GCかPreciseGCしか知らなかったので調べてみた。
結構いろいろ種類があるが、Mostly-copying GCがよさげかなと(根拠なし)思い、その元となったCopy GCを実装してみた。
といってもこのページをとりあえず理解のために写経しただけとも言う。

基本の考え方は、ヒープとルートが分かればなんとかなりそうな感じ。
っが、どうやってルート調べるのかがすごく疑問だった。
それを解決してくれたのがこのページ
一般教養としてのGarbage Collection
ぜんぜん一般教養ではないと思うが・・・
ルートは基本スタック上につまれている変数から辿れるポインタだと思えばよさそう。
なら、ESPの値を引っ張ってくればいいだけじゃん、と思い実装。
動いた!

このままでは使えないのでもう少し調べないとなぁ・・・
(Mostly-copying GCの実装って難しいのかな?ぜんぜん見ない・・・)

2010-02-10

movie: AVATAR

土曜日に観たので、実は4日くらい前・・・
アバターを観てきた。リアルの世界にパンドラがないって言って自殺(?)しちゃう人がでたやつ。

以下、多分にネタバレ注意。



物語は他の星に移民する地球人の一人、ジェイクを中心に進められる。
このジェイク君(といっても、見た目は僕より年上だったから、30以上か?)がものすごくガキ!精神的に。
個人的に副題は、ジェイク成長物語だと思っている。
宣伝(?)どおり彼は下半身不随で車椅子。なので、動く体を手に入れられてはしゃぐ。っで、はしゃぎすぎて他のメンバーとはぐれ、アバターの村にの娘に命を助けられる。
これはチャンスとばかりに地球軍がジェイクにスパイを命じ、ジェイクはアバターの生態(といっても言語とか生活習慣とか)を探る。
正直、この辺までは微妙。いや、アクションとかは多めでいいんだけど、ジェイクが図体の割りにガキっぽくて見てていらいらした。
っで、しばらくすると、地球軍が領地を広げるために木をなぎ倒していく。止めようとするジェイク。相手は鉄の塊、メインカメラを素手で壊して終了。
っが、当然カメラなので自分の姿が映り、謹慎処分をくらう。
地球軍は何故か星を侵略して自分たちの物にしたいらしく、戦争をしかける。
っで、後はお約束の勧善懲悪(ではないが)なアクションで地球軍を倒し、ジェイクがアバターに生まれ変わって終了。

どこに欝になる要素があったのか分からんかった。
個人的には、白人 VS ネイティブアメリカンって感じ。この映画の中では、アバター、自然の動物が一体になって星を侵略から守ったけど、
歴史上では卑怯な白人がネイティブアメリカンから土地を奪い取ったんだよなぁ、とか思いながら観てた。
軍隊とか、地球連合軍なのにすごくアメリカっぽい感じだったし(ものすごく偏見が混じってます)
2度観たいとは思わない感じの映画。でもCGとかアクションとかはよかった。
ストーリーは正直2流だなぁと感じた。
(何様のつもりだ、俺・・・)

2010-02-05

電話

以前はほとんどなかったのに、今更になって結構頻繁(といっても月1程度)にエージェントから電話がかかってくる。
正直今更・・・

たいていMonsterBoardから来てるんだけど、ぜんぜん更新してないのにどうして引っかかるんだ?
(まぁ、未だに職探し中のステータスにしてあるのも問題か・・・)
ようやく景気が上向いてきて求人が増えたか、時期的なものか、単にこの業界が慢性的な人手不足かのどれかだとは思うが。
結構条件いいのが多いのよね・・・本当に何で今頃・・・

2010-02-02

Linux: UbuntuをVirtualBoxで試してみた

会社のPCでだが・・・

とりあえず、デフォルトでインストール。
ものすごく簡単だった。ネットで調べる必要がないくらいに。
デフォルトのWMがGnomeなので、KDEに変更。
初めて触ったWMがKDEなのでKDE好き(^^;

使用感。
Linuxのディストリビューションなんて、Fedora、Redhat(ほぼFedoraと一緒)、Debianくらいしか構ったことないし、
デスクトップLinuxで本格的に使ってたのはDebianだけなのであまり比較はできないが、
個人的には気に入った。
外側がKDEな上にUbuntu自体がDebianを元に作られてるのである意味当たり前か。
いろいろやるのにsudoしなきゃならないところとか、GUI上だとMaxかよって突っ込みを入れたくなる頻度でパスワード求められるけど。

ちなみに、
DebianをVirtualBox上で試そうと思ったんだけど、インストールが上手くいかなかった・・・
これ実機でもこの調子だとしたら、やっぱりきついよなぁ・・・

次にPC買ったらUbuntuかな。
(OSなしのPCが安く売ってればだけど・・・でもWindows7とかに特に魅力を感じないんだよね・・・)

2010-01-30

練習中の曲に関してのメモ

ギターの練習をしている。別に発表会とかはない。
ちなみに、練習してるのはこの曲

激ムズ。ギター暦1年未満がやる曲ではない気がする。しかも、クラシックギターではなく鉄弦のアコースティックギター・・・
それは置いておいて、これをやるにあたって必要そうな奏法のメモ。

ハンマリング、プリングオフ: いたるところで
ラスゲアード: 動画の49秒くらいのところのフレーズで出てくる
タンボーラ: 最後のノリがよくて格好いいところで
ポルタメント、グリッサンド: 結構いたるところでみる
チョーキング: 1分くらいのところで
ゴルベ?: 最後の方

タンボーラってサンピングのことか?
いろいろ無謀な気がするが、ロングスパンでやろう・・・

2010-01-28

OS: メモリ

ここ数日(数週間?)まったく時間が取れなかった。
今も取れているかはよく分からんが。

OSがメモリを割り当てるところで停まっていた。
まぁ、今も停まっていると言えばそうだが・・・

いまいちページングがよく分からない。E820hで取得したメモリーマップ情報からメモリアドレスを取得して、そのアドレスに対してページングOnする。
そこまでは上手くいっている(と思う)
っで、とりあえずmallocもしくはnewが使えないと話しにならない。ということで実装していたのだが、どうも変な挙動をしていた。
今日ふと、ページを初期化してから、アロケータの初期化をしたら、動いた(・A・)

鼻から悪魔が出るコードかもしれんが、とりあえずこれでいこう。
この辺が動けば少しやりやすくなるし・・・

まじめに参考書探さないとなぁ。
だれかお勧めの本とか知りませんか?

2010-01-24

ブリュッセル

ベルギーのブリュッセルに行ってきた。
別に観光情報とかが書かれるわけではない。単に所感。

実は(前に書いたっけ?)ブリュッセルに行くのは2度目。1度目はあまりいい思い出が無く終わったので、少し心配だった。
今回は2泊3日なので、まぁ少しゆっくり見て周れるかなと思いつつ、南駅(?)に到着。
メトロに乗ってホテル近くの駅まで。
一日目はこれで終了。仕事が終わってからなのでまぁこんなものだろう。
ちなみに、ロッテルダムからブリュッセルまで2時間弱くらい。

二日目とりあえず歩く。ショッピングストリートとか。本屋を探したが欲しい本が売っている店は見つからず。
どうでもいいが、ベルギーは一応オランダ語(フラマン語?)が公用語なのだが、ブリュッセルでは見るだけで、主に耳に入ってくるのはフランス語だった。
北部にあるアントワープではオランダ語だったのに、不思議。頻繁に旅行するようならフランス語を覚えた方がよさそうだ・・・
街自体は、新旧が入り混じってる感じ。パリの町並みによく似ているなぁと思わせるところが多々あったし、やはりフランス寄りなのだろう。
歩きつかれたのでホテルに戻って2日目終了。

3日目は日曜日なので店という店は閉まっている。雨も降ってるし、ということで特に何もせず帰る。

ちなみに、本当にどうでもいいことだが、ブリュッセルの平均身長は割りと低めだった。僕が普通か少し高いくらいに分類される感じだったので。
オランダの平均では僕は間違いなく低い方・・・190超えがごろごろいるんだよ・・・
ちょっとだけベルギーを好きになった瞬間だった。

2010-01-17

movie: シャーロックホームズ

映画の話。

予告ではホームズは荒くれ者で、ワトソンが知的って感じで、いまいちじゃねぇのこれって思っていたが、裏切られた(いい意味で)
いろんな新要素というか、見たことないホームズが見れたけど、それはそれでありな感じ。
ホームズ好きもそうじゃない人も楽しめるんじゃないかと。

最後の最後でモリアーティー教授の名前もでてきたし、エピソード2もあるのかね?
出たら見る自信がある。それぐらいよかった。

日本で公開されるか分からんけど。
(多分されるだろう。宣伝されてる?)

C++: 構造体でアドレスを読む

我ながら意味不明なタイトルだ。
やりたいことは、アセンブラが設定した配列をC++(またはC)の構造体に入れるってそれだけなんだけど、何故かはまっている。

アセンブラは適当なアドレスに値を入れる。こんな感じで。
0x00002840: 0x00000000 0x0000000 0x0009fc00 0x00000000
0x00002850: 0x00000001 ...
これが配列の一要素。
っで、まぁこれはE820hで取得したメモリーマップなので、普通にこんな構造体で受け取る。
struct MemoryMapEntry
{
  uint32_t baseAddrLow;
  uint32_t baseAddrHigh;
  uint32_t lengthLow;
  uint32_t lengthHigh;
  uint32_t type;
};

// どこかの関数で
MemoryMapEntry mapEntries = getMemoryMapEntry(); // これはアセンブラ内で定義した。
これで普通ならいけるはずなんだけど、取り出される値がおかしい。上記のアドレスなら、
baseAddrLow  = 0x00000000
baseAddrHigh = 0x00000000
lengthLow    = 0x0009fc00
lengthHigh   = 0x00000000
type         = 0x00000001
になるはずなんだけど、こんな感じに実際にはずれる。
baseAddrLow  = 0x00000000
baseAddrHigh = 0x00000000
lengthLow    = 0x00000000
lengthHigh   = 0x00000000
type         = 0x0009fc00
感じとしては、20バイト取得できてないといけないのだが、12バイトしか取れてない感じ。なぜ?
これが普通の動作なのかなと思い、ちょっと実験してみた。
#include 

struct sample
{
    unsigned int val1;
    unsigned int val2;
    unsigned int val3;
    unsigned int val4;
    unsigned int val5;
};

void* getsample()
{
    static int *addr = (int*)0x404030;
    addr[0] = 0x00000000;
    addr[1] = 0x00000000;
    addr[2] = 0x00000000;
    addr[3] = 0x0009fc00;
    addr[4] = 0x00000001;
    return addr;
}

int main()
{
    sample *s = (sample*)getsample();
    printf("addr: %x\n", s);
    printf("%x, %x, %x, %x, %d\n", s[0].val1, s[0].val2, s[0].val3, s[0].val4, s[0].val5);
    return 0;
}
こんなむちゃくちゃなコードでもなんか動いてるから不思議。
っで、結果は普通に予定通りの値が取れていた。
コンパイラの最適化が効いてるからなのか(何もオプションつけてないけど)、別の要因で直にアドレスから取るのとは違うのかよく分からん。

何より腹が立つのは、以前はまともに動いていたのだ!ページングの実装を終えたらおかしくなった・・・
関係があるのかな、やっぱり・・・

2010/01/17 追記

原因が分かった。
結論: まともに動いていました。
原因: VGAクラスで実装していたprintfメソッドの不具合。
64ビットの数値には%xの書式指定子が対応しておりません・・・
参考にしている人はいないと思うが、
64ビットの整数値を表示したいのに、可変引数のポインタを進める際に(int*)のポインタでやっとりました。つまり、8バイト移動させないといけないところを、4バイトしか進めていなかったっと。
これで2時間悩んだ。printfデバッグの限界やね。と勝手に納得・・・

OS: ページング

メモリ管理をしないと動的にメモリが取れない。
っで、とりあえずページングに手を出してみることにした。

とりあえずここを参考にしつつ、人のコードを見つつ。
っで、ページングONしてやって、qemuで起動すると、何故か無限リスタートしてくれる。
意味が分からんなぁ、と思いながらMonaのソースを見る。
(分からなくなったときのMona頼りというわけではないが・・・)

PageManager.cppのsetupメソッドを見ると、VRAMのアドレスをページング対応してる。何でだろうと思いながら、とりあえず似たようなことをしてみたら、動いた(・д・)
ページングをONにするということはすべてのアドレスをページング対応する必要があるのかな?
よく分からん。
ちなみに、ページング対応させたアドレスの属性を、書き込み可能、ユーザー領域、カレントにしないとだめだった。意味はよく分かっていない・・・(汗
無知っていやだなぁ・・・
勉強しないといけないのだが、こっちじゃ書籍も探し難い・・・ネットの情報だけじゃ厳しくなってきたというのに・・・

っで、これ書いてるときに気がついたのだが。
そういえばバイオスのE820h命令でメモリーマップを取得してるんだから、適当なアドレスを使用すれば、動的メモリーの割り当てができるような気がするなぁ・・・
ページングの前に実装するべきだったか?

2010-01-16

OS: 便利リンク

自分のための便利リンク。
ChangeLogとか、メモとかHDDに置けよという意見は無視。

[Wiki]
OSDev(English)
osdev-j(MMA)(日本語)

[ブログ]
OSのようなもの
Outlandish Watch(日本語)

[BIOS関連]
Ralf Browns Interrupt List

何か見つけたら随時足すことにしよう。

2010-01-14

C++: クラスのサイズ

これをググったのももう何度目かなので、いい加減メモっておこう。

C言語のstructは基本中身のバイト数の合計+パディングになる。例えば下記のような構造体があったとする。
struct Sample {
  int   value1;
  char  value2;
  short value3;
};
この場合だと上記の基本に当てはめて、
int = 4, char = 1, short = 2, total = 7になるが、
7だとキリが悪い(あまりいい表現ではないが)ので、パディングがcharとshortの間に入って8になる。
(詳しくは、バイト境界とか、アライメントとかでググって)

っで、C++の話。
C++のクラスはC言語の構造体と違ってメンバ関数を持つことができる。これが曲者。
例えばこんなクラスがあったとする。
class {
  public:
    void print();
  private:
    int value;
};
この場合は、クラスのサイズは4になる。なぜか?
どれだけメンバ関数が足されてもサイズには影響が無いそうだ。実際、GCCの-Sオプションで吐き出されるアセンブリを見たらなんとなく納得した。

っが、仮想関数が入ってくると別の話。
仮想関数はvtblを不可視のメンバ関数として持つので、そのポインタアドレス分増える。つまり4バイト。

なんでこんなことを調べたかというと、メンバ関数を持つクラスを普通の構造体として扱いたかったから。まったく普通なら問題なんだけど、メモリの内容を直接(例えばmemcpyとか)クラスの中に移したかった。
そうすると、クラスのサイズが重要になるので。
それだけの話。

2010-01-10

感覚が狂ったか?

座頭一がTVでやっていたので見た。
最初から見たわけではないので、序盤の話はよく分からなかったが、まぁ大まかな内容はつかんだと思う。

っが、別に今回は映画の内容ではなく、その中ででた台詞で不思議な感覚を味わったという話。
最後の最後で口縄(これでいいのかな?)の頭が、
「おめえ、メクラじゃねえのか?」と聞くのに対して、座頭一が、
「そうだよ」と答える一節。
これを見たときに、
「やっぱり盲目なんじゃん」と思った矢先に、座頭一が目を開けた!!

あれ?
なんで?

きっと、日本語→英語→理解の順になっていたのだろう。こんな感じで。
「おめえ、メクラじゃねえのか?」 -> "Aren't you blind?"
「そうだよ」 -> "Yes"

う~む、日本語がおかしくなってきたか・・・

2010-01-09

Makefile: 依存関係

自作OSをビルドする際に、当然(?)makeを使うわけだが、ずぼらな僕は「make」って打つだけで全部やってほしいと思うわけだ。

っが、依存関係の問題があって、今まで
「make clean all」
なんて、毎回プロジェクトをリビルドしていたわけだ。
けど、これ今はまだいいが、ファイル数が10とか100とか増えた時に非常に面倒になる。
というか、僕の貧弱なノートPCでは時間がかかりすぎるようになる。
(こんなことやってるのに、使用してるPCがノートかよ、って突っ込みはなしで)

っで、とりあえず、依存関係を自動で解決するようにMakefileを書き直した。
ポイントになるのは、gccの「-MM」オプション。
っが、makeのマニュアルにある方法だと、sedを使う。っが、WindowsでMingwだけで何とかしようという環境の僕にはsedはおろかCygwinもない。
適当に、gccが吐き出す依存関係を編集して上手いこと書き出すプログラムをC++で書いた。
なんでこんなことしなきゃならんのだろうか?

これだけいろいろ便利になってるんだから、こんな変なノウハウじゃなく、もう少しスマートな解決方法があってもいいような気がする。

2010-01-08

C++: 初歩的なこと・・・

VGAのを使って色を変えたり、文字を表示させたりするということ実装していた。
リアルモードからプロテクトモードに移行するとBIOSが使えないので、VGAを使う必要が(ないかもしれないが)ある。
っで、主にこの辺とかMonaの初期のソースとかを参考にしながら、しこしこ書いてみた。

っが、なぜか一行おきに空白がでる(縦に)。なんでだろうと、いろいろVRAMに与える値を変えたりしながら考えてみたが、一向に改善しない。
おかしいなぁと思いながらトイレにいって思いついた。
そういえばVRAMのアドレスはunsigned shortのポインタだなぁと・・・
Monaはunsigned charでサイトはunsigned shortなので、ポインタに加算を行った際のアドレスが1バイトずれる。

これか。

おさらい。

// ちなみに、0xb8000はVRAMのアドレス
unsigned char* ptr = (unsigned char*)0xb8000;
unsigned short* ptr2 = (unsigned short*)0x8b000;
ptr++; // 0xb8001
ptr2++;// 0xb8002

これを行った際に。ptrとptr2のアドレスは異なる。
あほかと思うくらい当たり前だが、はまった。

2010-01-07

OS: IPL

その筋には(というと変な雰囲気がでて格好いい?)有名だが、
2ch発祥のOSでMonaというのがある。最初の会社にいたころに知ったから、2005年くらいか?
あれから、5年。何を思ったのが、僕もOSを作りたいと思ってきた。
(昔から思っていたが、当時は何をしていいのかさっぱり分からなかった。が、最近なんとなく必要なものが見えてきた。暇にかまけて勉強したのが功を奏した感じ)

っで、Monaをはじめ、いろいろ調べてみた。
30日でできる! OS自作入門とかが有名っぽいが、こっちじゃ買えん。
っが、結構実践サイトとかあって、解説が読めないだけでソースは読めたりする。

っで、IPL(OSを起動する前にBIOSが起動する。ブートローダーと同義?)を作ることからはじめることになるのだが、これが難しい(当たり前だが)
アセンブラがよく分からない(アセンブリ言語自体は割りとシンプルなのだが、アドレスとかレジスタとかがいまいち分からん)
あと、GCCとNASMの相性が悪い(というかGASとGCCの相性がよすぎるのか?)というのもあって、とりあえずNASMを選択していた状態ではさっぱり分からんかった。

とりあえず、このサイトの自作OSのタグに書かれているのを参考に(ほとんど丸写し)、IPLを作成。
GASを使うとCの関数がそのまま呼べるので楽!!
リンカスクリプトを使うとコンパイル時にプログラムのサイズが取れるので、FDの読み取りに必要なセクタ数が分かって楽!!!
なんて感じだった。
はじめからこれにしておけばよかった。
回り道は無駄じゃないと信じたい。

2010-01-04

ASM: 勉強中

何を思ってか、アセンブリ言語のお勉強中。
(いや、ちゃんと目標があってだけど)
(Shemeはどうした?勉強してますよ)

どうでもいいけど、アセンブリ言語をアセンブラでアセンブルするんですよ(多分)
AssemblyをAssemblerでAssembleするかね、英単語にするとちと分かりやすい?
(yをeeにすると、employ、interviewと同じ関係やね)

横道どころでなくそれた。
最初(未だに)、NASMを使うか、GASにするか。NASMはIntel標準なので、(ちょっとだけ)汎用性が高い。GASはGCCとの親和性が抜群。
とりあえず、標準という言葉に弱いので、NASMにした。

アセンブリ言語の構造は非常に簡単といってもいいと思う。
基本、こんな感じ
;; 簡単なprint
;; 呼び出しは、
;; mov si, msg_pointer
;; call print
;; こんな感じ
print:
  pusha
  xor bx, bx
.loop:
  lodsb
  or  al, al
  jz  .end
  mov ah, 0x0e
  int 0x10
  jmp short .loop
.end:
  popa
  ret
命令とレジスタの組み合わせでいろいろやる。ここまでは、それなりにいろいろ言語をやってきたので簡単に理解。
問題はこの辺
mov ah, 0x0e
int 0x10
今となっては何か分かっているのだが、最初は何のことやら・・・
これは、上のlodsbでALレジスタにSIレジスタに格納されている文字列の先頭を格納していることを前提に、AHレジスタにBIOSの0x0e(表示)命令を入れて、int 0x10で実行している。
BIOSのint 0x10はビデオ関係の命令を実行するという意味で、
AHレジスタに一文字表示の命令0x0eを格納し、ALレジスタに文字コードを入れる。
BIOSの命令は、使用するレジスタ、命令の種類が決まっているので、それを調べる必要がある。
例えば、こことか。

後は、セグメントとオフセット、各レジスタの意味とかが重要になってくる。
正直、覚えられん(まだ1週間・・・)
とりあえずの、備忘録。

2010-01-01

movie: トワイライト サーガ

邦題は知らん。とりあえずそのままカタカナにしてみた。

新年一発目はこれだった。
エピソード2らしい。

感想(以下はネタバレが含まれる可能性があります)
個人的な感想を最初に書こう。
3流映画で見る価値なし。

無いよう自体は、バンパイアの子孫(?)のエドワードと狼男のジェイコブ、普通の人間のベラの恋模様を波乱万丈っぽく描いた無いよう。
その昔みた、ママレードボーイの三角関係そのままって感じ。
ただ、
エドワード → 貴族な優男
ジェイコブ → 野性味あふれる感じ
ベラ → エドワード一筋なくせに、ジェイコブも捨てがたい超わがまま娘
って感じだった。
う~ん、あんまり批判的な意見を書いて、名誉毀損で訴えられるのも嫌なので、これくらいにしてしまおう。
正直、意味不明だった(英語が理解できないとかではなく、内容が)

あけましておめでとうございます

本年もよろしくお願いいたします。

今年は初詣もなく、なんとも静かな新年であります。
すこし物足りない気分でもあります。

旧年は、行く年来る年を見ることもなく、年が明けた瞬間の花火(と呼ぶにはあまりにやかましい)にはずいぶん驚かされました。
(市がやってるわけじゃなく個人。しかも結構大きめな打ち上げ花火。そりゃ指なくしたり、足なくしたりするわ)

本年は寅年ということで、躍動感あふれる年にしたいと思います。

2009-12-26

クリスマス

メリークリスマス。一応。

今日は26日なので、日本ならケーキが半値以下になっているはず。
っが、こっちはセカンドクリスマスといって、祝日!だったりする。
(ちなみに、クリスマス自体も祝日)
今年は土曜日なのであんまり関係ないが。
(来年は25と26で土日なので最悪だが)

クリスマスということで、えらい勢いで(名古屋弁)物が売れたらしい。
買い物にいったら売り切れとかどんだけ・・・
しかも売り切れたのは3日前とかどんだけ・・・
という状態だった。
この不況に消費が活性化されるのはいいことだとは思うけどね。

そんな感じであった。
取り留めないなぁ・・・

2009-12-22

Scheme: ソースを色づけするスクリプトを書いてみた

何か実用的なものを作ってみようと思い書いてみた。
(実用的かどうかはよく分からんが・・・)
1: (require rnrs/hashtables-6)
2: (define keywords (make-eq-hashtable))
3: (define (set-keywords)
4: (begin
5: (hashtable-set! keywords 'define "<span style=\"color: blue;\">define</span>")
6: (hashtable-set! keywords 'if "<span style=\"color: blue;\">if</span>")
7: (hashtable-set! keywords 'let "<span style=\"color: blue;\">let</span>")
8: (hashtable-set! keywords 'letrec "<span style=\"color: blue;\">letrec</span>")
9: (hashtable-set! keywords 'lambda "<span style=\"color: blue;\">lambda</span>")
10: (hashtable-set! keywords 'cond "<span style=\"color: blue;\">cond</span>")))
11: (define (keyword? key)
12: (hashtable-contains? keywords key))
13: (define (highlighted-keyword key)
14: (hashtable-ref keywords key ""))
15: ; string might be like this "(define",
16: ; this function should return like this -> "(<span style=\"color: blue;\">define</span>"
17: (define (has-tag? str)
18: (let loop((strls (string->list str)))
19: (cond ((null? strls) #f)
20: ((char=? (car strls) #\<) #t) ; if the string has "<" it's must be tag(might be < procedure...)
21: (else (loop (cdr strls))))))
22: (define (list->symbol ls)
23: (string->symbol (list->string ls)))
24: (define (parse-keyword str)
25: (if (has-tag? str)
26: str ; if the string has tag, just return.
27: (letrec ((ls (string->list str))
28: (set ((lambda (l)
29: (let firstb((c (car l))
30: (rest (cdr l))
31: (ret '()))
32: (cond ((null? rest) (cons ret rest))
33: ((char=? c #\() (cons (append ret (list c)) rest))
34: (else (firstb (car rest) (cdr rest) (append ret (list c)))))))
35: ls)) ; blanket + space
36: (br (car set))
37: (rest (cdr set)))
38: (if (null? rest)
39: str ; only ( or spaces
40: (let ((key (list->symbol rest)))
41: (if (keyword? key)
42: (string-append (list->string br) (highlighted-keyword key))
43: str))))))
44:
45: (define (read-file file-name)
46: (with-input-from-file
47: file-name
48: (lambda ()
49: (let loop((ls '())
50: (c (read-char)))
51: (if (eof-object? c)
52: (reverse ls)
53: (loop (cons c ls)(read-char)))))))
54:
55: (define (last-char str)
56: (let ((l (string-length str)))
57: (if (= l 0)
58: (integer->char 0)
59: (string-ref str (- l 1)))))
60:
61: (define (high-light str)
62: (let ((ls (string->list str)))
63: (if (null? ls)
64: ""
65: (let loop((forward "")
66: (c (car ls))
67: (src (cdr ls))
68: (is-quoted #f)
69: (is-escape #f))
70: (cond ((null? src) (string-append forward (string c)))
71: ; escape begin
72: ((char=? c #\&)
73: (loop (string-append forward (string c)) (car src) (cdr src) is-quoted #t))
74: ; escapse end
75: ((and is-escape (char=? c #\;))
76: (loop (string-append forward (string c)) (car src) (cdr src) is-quoted #f))
77: ; quote
78: ((and (char=? c #\") (not (char=? #\\ (last-char forward))))
79: (cond ((and is-quoted) ; end quote
80: (loop (string-append forward (string c) "</span>") (car src) (cdr src) #f is-escape))
81: ((not is-quoted) ; begin quote
82: (loop (string-append forward "<span style=\"color: green;\">" (string c))
83: (car src) (cdr src) #t is-escape))
84: ; in quote
85: (else (loop (string-append forward (string c)) (car src) (cdr src) is-quoted is-escape))))
86: ; comment
87: ((and (not is-quoted)
88: (not is-escape)
89: (not (char=? #\\ (last-char forward)))
90: (char=? c #\;))
91: (string-append forward
92: "<span style=\"color: #006600; font-style: italic;\">"
93: (string c)
94: (list->string src)
95: "</span>"))
96: (else
97: (if (and (< 0 (string-length forward)) (char-whitespace? c)) ; if the charactor is whitespace
98: (begin
99: (set! forward (parse-keyword forward)); check if the string is keyword
100: (loop (string-append forward (string c))(car src) (cdr src) is-quoted is-escape))
101: (loop (string-append forward (string c))(car src) (cdr src) is-quoted is-escape))))))))
102:
103: (define (make-line str num)
104: (string-append "<div><span style=\"display: inline-block; width: 30px; font-weight: bold; text-align: right;\">"
105: (number->string num)
106: "</span>: "
107: (high-light str)
108: "</div>"))
109:
110: (define (escape c)
111: (cond ((char=? #\< c) "<")
112: ((char=? #\> c) ">")
113: ;((char=? #\" c) """)
114: ;((char=? #\& c) "&")
115: (else (string c))))
116:
117: (define (read-line source)
118: (if (null? source)
119: '()
120: (let line((ret (cons "" (cdr source)))
121: (c (escape (car source))))
122: (cond ((null? (cdr ret)) ret)
123: ((string=? "\r" c) (line (cons (car ret)(cddr ret)) (escape (cadr ret))))
124: ((string=? "\n" c) ret)
125: ((string=? "\t" c) (line (cons (string-append (make-string 8 #\Space)
126: (car ret))
127: (cddr ret))
128: (escape (cadr ret))))
129: (else (line (cons (string-append (car ret) c)
130: (cddr ret))
131: (escape (cadr ret))))))))
132:
133: (define (build-html contents)
134: (define (build-itr contents)
135: (let build((ret "")
136: (line (read-line contents))
137: (num 1))
138: (if (null? line)
139: ret
140: (build (string-append ret (make-line (car line) num))
141: (read-line (cdr line))
142: (+ num 1)))))
143: (string-append "<pre>" (build-itr contents) "</pre>"))
144:
145: (define (main args)
146: (if (null? args)
147: (begin
148: (display "usage: scm2html file-name")
149: -1)
150: (let ((contents (read-file args)))
151: (set-keywords)
152: (display (build-html contents))
153: (newline))))
154:
155: (main "scm2html.scm") ; test
長い上に汚い・・・っが、開き直ってさらしてみた。

仕様:
* 行番号付与
* コメント、文字列及びキーワード色づけ
* タブをスペースに変換。

既知の不具合:
ダブルクオート(文字列)の色づけ周りは大分怪しい。文字列の後ろになんか文字がないとタグがおかしくなる。(ブラウザで見る分には問題ないけど、HTMLとして不正になる)

Perlで作れば簡単なのに何やってんだろうとか思いながら作った。Schemeは文字列処理得意じゃないのかしら?
(正規表現使ってないからだと思うが・・・R6RSって正規表現サポートしてるのかな?)

寒い寒い

雪が溶けない。土曜日にこんな感じだった。

今のところ、そのまま足跡がついた程度でとどまっていたりする。寒い。

こんな雪の中、ドイツに行こうとした(実際には以前から計画していた)。
ユトレヒトで国際列車(?)に乗り換えてという感じ。
ユトレヒトの駅はこんなだった。(ユトレヒト中央駅のバーガーキングから)

国際線は来ませんでした(昨日の話)。
まぁ、いかないと決めたのだが、今日電車がドイツまで走っているか調べてみた。


はい、ありませんでした~(ごちバトルの羽鳥アナ風)

この量の雪は珍しい(らしい)とは言え、いくらなんでも雪に弱すぎだろうオランダ。

2009-12-18

寒い

現在、オランダは冬です。当たり前です、北半球なんだから。
寒い。マジで。
最高気温1度って何ですか?殺す気ですか?
秋の雨で(工事中の穴に)たまった水が凍って、スケートできそう。
そんな気分です。

これだけ寒いと、当然彼が来るわけです。そう、白い悪魔君が・・・
ってか、来ました。10cmくらい・・・

雪が降ると日本でもそうだけど交通事情がえらいことに(名古屋弁)なります。
特に電車。
30分おくれは当たり前。
運休とか勝手に路線変更とか連発。
7時に家をでて9時半ちょい過ぎに職場に着きました。
いつもなら8時ちょい過ぎです。勘弁してください。

ってか、雪が降ること分かってる国のはずなのに、雪対策が無いってどういうことだよ!
おかしいだろ!!

Scheme: SICPの練習問題(2.68)

飛んでたりする。いや、これ以前もちゃんとやってますよ(^^;

以前Huffman符号のことを(LHAの話か?)をちらっと書いて、あきらめたとも書いたがその話題だったのでついつい。
とりあえず、Huffman符号木について。木自体はこんな感じ。
{A B C D E F G H} 17
               *
             /   \
           A 8     * {B C D E F G H} 9
                 /     \
     {B C D} 5 *           \
             /   \             \
           B 3     * {C D} 2      * {E F G H} 4
                 /   \        /       \ 
               C 1   D 1    * {E F} 2     * {G H} 2
                          /   \         /     \
                        E 1  F 1      G 1     H 1
いまいち二分木に見えないのはご愛嬌。
ここではなのか、一般的になのか、左に行けば1、右にいけば0となっている。数字は重み(多分、頻出度)

デコードは、ビット列から文字列を復元するので、先頭からビット見て行って葉にたどり着いたところで一文字復元完了という感じ。
エンコードは逆。上から木を舐めて、葉にたどり着くまでもビットを記録するって感じ。

っで、2.68の解凍
(define (encode-symbol symbol tree)
  (define (has-symbol? symbol tree)
    (if (leaf? tree)
 (eq? symbol (symbol-leaf tree))
      (or (has-symbol? symbol (left-branch tree))
   (has-symbol? symbol (right-branch tree)))))
  (if (leaf? tree) ; 葉ならシンボルを見つけた
      '()
    (let ((left (left-branch tree))
   (right (right-branch tree)))
      (cond ((has-symbol? symbol left)
      (cons 0 (encode-symbol symbol left)))
     ((has-symbol? symbol right)
      (cons 1 (encode-symbol symbol right)))
     (else (error "error"))))))
最初はcondの中でifを使って変な場合分けをしてlistを返してappendしていたが、解答はすっきりconsを使ってた。いまいちこの辺の使い方がまだ身について無い感じ。う~ん。
まぁ、でもHuffman符号の具体的なやり方がわかったということでちと満足。
(もやもやとは分かっていたが、木の作り方とかいまいちだった)

2009-12-12

TopCoder

アルゴリズムでググッたら出てきた。
面白そうなので登録。

サイト自体はプログラムコンテストサイトで、与えられた問題を解いていくというもの。
解ける問題から、そうでもないのまで幅広い・・・
とりあえず自力で解いて、誰かが書いた解答を見る。
自分が未熟を通り越して、スタート地点にも立ってないのかと思わされた。

基本的なことでできるのだが、柔軟な発想とか、数学的知識がぜんぜん足りない。
気づいたのだから勉強しないと・・・

2009-12-09

Scheme: SICPの練習問題(2.17~2.28)

最近SICPを読み始めた(オンラインなので、英語。きつい・・・)
SICPはMITが出してる本で、バイブル的な何からしい。
1章の問題は数学チックなのが多いので、半分くらい飛ばしてしまった。後でやろう。
折角なので、(自分の)答えを載せてみたり。

下のは職場のGaucheで作って(おいおい)、家のMzSchemeで確認。
MzSchemeだと「()」が使えないので、「'()」に変更。
一つMzSchemeで動かないのがあった。処理系依存なコードだったのかしら?
; 2.17
(define (last-pair list)
  (define (last-pair-itr val list2)
    (if (null? list2)
 val
      (last-pair-itr (car list2) (cdr list2))))
  (last-pair-itr (car list)(cdr list)))
(last-pair '(1 2 3 4 5 6))

; 2.18
(define (reverse list)
  (define (reverse-itr ret list2)
    (if (null? list2)
 ret
      (reverse-itr (cons (car list2) ret) (cdr list2))))
 (reverse-itr '() list))
(reverse '(1 2 3 4 5 6))


; 2.21
(define (square-list-no-map list)
  (if (null? list)
      '()
    (cons (* (car list) (car list))
   (square-list-no-map (cdr list)))))
(square-list-no-map '(1 2 3 4 5 6))



(define (square-list list)
  (map (lambda (x)(* x x)) list))
(square-list '(1 2 3 4))


; 2.22
(define (square-list items)
  (define (square x)(* x x))
  (define (iter things answer)
    (if (null? things)
 answer
      (cons (square (car things))
     (iter (cdr things) answer))))
  (iter items '()))
(square-list '(1 2 3 4 5))


; 2.23
(define (for-each proc items)
  (if (null? items)
      #f 
    (and (proc (car items))
  (for-each proc (cdr items)))))

; 2.25
(car (cdr (car (cdr (cdr '(1 3 (5 7) 9))))))
(car (car '((7))))
(car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr '(1 (2 (3 (4 (5 (6 7))))))))))))))))))

; 2.26
(define x (list 1 2 3))
(define y (list 4 5 6))
(append x y)
(cons x y)
(list x y)

; 2.27
(define x (list (list 1 (list 2 3) (list 4 5)) (list 6 7 8)))
(reverse x)
(define (deep-reverse list)
  (define (reverse-itr ret list)
    (cond 
     ((null? list) ret)
     ((pair? (car list))
      (reverse-itr (cons (reverse-itr '() (car list)) ret) (cdr list)))
     (else (reverse-itr (cons (car list) ret)
   (cdr list)))))
  (reverse-itr '() list))

; Gaucheでは動いたコード
;(define (deep-reverse list)
;  (cond
;   ((null? list) '())
;   ((pair? (car list)) (cons (car (cdr (car list)))(car (car list))))
;   (else (cons (deep-reverse (cdr list)) (car list)))))
(deep-reverse x)


; 2.28
(define (fringe l2)
  (cond ((null? l2) '())
 ((not (pair? l2)) (cons l2 '()))
 (else (append (fringe (car l2))
        (fringe (cdr l2))))))
(fringe (list x x))

2009-12-03

時間がほしい

働きつつ、(オランダ語)学校にいってるから平日は時間が全然無い。
日が昇らないうちに出社して、暗くなってから帰宅なんて生活だ。
(ちなみに、今の時期は8時ちょい過ぎに日が昇り、5時前に日が沈むけど:-P)

最近つらつらと考えていることの備忘録。
  1. 何か実用的なものを作りたいなぁ

    • ちょっと考えてるのはC++実装のServletサーバー。需要なさそうだけど・・・
    • OSとか言語処理系とかも面白そうだ。
    • 最近意図的にBoostを避けてたけど、そろそろ使おうかな。やっぱり便利だし・・・

  2. オランダ語の文法で意味不明だった部分が理解できた

2. について。
オランダ語の変な文法が理解できた。こんなの↓
Vandaag ben ik moe.
(英訳) Today am I tired.
ずっと、何で主語が動詞の真後ろに移動してるんだ?と疑問だった。なにしろ、普通に書くと
Ik ben moe vandaag.
になるのに、Vandaag(今日)を強調すると、上記みたいになる。
なぜ?
っで、理由。
Persoonsvormen(人称系?誰か訳教えて)は必ず2番目に来る。
Persoonsvormenとは英語で言うところの、三単現のSが適用される位置にある動詞のこと。つまり、格変化する動詞。
変なルールとか思いながらも、そのルールに当てはめれば確かに納得がいく。
ちなみに、他の文法は結構英語に似てるので、そんなに苦労はしない。っが、語彙が圧倒的に足りないのでぜんぜん話せない。先は長そうだ・・・

2009-11-29

C++: BFDを使ってみる その2(たぶん最後)

昨日の続き。いろいろできそうだなと思ったが、少し落とし穴があった・・・

【落とし穴その1】
mprotectで取得した関数のアドレスを実行可能とか読み込み可能とかにしないと動かせない。
よく考えればあたりまえか・・・
っが、MingwとかCygwin(要するにWindows環境)にはそげなものがない・・・

【落とし穴その2】
dlopenとかdlsymとかその辺の話。ある意味当然ではあるが、共有ライブラリじゃないと読み込めない。
上記の問題から、BFDでシンボル読み込んで、シンボル名をデマングルして、呼び出し時にシンボル名に変換してやればいいかなとか思ったんだけど、BFDはWindowsのDLLに対応していない。Mingwの-sharedオプションで作ったにもかかわらずである。
(本当かどうかはよく知らん、調べてない。PEに変換しているからか?)

この辺を試してみよう。Windows限定の話になるけど・・・

余談
折角なので(備忘録も兼ねて)、BFDの使い方をメモ。
こんな感じの流れ。
bfd_init(); //初期化。一回だけでいい。
bfd* abfd = bfd_openr("hoge.o", NULL); // .a とか .soでもいいと思う
if (bfd == 0) {
  bfd_perror("failed to open"); // error
  return; // 失敗したので
}
// オブジェクトのフォーマットチェック
// アーカイブとかもヘッダの中にあるので、適当に必要なチェックで。
// .aとかのアーカイブだと、.oが複数個入っているので、それ用の処理がいる
if (!bfd_check_format(abfd, bfd_object)) { 
  bfd_perror("format error"); // .o ファイルじゃないよ
  return; // それじゃ!
}
// 中身を読み込む
if (!(bfd_get_file_flags(abfd) & HAS_SYMS)) {
  return; // シンボルなし
}
long storage = bfd_get_symbol_upper_bound(abfd); // サイズを取得
if (storage < 0) {
  bfd_perror("bfd_get_symbol_upper_bound"); //  中身なし?
  return;
}
asymbol** symbol = (asymbol**)malloc(storage); // メモリ確保(new じゃだめなのかね?)
int symbolCount = bfd_canonicalize_symtab(abfd, symbol);
if (symbolCount < 0) {
  bfd_perror("no symbol"); // シンボルがない
  return;
}
// シンボルを読み出す
for (int i = 0; i < symbolCount; i++) {
  asymbol asym = symbol[i];
  int value = bfd_asymbol_value(asym); // シンボルの値(何が入ってるんだろう?)
  const char* name = bfd_asymbol_name(asym); // シンボル名(名前マングルされてる)
  if (name == 0 || ::strlen(name) == 0) continue; // シンボル名が無ければ次
  symbol_info info;
  bfd_symbol_info(abfd, asym, &info); // シンボル情報を取得(中身はよく知らん)
  // 関数ポインタ
  int* fp = (int)file->contents // .o ファイルの中身(バイナリで読み込む)
            + asym->section->filepos // セクションの場所?
            + value;
  // 多分セクションデータとかを自分自身に配置しないと
  // (略)
  mprotect((void*)(((int)fp+4095) & ~4095 - 4096),
          4096, PROT_READ | PROT_WRITE | PROT_EXEC);
  /* こっちのが正しい?(どっちにしろMingwでは動かん
  long pagesize = sysconf(_SC_PAGESIZE);
  char *p = (char *)((long)s & ~(pagesize - 1L));
  mprotect(p, pagesize * 10L, PROT_READ|PROT_WRITE|PROT_EXEC);
  */
  //適当にキャストして、実行
  typedef void (*fnc)(); // とりあえず、戻り値、引数無しと仮定
  fnc fncP = (fnc)fp;
  fncP(); // 実行
}
多分こんな感じ。実際に動かせないので、正しいかどうかは保障できない。
(他人のコードから推測、というかほぼ丸写し、しただけだし・・・)

2009/11/30 追記

落とし穴その1は大嘘であった。
mprotectで実行可能にしなくてもWindowsだと普通に動いた。Cで作った関数だが。
C++側だとどうもいろいろ面倒なのだろう。コンストラクタとか、継承とか。
(確かに、仮想関数のアドレスとかどうやって取るとか、thisポインタを渡すとか、考えればいくらでも解決しないといけない問題がありそう)
憶測だが、コンストラクタのアドレスが分かったところで、クラス全体の情報が取れているわけではないのだろう。ヒープに取るメモリの量とかコンストラクタだけじゃ取れそうにないし。
構造体がBFDから作れるか試してから探した方がいいだろうか?
(C互換の構造体だと単なるメモリの塊というイメージだが・・・)
気合入れればいけそうなのだが、頭と気力が足りない感じ・・・前者が特に・・・orz

2009-11-28

C++: BFDを使ってみる

前にLHAの展開を書いていたが、それとはぜんぜん関係ない話。
LZHUFがいまいち分からなくて挫折したとも言う・・・orz

BFD、big fucking dealがBinary File Descriptorになったライブラリ。GCCに付属してくるもの。
何ができるかといえば、オブジェクトファイルとか、アーカイブファイルからいろんな情報が取ってこれる。

っで、これを使ってC++らしくないものを作ってみようと考えたのだが、上手くいかない。
ちなみに、らしくないものとは、リフレクションのことである。
BFDつかってシンボルを読み込んで、関数のアドレスは取れた。名前マングリングされた関数名で取れるので、デマングルするか、呼び出しの際にマングルする必要があるが・・・
(あぁ、取得したときにデマングルすればマングラーなど要らんのか、無駄なもん作った)
っで、ここからが問題。
C++なので、newして、確保したメモリに対してコンストラクタ呼ぶ必要があるのだが、上手くいかない。
いくつか理由が考えられるのだが、どれだろう?
1. そもそも無理。
2. 取得が上手くいっていなくて、変なアドレスを指してる。
3. その他
取れるアドレスは、単に関数のアドレスなので、適当に関数ポインタにキャストするのだが、
こんな感じであってるのか?
// operator new の関数ポインタ
typedef void* (newP)(size_t);
newP p = (newP)pointer; // pointerは取得したnewのシンボルアドレス
void* buf = p(size); // 予定通りなら、bufには確保したメモリが入るはず・・・
が、今のところ結果はセグメンテーションフォルト。
う~ん、なぜ?
BFD自体もあんまり知られて無いのか、ネットに情報があんまりないし・・・困った。

2009-11-25

おいしいスパゲッティの食べ方

ここで言うスパゲッティとはいわゆるプログラム上の話である。つまりそういうことだ・・・
よく分からない人は、ググってください。
一応Wikipediaへのリンク

自社のコンポーネントを使って、スマートカードのデータを管理するシステムを提供する会社なのだが、そのコンポーネントが何年も前からの代々受け継がれてきたようなつくりになっていて、涙が出そうになる。
しかも、困ったことにドキュメントの類がない。ないことはないが、肝心な部分がない。製品マニュアルをみて理解しろというにはちと作りが悪すぎる。
外面はものすごくよくできていると思う。ユーザーインターフェースは秀逸と言ってもいい。それに反比例して開発者用のその他もろもろは・・・まぁそういうことだ。
更に困ったことに、5年とか10年とか開発に携わっている人でもよく分かっていないらしく、無駄なコーディングをしてバグをつぶすとか普通にある。
(というか、それをしたのでこれを書いてる)
ちょっとXMLの設定ファイルに10文字足すだけで直るバグを、Javaクラスを1つ作って、既存のクラスに定数を足して、XMLも弄ってということした。
それで給料もらっているのでいいといえばいいのだが、確認含めて30分で済む作業を4時間かけて修正するのはいかがなものだろうか?
(ドキュメントがないので、デバッガでソースを追いながらだとこんなもんだよと自分を慰める)

次回のメジャーバージョンアップでspringとかHibernateとかその辺のフレームワークを使って、メンテナンスしやすくすると言っているので、それを信じて耐えるか・・・

オランダの不思議

2つくらい不思議なものをみた。

その1.
オランダにはクリスマスシーズンに、サンタクロースとは別にシンタクロース(Sintaklaas)なるものがいる。彼はトナカイではなく、黒人のプリーストをつれてきて、なんだかよく分からん呪文(オランダ語で喋ってただけ)を唱えたのち、子供たちにプレゼントを配っていた。
本来は12月15日くらいの行事らしいが、(多分その時期は休暇をとる人が多いため)、僕の会社では11月末に移動したらしい。会社が(おそらく)福利厚生の一環(単にオランダ人が祭り好きなのかもしれんが)で行っていたので、社員の家族とか子供とかきてた。
ちなみに、この行事、いつの頃からシンタクロースがつれてくる牧師が黒人に変更されたため、黒人の人たちには受けが悪いらしい。よく知らん。

その2.
この国で(自称)上流家庭の人たちはナイフとフォークでパンを食べる。
正直見ていて滑稽に映るのだが、そういうことらしい。育ちがいいことの証明なのか、その方がマナーがいいと思われるのかは知らんけど。ちなみに、徹底してる人は、食べ物に直接手を触れないそうだ。
つまり、ナイフとフォークでパンを袋から取り出し、皿に置かれたパンにバターを塗り、Beleg(パンにのせるもの全般)をナイフとフォークで取り、切って食べる。
不思議な光景であった。
試してみようかとも思ったが、あまりに抵抗があるのでやめた。どうやら僕は上流家庭の人間にはなれないらしい。

2009-11-21

C++: istreamのread

職場の環境でexe、zipのファイルがダウンロードできない。
っが、普段使っているエディタじゃないとどうも調子が出ない(エディタは重要だ)
ちなみに、xyzzyである。Emacsライクな素敵エディタ。
配布形式はlhaなので、ダウンロードはできた。っが展開できない・・・
なら、自力で展開してやろうと思い、Lhaの展開プログラムを書いているのだが、まさかファイルの読み込みでえらいことになるとは思わんなかった。
普段は固定長のバイナリデータなんて扱わないからなぁ・・・
問題になったのはこんな感じのコード。
-----
unsigned char* buffer = (unsigned char*)new char[size + 1];
in.read(buffer, size); 
-----
ちなみに、「in」はistream。
こんな感じでやったら、何故かセグメンテーションフォルトで死んだ。理由はよく分からない・・・
デバッガで追っかけてもread()の部分で死んでるし、意味不明。
しょうがないので、1バイトずつとって押し込めることにした。
それだと動いた・・・なぜだ?

2009年11月21日 追記

理由が分かった。
利便性を高めるために、こんなメソッドを一枚かませていたが、それがいけなかった。
-----
template<typename T>
int get_byte(T& t, int size)
{
  in.read(reinterpret_cast(&c), size);
  return in.gcount();
}
-----
だめな理由も一日寝てすっきりしたらよく分かった。ある意味当たり前。
渡してるのはポインタなのに、受け取る方式はリファレンス。何が起きるんだろう?
ポインタのポインタみたいな感じになっていたんだろう。そりゃ鼻から悪魔が出てくるわ・・・
自分の未熟さだけを露呈しただけだった・・・orz

2009-11-16

初日

今日は仕事の初日であった。
場所はロッテルダム。駅前といってぜんぜん問題ない場所なので、通勤には非常に便利。
(電車通勤で1時間を下回る職場はこれが初めてだ!)
職種は何を血迷ったのか再びプログラマー。ま、日本と違って残業はほとんどない(らしい)ので、特に問題は無いだろう。
(問題になるとすれば、言葉か・・・いや、英蘭どっちでもOKなので大丈夫なはず・・・)

個人的にいろいろ日本にいたときと比較すると環境はいい気がする。
(給料はそんなに高くはないが・・・)
初日が終わったばかりで浮かれているというのもあるだろうが、それを差し引いてもいい会社だと思う。
(と思いたい。自分の中で結論が出るのは分かるのは早くとも1ヶ月後だろうなぁ・・・)
まだ試用期間中だしぼろを出さないようにしないと・・・

2009-11-15

2012

観てきた。
感想、いまいち・・・
インデペンデンスデイとかアルマゲドンとかと同じ監督らしい(よく知らん)
まぁ、インデペンデンスデイで感動できるなら・・・きっと、多分・・・

話の概要は、要するに現代版ノアの方舟といったところかな。
2012年12月21日に太陽系の惑星が一直線に並んで、その重力場の影響で地球のマントルが暴れる→津波→世界が沈む
こんな感じ。
ぶっちゃけ、突っ込みどころ多すぎ。
例えば、
高さ6000メートルを超える津波は起き得るのか?
わずか3年でArcと呼ばれる超巨大な方舟を7隻も作れるのか?しかも極秘裏に?
なぜアメリカだけがそのことを知っているのか?
(この場合、世界中に優秀な科学者はいるという意味)
その他、たくさん。

あんまりネタ晴らししてもいかんのでこれくらいで。
個人的に話のネタ程度に観る価値はあるかもといいたかっただけ。

2009-11-11

C++: テトリス

ニコニコ動画(たまに見るんです)に1時間でテトリスを作るという動画があった。
これ↓

300行そこそこのソースコードでそこそこ動くテトリスができてた。すげ~。
っで、触発されたわけでもないが、ちとGUIプログラムを組んでみたくなり、なんかいいライブラリ無いかなと探してたりする(Win32APIを直接構う気力はない・・・)

有名どころで、Qt、wxWidgetなどがあるが、ためしにという割には巨大すぎる。
(最初は慣れようという意味合いもあり、上記のテトリスをC++的にしてみようと思うのだが・・・)
っで、よさ下なのがWTLだったのだけど、ATLというライブラリが必要で、ATLはVisualStudioに入っているという・・・
それだけのためにそんなものを入れる気力もなく(そもそも僕のノートPCの容量では入れたくないというか・・・)
う~ん、適当な何かはないだろうか・・・

2009-11-07

カレー

カレーを作ってみた。
といってもカレールーを入れてというのではなく、ゼロから。
(カレールー使って作るんならブログに書くようなことではないし)

こっちでカレールーを買うとなるとかなり高い。1パック(ゴールデンカレーの小さいの)5ユーロとかする。高すぎ!
ということで、スパイスから作ることに。
【材料】
ジャガイモ 大4つ
鶏肉 どんなもんだか知らん、500gくらい?
たまねぎ
トマトピューレ
クミンシード
ローリエ
唐辛子
マギーキューブ

胡椒
味の素
-- 以下 ホワイトカレーソース(?)
小麦粉
牛乳
マサラ粉
--

【作り方】
たまねぎをスライス。鍋に油、クミンシードをいれ、たまねぎを茶色になるまで炒める。鶏肉投入。塩コショウ投入。いい感じになったらジャガイモ、水をいれ、マギーキューブ、ローリエ、トマトピューレ、唐辛子を投入。煮る。
その間にカレーソースを作る。ホワイトソースにかなり大目のマサラ粉を入れるだけ。気合で作る。多めに作った方がとろみが出やすい。できたら鍋に投入。
煮る、煮る、煮る。
出来上がり。

ジャガイモのでんぷんと小麦粉のグルテンでとろみがでます。一日経つとマジでカレーになってます。
適当にスパイスを足すとより風味が出るかも。
後は適当に。
たまには手作りカレーもいいもんですぜ!!

2009-11-03

オランダ語学校

新参者かつオランダ語がしゃべれない人用にオランダ政府が超格安(?)で学校の手配をしてくれる。
拒否権はないので、行くしかない・・・

ということで昨日が初日だった。学校に行くまでには仕事が見つかっているだろうとの目論見から夜間の部を選択。
(実際は・・・見つかってはいたりするが、まだ働いてない・・・)

っで、行ってみてびっくりしたこと。
1. 新参者(オランダに1年以内に来た人)は僕一人
2. ほとんどの人はオランダ語がしゃべれてるじゃん!!
3. 19年オランダに住んでる人が同じクラス
4. クラスの7割がトルコ人

トルコ人たちは(当然?)英語が話せない。僕はトルコ語が話せない。彼らとコミュニケーションをとるかどうかは分からんが、やるとしたらオランダ語になるのだろうか?
いい環境にいると思い込むとして、勉強するか・・・

2009-11-01

Perl: CGI.pmで気づいたこと

PaypalでIPNを受信する件は無事何とかなった。
解決するまでに3時間くらい必要だったが・・・
(んでもって、失敗していた理由が送るはずのパラメータを送ってなかったとか、それが間違っていたとかそんな話だったりする・・・-_-;)

PaypalのIPNはデータをPostで送信してくるので、追加のパラメータ(自分とこで必要なもの)をクエリーストリングで追加することにした。
方法は、Paypalのショッピングカート画面を開く際のパラメータの一つ「notify_url」で、コールバックURLの後ろの「?key=value」ってやっただけ。まぁ、「?、&、=」辺りはお約束の「%~」に変換する必要はあるけど。

っで、RubyとかPythonとかPHPとか使えない(使わない)僕はPerlのCGI.pmを使って送信されたデータを取得しているわけだが、普通にCGI.pmのparamメソッドを使っても追加パラメータが取れない。
でも、URLの末尾には「?key=value」がくっついてる・・・
しょうがないので$ENV{"QUERY_STRING"}で取得して、自前でパースした。
試してない上に、ドキュメントも読んでいないので憶測に過ぎないが、
送信メソッドが「Post」の際、CGI.pmはクエリーストリングを取りに行かないのかな?
理由はなんとなくわかるし、それがただし動作な気はするが・・・
(逆をやったら、おかしなことが起きるだろうし・・・、GETの時に標準出力から読むっての)
おかげで、数年ぶりくらいにこんなコード書いた。
my @query = split("&", $ENV{"QUERY_STRING"});
my %hash;
foreach (@query) {
  my ($key, $value) = split("=");
  $hash{$key} = $value;
}
実際は、$value =~ s/%([0-9a-fA-F]{2})/pack('H2', $1)/eg とか入れる必要があるだろうけどね・・・

Paypal: よく分からん

玩具販売サイト構築の話。
支払方法としてPaypalを利用するというところが決まっていて、PaypalのPDTとIPNについて調べて動作確認しているとろこなのだが、いまいちよく分からん。
なんというか、う~ん。ぶっちゃけ何が送られてくるのかわからんのがいかん。
IPN simulatorでも使ってみるかな・・・

ちなみに、PDTとIPNの違いについてはこの辺が分かりやすかった。
同期通信か、非同期通信かの違いなんだけどね。
しかし、何とかしてIPNに追加パラメータを渡せないかな。
そもそも、今のところIPNを上手く受信できて無いが・・・

2009-10-31

MySQL: 涙が出そう・・・

最近、MySQLを使っている。自分用ではない。自分用なら間違いなくPostgreSQLを選ぶと思う・・

MySQLは他のRDBMSと違って、SQLにくせがある。拡張SQLというか制限SQLというかとにかく不便。Update関係で自己相関クエリが使えないのは以前書いたけど、Viewの中でselect句を使って結合ができないとは思わなかった・・・

こんなのはNG:
CREATE OR REPLACE VIEW adult_member AS
SELECT m.name, m.age
FROM (SELECT * FROM member WHERE age >= 20) AS m;
そんな・・・さすがに困るなぁこれ・・・
将来的にはOKになるらしい。ソースはここ

個人的Q&A
Q:将来まで待てない状態の人はどうしたらいいのでしょう?
A:from句の中を別viewにすればOKです。

もうね、涙がでるよ、マジで・・・

2009-10-27

IE6: フリーズする

玩具販売サイトの話。
経緯はこの辺
(といっても、2行しか書いてないが・・・)

通常はFirefoxで開発して、確認でIE6とかを使っている。
(Firebugいいよ~)
っで、持たせてたデータをファイルからMySQLに移行したら、IEがフリーズするようになった・・・orz
理由はいまいち分からない。
考えられそうな理由
  1. Javascriptで変なことがおきている
  2. CSSの解釈で起こしなことがおきている
  3. DB接続が遅すぎてTimeout
よく考えると、3はありえなかったりする。
単にAjaxでhtml取ってきてるだけだし・・・

なぜだ?
IE6だからか?

2009/10/28 追記

原因が分かった。
prototype.jsのAjax.Updater(たぶんRequestでも)で、asynchronous(非同期通信)をfalseにすると起きてた。
まぁ、Ajaxのいいとこを殺していたので(理由もあったのだが)オプションを除去。
そのページはAjax通信だけで4~5ほどあったので、なんとなく納得。っが、FirefoxはOKだったのはなぜだ?
同時通信数増やしてたっけ?

2009-10-26

SQL: MySQLで更新、削除時に起きた問題

こんな感じのクエリーが動かない。
delete from 
   child
where id in
    (select p.id as id
    from parent p
    left join child c
    on p.id = c.id
    where c.id is null);
SQLの内容自体はよくありそうな、親テーブルと子テーブルを左側外部結合して、親テーブルにはあるけど子テーブルにはない行の削除といった感じ。
Oracle、DB2、PostgreSQLでは動いた記憶があったので、当然MySQLでもいけるだろうと思ったら動かない。
こんなエラーが出た。
ERROR 1093 (HY000): You can't specify target table 'child' for update in FROM clause
(適当な)訳:更新にはFROM区で指定した特定のテーブル「child」を使えないよ~ん。

調べてみた。
どうやら、このタイプのクエリは自己相関サブクエリというらしい。
ソースはここ
鬼かと・・・

解決方法を考えてみた。
1.所詮はプログラムで行っているのだから、クエリーを2回投げればいいじゃん。
2.Viewを一個こしらえれば回避できるらしい。
3.そもそもこんなクエリ投げるってことはデータの持ち方がおかしいのでは?
4.気合で解決方法探してみる・・・
4は方法じゃないね。

誰かいい方法知りませんか?

2009-10-24

C++: MingwでWindowsDLLを使う

Mingw GCCでVCとかでコンパイルされたDLLを使う方法。
この辺参考。

pexportsを使ってDLLの中で定義されている関数を抜き出す。
その後、そいつを使ってDEFファイルを作る。
んで、Mingw付属のdlltoolを使って「.a」ファイルを作って完了。

字面は簡単、実際は面倒だった。
リンカ実行時に表示される、「undefined reference "hogehoge@4"」みたいなのを全部洗い出して、上記のDEFファイルに書き込む必要がある。しんどい。
この辺の互換性って何とかならんのかなぁ・・・

2009-10-17

ぼくらの

漫画の話。アニメではない。
実際のところ、この作品との出会いはアニメのオープニングテーマなのだが。
っで、全10巻読んでみた。

感想:よくこんなの思いついたな作者・・・
基本設定は、別次元の地球と存在をかけての戦い。方法はどっかから与えられたロボット。
操縦者はロボットを操る力を得る代わりに戦闘終了後に必ず死亡。
「勝って地球を守って死ぬか」「負けて地球と一緒に死ぬか」の2択。
選ばれた時点で(最終的には自分で契約する必要があるが)、「死」確定。

内容は面白い。というか考えさせられる。
しかし、パラレルワールドと戦うってどっかで見た設定だな。
ポンコツのヘルメット被って、木刀で戦う高校生だった気がするが、なんだっけ?
思い出せん・・・

2009-10-14

StyleSheet: 高さの異なるカラムを揃える

まさにタイトルどおりの話。
この辺を参考にした。

なるほど、:afterを隠しておいて、必要になったら勝手に表示といた感じかな?
かなり面白い。多分高さ32768pxまで対応してるんだろう。なぜこの数値なのかはよく分からんが?
ブラウザが認識する最大値かな?

ソースが載ってなかったので載せておこう。
#content {
    text-align: center;
    margin:0 auto;
    overflow:hidden;
    /* width: 700px; *//*これ僕は必要なかったので削除*/
}
#content:after {
    content:".";
    display:block;
    height:0;
    clear:both;
    visibility:hidden;
}

#column1, #column2, #column3{
    float:left;
    padding-bottom:32768px;
    margin-bottom:-32768px;
}

#column1 {
    float: left;
    width: 20%;
}

#column2 {
    float: left;
    width: 40%;
}

#column3 {
    float: left;
    width: 35%;
}
幅は適当に変えた。
後は、それぞれのIDを持つHTML要素を作るだけ。
ずっと探していたがようやっと見つかったわぁ。
(前にも見つけた気はするが・・・)

タグがprogramになってるけど、あまりそれ以外に選択肢がなかったから・・・
(増やしたくないという理由で・・・)

2009-10-12

C++: expatを使ってみた

激しく今更感があるがexpatを使ってみた。
ちなみに、expatはSAXでXMLを扱うためのライブラリ。C言語で実装されてるけど、問題なくC++で使える。

RSSを読み込んでデータ型に落とし込もうということをしてみたんだけど、意外と難しい。
SAXってイベント駆動型のAPIなので、全部自前で管理するのだが、結構どうしたもんかなと言うときがある。
基本の動きとしては、
開始エレメント -> 中身 -> 終端エレメント
という感じで動くんだけど、
こんな感じのXMLだとえらいことになる
<hoge>
  <fuga>中身</fuga>
</hoge>
XMLは性質上、空白文字とかもテキストノードとして扱うので、イベントがこんな感じになる。
hoge開始
 ↓
改行文字及び、空白文字
 ↓
fuga開始
 ↓
中身の文字
 ↓
fuga終了
 ↓
改行文字
 ↓
hoge終了

正直、無駄イベントが多すぎな印象。こんな場合個人的には、改行文字と空白文字を除いてほしいのだが、そうもいかんらしい。自前で無視するか、イベントハンドラを追加するか・・・悩ましい。

2009-10-10

Javascript: 苦労した話

JavascriptでIFrameを扱う話。
「tmpl.js」という誰かが作っているライブラリを見つけ、便利そうだったので使おうかと考えた。
この辺
incl.jsで外部HTMLを読み込んで、tmpl.jsで文字列の置換を行うつもりだった。
こんな感じ。

本体
<include id="navi.html"></include>

外側
{ヘッダー部分(tmpl.jsとかとか)}
<a href="hoge.html">{something}</a>

上手くいかなかった。
正確にはFirefoxでは動くがIEではだめといった感じ。
あきらめて、prototype.jsとAjaxにした。
読み込んだ後にごりごり文字列の置換を行っただけ。

同じようにIFrameで別ページを読み込んで、中身だけ取り出そうと試みた。
外側のHTMLではAjaxを使ってデータを取得し、中身だけ取り出す、そうすることでサイトの外観の定義を一箇所にできるかなぁなんて思ったり。
無理だった。
理由:遅延処理のせい。
IEのIFrameにはonreadystatechangeなんてのがあるし、Firefoxは単にonloadに入れればいいだけじゃん、外側はonloadで読み込んでるし。
こんな感じで。
if (/*@cc_on ! @*/ false) {
  iframe.onreadystatechange = function() {
    if (this.readyState == "complete") {
      doSomething(this);
    }
  }
} else {
  iframe.onclick = function() { doSomething(iframe);}
}
安易でした・・・orz
問題はdoSomethingの中の処理なんだけど、IFrameから中身の文書を取り出すときに、contentWindowをが必要になるんだけど、IEではnullになってる。
やり方が悪いんだと思うんだけど、あきらめて力技でやることにした。

IE7とか8ならいけるのだろうか・・・
未だにIE6が必要なのかも怪しいが・・・
(とはいっても、僕の環境はIE6。メインがFirefoxだからという理由)

台風18号

人に言われて思い出した。そういえば最大級の台風が日本に上陸したとか・・・
っで、ちょっと地元のニュースを読んでみたが、結構ひどい。
割とピンポイントで知っている地名とか出てるし・・・僕の地元は大丈夫か?

K氏とかS氏とかの地元の写真が出てたなぁ・・・大丈夫かね?

2009-10-02

ギター

更に連投。。。
(いや、ちまちま上げるの好きじゃないから、ネタがまとまったときにドカンとアップなんて考えてないですよ)

こっちに来てからギターを始めた。バンド仲間などいないので、アコギでソロギター・・・
仕事が見つかるまでものすごく暇なのでというだけではなく、音楽にかかわっていたいという思いもあったからである。
足掛け7ヶ月か・・・
最近になって、ようやく少し弾けるようになったかなぁって程度なので、あまり才能はないのだろう・・・(TДT)

っで、なんとなく気づいたこと。
  • 以外にも左手は器用だったということ
  • 器用だと思っていた右手はそうでもなく、不器用だったんだということ
狙った2弦(or 3弦)だけを人差し指もしくは中指だけで弾くなんてムリポ・・・
右手よ、器用になってくれ~・・・

Javascript: DOM操作でテキストだけ抜き取る

連投。

以前かいたWebサイトで、「ページ内にあるサムネイル画像の検索を行いたい」なんて要望がでて、テキストの検索だからできるだろうと思って作ってみた。
ちなみに、各サムネイルはこんな感じ。
<span class="product">
<img id="hoge" src="hogehoge" />
<div>Produce Name</div>
<div>€ 50</div>
</span>
先頭要素が「span」なのはIE6対策。
っで、prototype.jsを使ってるので、document.getElementsByClassNameでサムネイルの各要素を取り出して、以下のスクリプトでテキストノードだけ抜き取る。
var tags = $A(element.getElementsByTagName("*"));
var text = "";
tags.each(function(tag, index) {
    var children = $A(tag.childNodes);
    children.each(function(node, index) {
        if (node.nodeType == 3) {
            text += node.nodeValue + " ";
        }
    });
});
elementは取得した要素配列の一つ。
元々はここにあったソースだけど、これはFirefox限定だったので、prototype.js使ってクロスブラウザにした。
ただ、それだけ。

どうでもいい話だが、上記のスクリプトの「var text="";」の部分、初期化せずに「var text;」って書くと、for文の中の宣言にもかかわらず、あたかもC/C++のstatic宣言みたいな動作してた。Firefoxでしか確認してないけど。バグか?

免許ゲット

日本の運転免許をオランダのに書き換えた。

オリジナル(日本の)はRDWという免許関連のことをしている機関に納められる。要は取り上げ。
が、確認したところによると日本の免許はちょっと特別で、1ヶ月後くらいに日本大使館に送付されて、取りに行けば返してくれるらしい。便利。
今のところ必要ないのが、気が向いたら取りに行こう。ちなみに日本大使館はハーグにある。

こっちの免許はなのか、書き換えたからなのかは知らないが、10年有効で、日本の免許の最長より5年長いことになる。
10年ここにいるかどうかは分からないが、面倒な手続きは10年に一回でいいのはいいことだ。
ちなみに、ぜんぜん関係ないが、パスポートは最長5年らしい。日本のだと5年のと10年のが選べる。なんかひっくり返った感じだ。
当然僕のは日本のパスポートなので、期間だけ見ればいいとこ取りな感じで得した気分。

っま、免許だけあっても車はないので、あんまり意味はないんだけどね。