Crash Dartやります

http://partake.in/events/f986e926-1dbf-4c1f-aca0-d454d3305e49

日付は10月22日(土曜日)
会場はアリエル・ネットワーク様です

簡単に言えば、新しい言語とその処理系を遊び倒しましょうということで、しかし遊び倒すといってもピンキリですから、crashさせよう!という一応の目的を設定したものです。

プログラミングの魔導書Vol.2 最遅レビュー

今年も最遅レビュー達成なるか!?

まず何をもって最遅レビューが決まるかというと当然
http://longgate.co.jp/books/grimoire-vol2.html
の「書籍版予約締め切り」を基準にするものです。

実は本日、10月4日(火)がまさにその予約締め切りなのです。

受注生産の形態をとっているため、書籍版に関しては予約でのご注文のみとなりますのでご注意ください。

PDF版は予約期間が過ぎた後でもご購入いただけます。

予約期間は2011/10/04(火)までです。
http://longgate.co.jp/books/grimoire-vol2.html の お知らせ より

ここより後は、(他の人と間違いなく被るしぼくが書いても意味が無いC++の部分は避けつつの)章毎の低レベルレビュー(皆様大変申し訳ありません)で、真剣に時間の無駄ですから、特に書籍版が購入したい方は先に予約を済ませてしまいましょう。

「Dave Abrahamsへのインタビュー」

皆さんを混乱させるDSELとEDSLの違い(というか同じさ)について書かれた,ぼくにとってはじめての文章でした。

それと,C++と異なる文脈で既に話題には成りましたが
http://bartoszmilewski.wordpress.com/2011/07/11/monads-in-c/
これを読んでみましょう皆さん

「風とF#とメビウスの輪

F#の機能的な話も書いています.
本ブログを何故か読んでしまう皆さんは,計算を扱うのは良いけど,計算する(実行したりする)して黒い画面を値で白くしたりするのはどうでも良い,という考えだと思うのですが,そう言った人間向けにも楽しいものです.

特に,@...@を用いた型情報付きparse treeの取得と,builderの部分を読むと,実行しない派の人にも面白い筈です.

寧ろ,OCaml使ってますし一々F#なんて…という方々や能動的に摂取しようと思わなかった方々が,受動的に摂取させられると良いのではないでしょうか.

ぼくは正に後者です.

D言語の設計と進化とか」

type qualifier transitivityが面白かったです.
良い加減D言語パーフェクトガイド

D言語パーフェクトガイド―Windows Linux FreeBSD対応

D言語パーフェクトガイド―Windows Linux FreeBSD対応

から知識が更新されない皆さんは、一度読んでみると良いのではないでしょうか?

しかしどう考えてもD言語はマイナーではもはや無くなってると思うのですけどね…。
むしろぼくの中では既に企業で使われてる言語って感じなのですが。

「The Door To Dependent Types」

もう2年程前の話になりますが,(ネタ的な意味で)C++で定理の証明をしよう! という話が,twitter上の数人の間で,わずかな期間盛り上がった(とぼくは記憶しているのですが)ことがあります.

http://www.kmonos.net/wlog/102.html#_0103091022

上記は,いなばさんによる大変分かり易い「C++で定理を証明っぽいことをする」ことについてのintroです.

内容としては

  • C++では一応「値に依存した型」は書けない
  • 一方私達が普通証明を書くときというのは「値に依存した型」で考えられると割と自然になる
  • アレじゃあ困った!?

なので「型に依存した型」ベースで(ちょっと強引に)考えたぜ!! とも言えると思います.

一方,本記事はそうじゃなくって,シンプルに「値に依存した型」が使えると良いじゃん,という視点を説明してくれています.

特に,「【証明】という正直な話そんなことしても給料には結びつかない,従ってどうでも良い.」
という皆様でもおもしろおもしろい感じに読み進めることだと思います.
何せ普通にプログラムを書く時の視点を中心に紹介してくれていますし、証明は殆ど紹介せざるを得ない1つのapplicationみたいなものです.

プログラミング言語Scalaの歴史とこれから」

