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 |

April 27(Sun), 2008

[][] 1000speakers:4で話してきましたよ

とりあえず発表資料を。JRE1.5以上の環境がある人用の発表資料または資料を800x600に画像化したもの

April 24(Thu), 2008

[][] 1000speakers:4で話してきますよ。

イベント詳細はエロと風俗情報満載 どう抜く?

当日の会場の様子はustreamで中継されます。あとたぶん後日ニコニコ動画にもアップされる。

たぶんアホな話してきます。けっこう楽しみ。

[] みんな Perl やろうよ! - IT戦記に同意。

perlやる人の悪い癖として、perlやらない人の「perlはわけわからん」とかの発言に対して「HTTPサーバできたよー」

use IO::Socket;$SIG{CHLD}=sub{wait};for($s=new IO::Socket::INET(
LocalPort,9999,Listen,5,Reuse,1);$c=$s->accept;){if(!($p=fork)){while(
<$c>){if(/GET \/(\S+\.(\S+))/){open F,$1;read F,$d,-s$1;print$c
"HTTP/1.0 200 OK\nContent-Type: ",$2=="html"?"text":"image","/$2\n\n";
print$c $d}}}}

とか言って悪ふざけすることがあげられると思います。悪ふざけだとわかっていただければよいのですが。


とにかく、

use strict;
use warnings;

が書かれていないperlスクリプトは全部悪ふざけですので、perlやらない人はそんなコードに騙されてはいけません。perlの読み書きができるとちょっと楽しくなることが増えるので、みなさんperlもやるといいんじゃないかと思いました。

April 23(Wed), 2008

[] なんか急にPascalやりたくなった!

http://www.taoyue.com/tutorials/pascal/index.htmlをやることにする随時更新

こんにちは!

もうなにも憶えてなかったのでhelloworldから。

program Hello;
begin (* Main *)
  writeln ('Hello, world.');
end. (* Main *)

(* Main *)ってなんだよ! とおもったけどvimのシンタックスハイライトのおかげでコメントだとわかった。

% gpc hello.pas
% ./a.out
Hello, world.

writelnがあればもちろんwriteあるよね。

program Hello;
begin (* Main *)
  write('Hello, world.');
end. (* Main *)
% gpc hello2.pas
% ./a.out
Hello, world.%

読み書き

writeあるならreadある。引数無しなら()省略できんのかね。

program ReadWrite;
begin
  writeln('hogehoge');
  readln
end.
% gpc readwrite.pas
% ./a.out
hogehoge
dsjafi

読んだ値は使えるんですか

program ReadWrite;
begin
  writeln(readln)