タイムライン上で度々見る,type-safeとは異なるTypesafeの説明が,そもそも調べる気にもならなかった皆様に齎されます!!

ぼくが面白かったのは,Scala Daysのレポートでした.
今までどのように行われているか知りませんでしたし,何よりScala Days 2012への参加を今から考えている方の後押しになると思います.

Haskell 2010/2011とHaskellのこれから」

Haskell2010における新機能と2011で入るだろう機能を「日本語で」「実例を用いて」説明した,非常に素晴らしい文書です.

「証明支援系Coqの紹介」

Curry-Howard対応を紹介しつつ,Coqによる証明の入門が行われています.
twitterのタイムラインでCoqという語を見て気になってググるけど,出てくるものといえば簡単なところで細事に括り過ぎてつまんない,そもそも興味は無いから入り口のあたりをざっくり捉えたいんだけど…」という方に特にオススメかもしれません.
そのような人が読んだ方が「興味を持ち易く成る」気がします.

「Boostを使い倒してTwitterクライアントを作る」

C++で…,というよりも,Boostライブラリを用いて非同期ネットワークI/Oを行うtwitterクライアントの実装を行います.

非同期処理においては,オブジェクトのlifetimeが(ポインタを用いた処理を行う際に)問題となることは一般的な話ですが,これに対しC++でどうするべきか??
という良くあるパターンについて,どう解決するかの考え方も述べられています.

そしてtwitterは,API(周辺)を殴るとJSONを吐き出すので,そのJSONをパーズする為にBoost.Spiritを用いています.
だいたい,これ以前に,HTTPリクエストのお話もあるのですが.

おわりに

今から書きます。

エラーハンドリング勉強会で発表してきました

発表資料はココで : http://ranha.kerox.info/start_exception.pdf

全体構成は3部です。
しかし、そのうち1つは、Exceptional C++とか(何か聞く所に依るともっと適切な本があるらしいですが)読むと例外安全とか例外中立を一々気にする姿勢について分かるし良いのではないでしょうか、ということの紹介みたいなものなので、実質2つです。

Haskellのパートは,StackのPushを何も気にせず代数的データ構造で表現すると

data Stack a = Empty | Push a (Stack a)

となって、このPushの型が

-- Push :: a -> Stack a -> Stack a

Stack aというEmptyであるかもしれない型を返すのが良くない。
更に、PopってPushの逆操作だからーということで

pop :: Stack a -> (a , Stack a)

みたいな型にすると、実装はEmptyの場合に例外を投げるか、返値の型をMaybe (Stack a)として失敗を表す値とするしか。
でもそうすると残りの部分全体にMaybeというか、計算の失敗が入って来て邪魔くさくなる。

いや、そもそも、なんでこんな不適切な型(Stack a)をPushが返す必要があるのか、GADTsを用いてEmptyではないStackを返すことをちゃんと書いてあげましょうみたいな話でした。

Cのパートは,簡単に言えばまぁヒープが死にましたみたいな、mallocがNULLを返すケース、これは何とか扱えそう。

あと、MaybeをCで実装するの面倒臭いですし、生みだされたものがマトモに使えるのか分からないので、別のアプローチの紹介をしました。

そもそもMaybeを使うのは、「関数の返す値で場合分け」をしたいからで、値を返さなければMaybeとか使う必要ないわけです。
ということで、失敗するかもしれない関数には「そこまでの計算が成功した場合の続き」と「そこまでの計算で失敗した場合の続き」を準備して(いわゆる継続です)あげればさしあたり上手くいきそうですよねーという。

ただ例外安全みたいなものを達成したい場合、シグナルが飛んでくる時(特に今回の場合は一段面倒臭いスタックオーバーフロー)にどう後片付けをして死ぬべきなのかという問題提起をしました。

ヒープアロケーションの成功失敗を気にするなら、まぁアラユル関数呼び出しでスタックが溢れる可能性があるわけでさてどうするべきなのでしょうか…。

更にCでなくC++の話をするとシグナル飛んで来て元に戻してあげないとデストラクタ呼び出されないわけで、更にどうするんでしょうかという感じです。

どうすれば良いのでしょうか…。

Apple ldのalias_listオプションの挙動が良く分かりません その2

前回に引き続き。

% gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% ld -v
@(#)PROGRAM:ld  PROJECT:ld64-97.17
llvm version 2.9svn, from Apple Clang 1.7 (build 77)

次の4ファイルを準備してそれに対してalias_listオプションを使ってみます。

/* h.h */
struct S {
    int *i;
};
/* main.c */
#include "h.h"
#include <stdio.h>

extern int i;
struct S bar = { &i };

extern void check(struct S*);

int main()
{
    printf("*bar.i = %d\n",*bar.i);

    check(&bar);
    return 0;
}
/* lib.c */
#include "h.h"
#include <stdio.h>
#include <assert.h>

extern struct S hogefuga;

void check(struct S *p)
{
    printf("*(p->i) = %d\n",*(p->i));
    printf("*hogefuga.i = %d\n",*hogefuga.i);

    assert(p == &hogefuga);
}
/* define_i.c */
int i = 42;

さて、今回は、lib.cの"hogefuga"シンボルを、main.cの"bar"シンボルへとリネームするべく、alias_listオプションに渡すファイルを次のように書きます。

% cat alias
_bar _hogefuga

これを使って2バージョンのコンパイルをします。

% gcc -Wall -c main.c lib.c
% gcc -Wall -c define_i.c
% gcc -shared define_i.o -o define_i.so
% gcc -o static main.o lib.o define_i.o -Wl,-alias_list,alias
% gcc -o shared main.o lib.o define_i.so -Wl,-alias_list,alias
% nm static
0000000100000ee2 s  stub helpers
0000000100001050 D _NXArgc
0000000100001058 D _NXArgv
                 U ___assert_rtn
0000000100000ea7 s ___func__.2336
0000000100001068 D ___progname
0000000100000000 A __mh_execute_header
0000000100001070 D _bar
0000000100000e0d T _check
0000000100001060 D _environ
                 U _exit
0000000100001070 D _hogefuga
0000000100001078 D _i
0000000100000ddc T _main
                 U _printf
0000000100001000 s _pvars
                 U dyld_stub_binder
0000000100000da0 T start

これは上手くいきそうですね!!

% nm shared
0000000100000ee2 s  stub helpers
0000000100001058 D _NXArgc
0000000100001060 D _NXArgv
                 U ___assert_rtn
0000000100000ea7 s ___func__.2336
0000000100001070 D ___progname
0000000100000000 A __mh_execute_header
0000000100001050 D _bar <-
0000000100000e0d T _check
0000000100001068 D _environ
                 U _exit
0000000100001078 D _hogefuga <-
                 U _i
0000000100000ddc T _main
                 U _printf
0000000100001000 s _pvars
                 U dyld_stub_binder
0000000100000da0 T start

!? 2つのシンボルのアドレスが異なっています…。

% ./static
*bar.i = 42
*(p->i) = 42
*hogefuga.i = 42
% ./shared
*bar.i = 42
*(p->i) = 42
zsh: segmentation fault  ./shared

やはりsharedの方は失敗しました。

ちなみに、リンカスクリプトが渡せるldでは次のように書き

hogefuga = bar;
EXTERN(bar);

EXTERNが必要かどうかは分かりませんが…、同様にコンパイルしてあげるとどちらも正しく動きます。

Apple ldのalias_listオプションの挙動が良く分かりません

本エントリで何がしたいか

Appleのldは、リンカスクリプトを受け取る事が出来ません。(多分…)
ところで、リンカスクリプト中のシンボル同士の代入を用い、シンボルのrenamingをしたいといった事は稀に良くあることだと思うのですが、じゃあリンカスクリプト使えない時にそれをどうしましょう…という話を書いています。

Apple ldにはaliasとalias_listという「それっぽい」オプションがあるのでこれを使えば動くのではないかなーと思うのですが、どうも上手く動かないように思われるケースがあるので以下に記します。

% gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

の元で以下コンパイルしています。

h.h

struct In {
    int i;
};

struct S {
    struct In in;
    int d;
};

lib1.c

#include "h.h"
#include <stdio.h>
#include <assert.h>

extern struct S lib1_s;
extern struct In lib1_in;

void f(int v)
{
    puts("-- f --");
    printf("&lib1_s = %p\n",&lib1_s);
    printf("&lib1_in = %p\n",&lib1_in);

    printf("lib1_s.in.i = %d\n",lib1_s.in.i);
    printf("lib1_in.i = %d\n",lib1_in.i);
    printf("lib1_s.d = %d\n",lib1_s.d);

    assert(v == lib1_s.d);
}

main.c

#include "h.h"
#include <stdio.h>

struct S main_s;
struct In main_in;

extern void f(int);

int main()
{
    main_in.i = 42;
    main_s.in = main_in;
    main_s.d = 84;

    printf("&main_s = %p\n",&main_s);
    printf("&main_in = %p\n",&main_in);

    f(main_s.d);

    return 0;
}

alias_listオプションを使いつつ、実行可能ファイルを作ります

いや、そもそもalias_listオプションて何?という話ですね。

man ld(あと、http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/ld.1.html) から抜粋すると

     -alias symbol_name alternate_symbol_name
                 Create an alias named alternate_symbol_name for the symbol symbol_name.  By default the alias symbol has global visibility.
                 This option was previous the -idef:indir option.

     -alias_list filename
                 The specified filename contains a list of aliases. The symbol name and its alias are on one line, separated by whitespace.
                 Lines starting with # are ignored.

今回は、lib1.cのシンボル、lib1_sをmain1_sへ、lib1_inをmain1_inへ書き換えてみよう(特に意味はありませんが)。少なくともassertで死ぬ事はないでしょう。という考えです。

次のようなファイルを作り、alias_listと共にgccに渡します。

#alias
_main_s _lib1_s
_main_in _lib1_in
% gcc -Wall -c -g -O0 main.c lib1.c
% gcc main.o lib1.o -Wl,-alias_list,alias


% ./a.out 
&main_s = 0x10000107c
&main_in = 0x100001078
-- f --
&lib1_s = 0x100001078
&lib1_in = 0x100001078
lib1_s.in.i = 42
lib1_in.i = 42
lib1_s.d = 42
Assertion failed: (v == lib1_s.d), function f, file lib1.c, line 18.
zsh: abort      ./a.out

ギョエピー!!!!

Linuxリンカスクリプトを使ってやってみる

% gcc --version
gcc 4.4.3
% ld --version
GNU ld 2.20.1-system.20100303

次のようなリンカスクリプトを準備

lib1_s = main_s;
EXTERN(main_s);

lib1_in = main_in;
EXTERN(main_in);

EXTERNが本当にこの例で必要かどうかは分かりませんが…。
さて、今度はldがリンカスクリプトを受け取れるのでこれを使って生成してあげると

% gcc -Wall -c -g -O0 main.c lib1.c
% gcc main.o lib1.o linker.script

% ./a.out

&main_s = 0x804a024
&main_in = 0x804a02c
-- f --
&lib1_s = 0x804a024
&lib1_s.in = 0x804a024
&lib1_in = 0x804a02c
lib1_s.in.i = 42
lib1_in.i = 42
lib1_s.d = 84

とこっちでは上手く動いている事が分かります。

C言語オンリーイベントを目論んでいます

http://partake.in/events/bc4eb051-da12-465c-84d8-3ab93a4390de


スタートC language面白論文紹介&読み会です。

タイトル通りに、C言語オンリーです。

今の所日程としては、9月はICFPはじめとして色々ありますので、10月の1日にしておきました。

7,8時間ぐらいはやりたいかなーと思っています。

それでまぁぼくはこういうのやる時は、参加者皆が発表するっていうのを考えているので10人全員発表するとなると、1人(ツッコミや議論を含んで)45分だと、45 * 10 = 7.5時間で丁度良いかなぁみたいな。

ネタ被りは出来るだけ避けたいので、発表したい方はコメントを残してもらえればそれをreserveということにしたいと思います。