end.
% gpc readwrite2.pas
readwrite2.pas: In main program:
readwrite2.pas:3: error: syntax error before `readln'

なんかちがうらしい。どうやるんだ。

一旦おちついて言語構造など

PROGRAM ProgramName (FileList);

CONST
  (* Constant declarations *)

TYPE
  (* Type declarations *)

VAR
  (* Variable declarations *)

(* Subprogram definitions *)

BEGIN
  (* Executable statements *)
END. 

なるほど。FileListあたりがかなりわからんけど先行こう。ところで、予約語は大文字小文字区別なしってことかなたぶん。最小プログラムは

program DoNothing;
begin
end.

と。ところでProgramNameてなんの意味があるんだろうね。

const節

こんな感じで定数を宣言できると。

program Constant;
const
  hoge = 'hoge';
  pi = 3.1415926535;
begin
  writeln(hoge);
  writeln(pi);
end.
% gpc const.pas
% ./a.out
hoge
 3.141592653500000e+00

writeさん意外と高機能ですね。アセンブリ出力見てみよう。

% gpc const.pas -S
% cat const.s
        .file   "const.pas"
        .section        .rodata
.LC0:
        .string "hoge\n"
...

ちゃんと"hoge"という文字列用意されてるなーと思ったら"hoge\n"だった。なんで! と思ってたらすげえ、writelnでしか使われんから"hoge\n"にしちゃってwriteしちゃってるみたい。

program Constant;
const
  hoge = 'hoge';
  pi = 3.1415926535;
begin
  write(hoge);
  writeln(pi);
end.
% gpc const2.pas -S
% cat const2.s
        .file   "const2.pas"
        .section        .rodata
.LC0:
        .string "hoge"
        .text
...

ちなみに型をちゃんと指定してやると、

program Constant;
const
  hoge : string[5] = 'hoge';
  pi : real = 3.1415926535;
begin
  writeln(hoge);
  writeln(pi);
end.

こんなんかね。stringの長さ指定はちょっとわからんな。たぶん、十分な長さとっておけばいいんだろうけど。自動で長さ読むとかできねえかな。

% gpc const3.pas
% ./a.out
hoge
 3.141592653500000e+00

Pascalに型推論があったのですかすげええ!! 型推論っていうのかこれ。

var節

変数がねえとなんにもできないよね!(手続き脳の恐怖

program Variable;
var
  i, j : integer;
  pi : real;
  ch : char;
  success : boolean;
begin
  i := 3;
  j := 4;
  i := i + j;
  read(ch);
  write(ch);
  writeln(i);
end.

適当に、たぶんこんなだったかなというプログラム。基本的なデータ型はinteger, real, char, booleanだそうで。さっき書いたstringってなんだ。

% gpc var.pas
% ./a.out
hoge
h7

うごいた。

標準関数とか

文字と整数の変換とか

program StdFun;
var
  ch : char;
begin
  read(ch);
  writeln(chr(ord(ch)+2));
  writeln(succ(succ(ch)));
end.
% gpc stdfun.pas
% ./a.out
3
5
5

すこしはプログラムらしいプログラム

(* Author:    Tao Yue
   Date:      19 June 1997
   Description:
   Find the sum and average of five predefined numbers
   Version:
   1.0 - original version
*)

program SumAverage;

const
  NumberOfIntegers = 5;

var
  A, B, C, D, E : integer;
  Sum : integer;
  Average : real;

begin    (* Main *)
  A := 45;
  B := 7;
  C := 68;
  D := 2;
  E := 34;
  Sum := A + B + C + D + E;
  Average := Sum / NumberOfIntegers;
  writeln ('Number of integers = ', NumberOfIntegers);
  writeln ('Number1 = ', A);
  writeln ('Number2 = ', B);
  writeln ('Number3 = ', C);
  writeln ('Number4 = ', D);
  writeln ('Number5 = ', E);
  writeln ('Sum = ', Sum);
  writeln ('Average = ', Average)
end.     (* Main *)

うわーA..Eは配列にしてえなあ。

% gpc sumaverage.pas
% ./a.out
Number of integers = 5
Number1 = 45
Number2 = 7
Number3 = 68
Number4 = 2
Number5 = 34
Sum = 156
Average =  3.120000000000000e+01

いちおう入力ありのプログラム

program SumAverage;
const
  NumberOfIntegers = 5;
var
  A, B, C, D, E : integer;
  Sum : integer;
  Average : real;
begin
  read(A, B, C, D, E);
  Sum := A + B + C + D + E;
  Average := Sum / NumberOfIntegers;
  writeln ('Number of integers = ', NumberOfIntegers);
  writeln ('Number1 = ', A);
  writeln ('Number2 = ', B);
  writeln ('Number3 = ', C);
  writeln ('Number4 = ', D);
  writeln ('Number5 = ', E);
  writeln ('Sum = ', Sum);
  writeln ('Average = ', Average)
end.
% gpc sumaverage2.pas
% ./a.out
1 2 3 4 5
Number of integers = 5
Number1 = 1
Number2 = 2
Number3 = 3
Number4 = 4
Number5 = 5
Sum = 15
Average =  3.000000000000000e+00

わー合計と平均値がだせたー、と。

Formatting Output

どうもwriteとかもっと高機能だったらしい。まじでか。

program Format;
begin
  writeln(1:10, 'i''m hungry':20);
  writeln(123:10, 'plz':20);
  writeln(3.1415926535:10:3, 'hoge':20);
end.
% gpc format.pas
% ./a.out
         1          i'm hungry
       123                 plz
     3.142                hoge

おー。普通に便利だな。

ファイルの読み書きとか

program FileIO;
var
  buf : string[100];
  filein, fileout : text;
begin
  reset(filein, 'file.pas');
  rewrite(fileout, 'hoge');
  read(filein, buf);
  writeln(fileout, buf);
  close(filein);
  close(fileout);
end.
% gpc file.pas
% ./a.out
% cat hoge
program FileIO;

まあなんか一行読めてる。resetとかrewriteとかなんだ。

EndOfFileのチェック

cだとまあ大抵返り値がEOFだったりNULLだったりとかを読んだりするかもしれんけど、Pascalだとeofで見るしか無いのかな?

program EOFcheck;
var
  filein : text;
begin
  reset(filein, 'hoge');
  writeln(eof(filein));
end.
% gpc eof.pas
% cat >hoge
% ./a.out
True

真偽値

not, and, or, xorなどあり。あとC系などとは違ってnot equalは!=じゃなくて<>

program BoolExp;
begin
  writeln('3=8':20, ' = ', 3=8);
  writeln('3<>2':20, ' = ', 3<>2);
  writeln('3<2.3':20, ' = ', 3<2.3);
  writeln('(3>8) or (10>2)':20, ' = ', (3>8) or (10>2));
end.
% gpc boolexp.pas
% ./a.out
                 3=8 = False
                3<>2 = True
               3<2.3 = False
     (3>8) or (10>2) = True

左寄せでformattingとかできねえかな。


はらへったからとりあえずここまで。

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

April 21(Mon), 2008

[] Garbage Collectionの学会

lucille development blog さんの 『プログラミング言語の学会』 は並列化やコンパイラに焦点を当ててまとめてらしたので、こちらは、Garbage Collectionという視点で纏めてみました。

なんかちょうど学会とかってどういうのあるのかなー、とか調べてみてるときにまとめとかあったんで、真似してみました。論文一本も書いたことない(どころかほとんど読んだこともない)、手探りサーベイしてる段階の学生がやってることですので、漏れとかツッコミどころはあると思います。

論文はだいたい403 - Forbidden Access to The Digital Libraryとかからいけば辿りつきやすいんじゃないかなと思う。ACMに登録してれば本文まで読めるんじゃないですかね。

SIGPLAN

Special Interest Group on Programming LanguagesAssociation for Computing Machinery(ACM)の分科会。プログラミング言語の学会の総本山と言える。

ISMM

International Symposium on Memory Management。メモリ管理(アロケータ、GC)分野のみに対象を絞った国際会議としてはおそらく唯一。

'92、'95に開かれた「The International Workshops on Memory Management」を前身として1998年に第一回が開かれ、以降は隔年で開かれている。

PLDI

Programming Language Design and Implementation。プログラミング言語全般の、主に実装よりの国際会議。GCの論文もよく採択される。

POPL

Principles of Programming Languages。これもプログラミング言語全般が対象だが、主に理論より。そのためかGCまわりの論文はPLDIよりは少ない印象を受ける。

OOPSLA

Object Oriented Programming, Systems, Languages, and Applications。オブジェクト指向プログラミングの学会。Smalltalk、Javaなどのオブジェクト指向プログラミング言語がGCを供えていることもあってか、GCの論文も多い。

MSP

Memory Systems Performance。メモリシステムに関する学会ということでGCの論文も多かったが、2006年以降の予定は無い模様。

ECOOP

European Conference on Object-Oriented Programming。OOPSLA同様、GCの論文は多い。


そもそも論文とか全然読んでない身なので、私感による簡単な印象というものを付すことができないのが悲しいところ。ほとんどpreceedingのタイトルとかだけ読んで書いてます。(たぶん)ISMMをおさえておくのは当然としても、探せば探すだけ色々な学会からGCの論文出てくる気すらしました。GCとの戦いはかくも長いものなのだなと感じましたね。専門家の突っ込みお待ちしております。

以下 2008/05/01 追記

GC屋さんの書いたGC学会まとめありましたね! その辺参考にしつつ追記。

MM-NET

The UK Memory Management Network。メモリ管理に関する情報とか集まっている。workshopも開かれてるので、メモリ管理に対象をしぼった国際会議ISMMの他にもあったようで。ここが管理しているGCのベンチマークまとめは、なんかGCで論文とか書こうと思うなら目を通して損は無いんじゃないかな!

VEE

International Conference on Virtual Execution Environments。仮想マシンのような、仮想的実行環境の学会。JVMだCLI、Parrotだのといった高水準な言語をターゲットとしたVMなどではGCが重要ですし、GCの論文は多いです。あのHans Boehm先生がchairですね。

SPACE

Workshop on Semantics, Program Analysis, and Computing Environments for Memory Management。ISMMと同じあたりをターゲットとしてる? メモリ管理そのものとかいうより、メモリ管理するためのほげほげをまとめてるということか。

April 20(Sun), 2008

[] 呼ばれるタイミング

C++の、コンストラクタとかデストラクタとかコピーコンストラクタとかの呼ばれるタイミングとかがイマイチ感覚としてわからん。以下のようなコードを実行してみたりして、まあ自分で定義したものはだいたいこんな感じかなー、と想像することはできるかなあ。あんまわからん。

#include <iostream>
using namespace std;
class Fuga {
  public:
    string name;
    Fuga(string _name)
    {
      name = _name;
      cout << "new " << name << endl;
    }
    ~Fuga()
    {
      cout << "delete " << name << endl;
    }
    Fuga(Fuga& ref)
    {
      name = "Copy" + ref.name;
      cout << "copy " << name << endl;
    }
};
class Hoge {
  public:
    Fuga *child;
    string name;
    Hoge(string _name)
    {
      name = _name;
      child = new Fuga("Child"+name);
      cout << "new " << name << endl;
    }
    ~Hoge()
    {
      delete child;
      cout << "delete " << name << endl;
    }
    Hoge(Hoge& ref)
    {
      name = "Copy" + ref.name;
      child = new Fuga("Child"+name);
      cout << "copy " << name << endl;
    }
};
Hoge& hogef(Hoge hoge)
{
  puts("in hogef");
  return hoge;
}
int main(int argc, char *argv[])
{
  puts("m1");
  Hoge hoge("HOGE");
  puts("m2");
  Hoge fuga = hogef(hoge);
  puts("m3");
  return 0;
}

実行するとこんなんで、引数と返り値の受け渡しは値渡しで基本コピーコンストラクタ経由になると。で、スコープの外になって消すときにはデストラクタを呼んでくれる。

% ./a.exe 
m1
new ChildHOGE
new HOGE
m2
new ChildCopyHOGE
copy CopyHOGE
in hogef
new ChildCopyCopyHOGE
copy CopyCopyHOGE
delete ChildCopyHOGE
delete CopyHOGE
m3
delete ChildCopyCopyHOGE
delete CopyCopyHOGE
delete ChildHOGE
delete HOGE

まあそういうのはさておいて、stringのname = _name;とかがわからんなー。あー、basic_stringがその定義か。templateだな。


「better CとしてC++を使う」にしても、templateわからんとやっぱりスッキリ気持ち良く使えねえなー。なんかこういいかげんに手探りするよりやっぱりすっぽすぽ先生の原典読もう。わりとおもしろそうだったし。

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

April 18(Fri), 2008

[] ガベコレおいしい!!! (または いかにして 私がガベコレを研究にするのを諦めたか)

以下いいかげんだぞ! 信用するな!! 諦めてねえし!!!


ガーベジコレクション(以下GCとかガベコレとか略す)は大事。なんで大事かって言うと、動的メモリ領域*1の管理は開発における最大のボトルネックの一つだから。メモリ管理のためのコードのために頭使うところもそうだし、わかりにくいバグ入れちゃって、後から直さなきゃいけなくなった場合なんてもっと大変。だからもうさ、プログラマの力を信用するのは止めてGC使わせときゃもうちょっとだけ世界が幸せになれるんです。


でまあ実際各種スクリプト言語とかJavaとかD言語とか、最初からGCを前提としたプログラム言語も普及してるし、GCの重要性は鰻登りなのです。というか「重要なんだってば!」という意見がようやく市民権を得てきたのです。


というわけでまず、その辺のこととか調べるときに使った諸々へのリンク

一般教養としてのGarbage Collection
PDF。日本語での入門レベルGC文書では一番まとまってる気がする
GCアルゴリズム詳細解説
書いてることもそうだけど、あちこちへのポインタとしてとてもありがたい!
no title
Boehm先生のGCのページ。論文とかの情報とかものってる。
ftp://ftp.cs.utexas.edu/pub/garbage/gcsurvey.ps
Paul Wilson's サーベイ論文。基本的なGCアルゴリズムの解説と、それらがどの論文に書いてあるかがまとまってる。通読すると(この論文が出された1992年頃の)昨今のGC界隈の情勢とかわかるんじゃないですかね! あんま読んでない!
Garbage Collection
GCの教科書的一冊。すごい初歩的なところから、様々なアルゴリズムまで網羅している感じ。とても良さそう。英語だけど。
Garbage Collection: Algorithms for Automatic Dynamic Memory Management

Garbage Collection: Algorithms for Automatic Dynamic Memory Management

この辺から適当に辿ったWEBページやら論文とかを眺めたりしてるNow。とりあえず「一般教養としてのGarbage Collection」はわかりやすくて、お勉強云々ぬかしても普通におもしろかったのでみんな(って誰だ! 人類全部じゃね!)読むといいと思う。

学会

Garbage Collectionの学会 - hogeなlogにGC関連の学会をまとめてみました。最新の動向を知りたいなら学会とかをチェックするといいのではないでしょうか。

この辺に「ヒープってなにそれおいしいの!?」とかを挿入する予定

GCの動作例

たとえば以下のようなcプログラムを実行してみます。mallocがNULL返すか、10万回mallocを実行したらループを抜けて終了するみたいですね。

#include <stdio.h>
#include <stdlib.h>
#define SEG 100000
int main()
{
  int *p;
  unsigned long count = 0;
  while(1) {
    if((p = malloc(SEG))==NULL) {
      fputs("no heap\n", stderr);
      break;
    }
    if(++count>100000) break;
  }
  printf("count: %d, heap: %llu\n", count, (unsigned long long)count*SEG);
  return 0;
}

環境によって結果は違ってくるかもしれませんが、例えばこんな出力をします。

% gcc over.c -o over
% ./over
no heap
count: 32050, heap: 3205000000

mallocさんが「10万回もできるかボケ、3205600000バイトもヒープ領域確保したんだから勘弁してくれ!」と悲鳴を上げてNULLを返して終了してしまいました。ではGC*2を使った以下のようなコードに書きかえてみます。

#include <stdio.h>
#include <gc/gc.h>
#define SEG 100000
int main()
{
  int *p;
  unsigned long count = 0;
  while(1) {
    if((p = GC_malloc(SEG))==NULL) {
      fputs("no heap\n", stderr);
      break;
    }
    if(++count>100000) break;
  }
  printf("count: %d, heap: %llu\n", count, (unsigned long long)count*SEG);
  return 0;
}

stdlib.hじゃなくてgc/gc.h、mallocじゃなくてGC_mallocとしてるだけですね。で、以下のようにコンパイル実行。

% gcc gc.c -lgc -o gc
% ./gc
count: 100001, heap: 10000100000

なんと10万回のmallocをやり遂げました。なんで? GC_mallocとか使うとヒープ領域が大きくなるの? そんなわきゃないですね。上記コードでpに代入してる、確保した動的領域は明らかにその後使われないですね。なので、GC_mallocさんは賢いので将来使われないことがわかってる子は再利用するわけです。「heap: 10000100000」ってのは確保したのべの領域サイズになります。

(続く)

*1:Cで言うとmallocとかで取ってきた領域

*2:ここで使ってるのはBoehm GC

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

April 17(Thu), 2008

[][][] 画面サイズとDPIを得る方法(WindowsかX環境下で)

世の中にはWindowsか、Xのある環境しか無いと思っている恐しいコード。切り分けするためのマクロがわからんかった。

#ifdef WIN32
#include <windows.h>
#else
#include <Xlib.h>
#endif
typedef struct ScreenInfo ScreenInfo;
struct ScreenInfo{
  int width_px, height_px;
  int width_mm, height_mm;
  int dpi_width, dpi_height;
};
ScreenInfo *getScreenInfo(ScreenInfo *info)
{
#ifdef WIN32
  HDC dc;
  dc = GetDC(GetDesktopWindow());
  if(dc == NULL) return NULL;
  info->width_px = GetDeviceCaps(dc, HORZRES);
  info->height_px = GetDeviceCaps(dc, VERTRES);
  info->width_mm = GetDeviceCaps(dc, HORZSIZE);
  info->height_mm = GetDeviceCaps(dc, VERTSIZE);
  ReleaseDC(GetDesktopWindow(), dc);
#else
  Display *display = XOpenDisplay(NULL);
  if(display == NULL) return NULL;
  info->width_px = DisplayWidth(DEFAULT_DISPLAY, DefaultScreen(display));
  info->height_px = DisplayHeight(DEFAULT_DISPLAY, DefaultScreen(display));
  info->width_mm = DisplayWidthMM(DEFAULT_DISPLAY, DefaultScreen(display));
  info->height_mm = DisplayHeightMM(DEFAULT_DISPLAY, DefaultScreen(display));
  XCloseDisplay(display);
#endif
  info->dpi_width = (info->width_px*254 + info->width_mm*5) / info->width_mm*10;
  info->dpi_height = (info->height_px*254 + info->height_mm*5) / info->height_mm*10;
  return info;
}
トラックバック - http://d.hatena.ne.jp/hogelog/20080417

April 13(Sun), 2008

[] ゼミで使うレジュメ用itemizeスタイル

itemizeの幅とか詰めたかったんで、/usr/local/share/texmf/ptex/platex/base/jarticle.cls参考itemizeを再定義。

% itemize
\renewenvironment{itemize}
  {\ifnum \@itemdepth >\thr@@\@toodeep\else
   \advance\@itemdepth\@ne
   \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
   \expandafter
   \list{\csname \@itemitem\endcsname}{%
     \topsep0zh
     \itemindent0zw
     \leftmargin2zw
     \rightmargin0zw
     \labelsep.5zw
     \labelwidth1zw
     \itemsep0em
     \parsep0em
     \listparindent1zw
     \def\makelabel##1{\hss\llap{##1}}}%
   \fi}{\endlist}

%%\leftmargin 左のインデント
%%\rightmargin 右のインデント
%%\labelsep ラベルと説明の間
%%\labelwidth ラベルの幅
%%\itemsep 項目ごとの改行幅
%%\parsep 段落での改行幅
%%\listparindent 段落下げ
トラックバック - http://d.hatena.ne.jp/hogelog/20080413
最近のコメント
Connection: close