D言語 Language Update 2015


D言語 Advent Calendar 2015の最初の記事です．今回も1年の更新を振り返って行きます．今年はコンパイラのD言語実装への置き換えなど，大きなマイルストーンが消化された年でした．

今年リリースされたdmdは2.067，2.068，2.069の3つです．それらの変更やコミュニティ関係に関してまとめます．

# 公式プロジェクト

## 言語仕様

### pragma(inline)の追加

[inline](http://dlang.org/spec/pragma.html#inline)

プログラマが関数のinlineを制御出来ます．コンパイラに任せる`pragma(inline)`，inline化を抑制する`pragma(inline, false)`，inline化を強制する`pragma(inline, true)`(できない時はコンパイルエラー)，など．

`-inline`がない時でも`pragma(inline, true)`はinline化するべきですが，その部分はまだ未実装となっています．

### ヒープに確保されたstructのデストラクタが実行されるように

題名の通りで，今までnewしたstructがGCによって回収される時にデストラクタが呼ばれてなかったんですが，呼ばれるようになりました．まぁヒープに取らないといけないようなやつは皆classを使っていたんですが，PODであるstructも呼ばれるようになったので，利用の幅が広がった感じです．

### Invalidなcastの判定がフロントエンドでされるように

今までcastの判定に関してはバックエンド側のコード生成の所でやられてたんですが，フロントエンドで行われるようになりました．それによって非互換な挙動があります．以下がchangelogの例．まぁこの手のコードはあんまり出てこないとは思いますが，気になる方はチェックしましょう，

```
pragma(msg, is(typeof({ void* x; auto y = cast(void delegate())x; })));
// Since 2.067: it prints 'true'
//  From 2.068: it prints 'false'

void test() { void* x; auto y = cast(void delegate())x; }
// Since 2.067: it had reported internal compiler error "Error: e2ir: cannot cast ..."
//  From 2.068: it reports proper frontend error.
```

### asmでの属性サポート

今まで`asm`を使っていると関数そのものはpureな実装でもpureとかに出来なかったんですが，`asm`にこれらの属性をつけてコンパイラに知らせることにより，`asm`を使っている関数でも適切に属性をつけられるようになりました．なので無理して`@trusted`にするとかの必要性がなくなりました．

```dlang
asm pure nothrow @nogc @trusted
{
    // コンパイラは属性のチェックをしないので，実装者が保証する必要がある
}
```

以上の他，[Sealed references](http://wiki.dlang.org/DIP25)の機能が実装されたり，`with`がテンポラリオブジェクトの寿命を無視してしまう問題が解決されたりと，より安全になりました．
またtemplate関係でも，属性のinferがauto returnの時に行われるようになったり，deductionが賢くなったりと，よりコードが書きやすくなりました．

## dmd

### フロントエンドのD言語化

[dmdのフロントエンドのD言語化とD foundation](http://qiita.com/repeatedly/items/a7e3efacaaa0b6c674f4)の記事で言及しましたが，フロントエンドがC++からD言語になりました．目に見えて遅くなってる感じはしないので，最初の置き換えにしては十分だと思ってます．D言語が高速化されるとコンパイルも高速化されるということで，今後より開発は加速すると思いますし，パッチも投げやすくなったと思います．

gdc/ldcもフロントエンドはdmdのを使っているので，様々な環境でメリットが享受できると思います．

### Objective-Cとのインテグレーション

[Interfacing to Objective-C](http://dlang.org/spec/objc_interface.html)

個人的に使う予定がないので全然追ってません！興味のある方は上のページを読みましょう．

### -unittestが指定されなかった時の高速化

今までコンパイラは律儀にunittestブロックもパースして構文チェックなど色々としてたんですが，`-unittest`がついてない時はその辺をスキップするようになりました．なので，プロダクション向けのビルドなどでコンパイル速度が向上しました

### -profile=gcフラグ

`-profile=gc`をつけてコンパイルすると，GCによるアロケーションに関して，アプリケーション終了時にログで出してくれるようになりました．思ったよりメモリアロケーションに時間を使ってるな，って思ったらこれをつけて走らせてみましょう．以下のようなログがはかれます．

```
bytes allocated, type, function, file:line
     171	immutable(char)[] example.concat example.d:4
      24	closure D main example.d:18
      16	example.Klass D main example.d:20
```

## druntime

### GCの高速化

ヒープ伸長のアルゴリズムや，ヒープの探索を効率化することで，GC全体のパフォーマンスが改善されました．以下はdruntimeにある[ベンチマークスクリプト群](https://github.com/D-Programming-Language/druntime/tree/master/benchmark/gcbench)の結果です．GCはバージョンを追う毎にコツコツとパフォーマンスが改善されている感じです．

![GC Benchmark](http://dlang.org/images/faster-gc-1.svg)

### 組み込みAAの高速化

実装が，今までのSeparate chainingから，Quadratic probingを使ったOpen Addressingに変更されました．Martinのベンチマークによると，基本的にはパフォーマンスが向上したようです．メモリ傾向とかに違いは出てくるので，気になる方は自分のプロジェクトで上のGCともどもチェックしましょう．

![AA Benchmark](https://cloud.githubusercontent.com/assets/288976/7243965/e0fc6e20-e7d4-11e4-9294-f8ac1e2cd3af.png)

### volatileStore / volatileLoad

core.bitopに追加された命令です．同一スレッドでコンパイラによる削除やre-orderを抑制するために使います．以下はchangelogに載っている例です．

```d
void example(uint* address, uint value)
{
    import core.bitop;

    // store value
    volatileStore(address, value);

    // wait until value takes affect
    while (volatileLoad(address) != value)
    { }
}
```

将来的には`volatile`は予約語から削除され，core.volatileで置き換える予定です．


## phobos

### std.experimental

いずれphobosに入るんだけど，レビュー段階では洗い出し切れないユースケースやAPIの問題について，experimentalパッケージとしてユーザに提供して使ってもらうことになりました．

現在[logger](http://dlang.org/phobos/std_experimental_logger.html)と[allocator](http://dlang.org/phobos/std_experimental_allocator.html)の二つが入ってます．allocatorについては別の日のAdvent Calendarで書きます．loggerについても書くかも．

### さらなる関数群のRange化

PhobosはRangeを中心に構築されており，その対応がされていなかったものも更に対応されました．引数としてRangeを受け取るようになったのが増えたのはもちろん，以下のようにRangeを返すことでメモリアロケーションを回避する実装も増えたりしました．

```d
setExtension("foo.jpg", ".png"); // 新しく生成された文字列を返す
withExtension("foo.jpg", ".png"); // chain Rangeでラップされた結果を返す．chainをイテレートするだけなので，メモリアロケーションは起きない
```

### curlの動的ローディング化

いままではstd.net.curlを使うためには，libcurlを明示的にlinkしないと行けなかったんですが，シンボル周りのバージョン問題や，dmd本体のリンクオーダー周りでいくつかトラブルがあったので(これ自体は別の方法で修正済み)，それらを回避するために実行時に動的にロードするようになりました．

Windowsでの注意事項とかあるので，Windowsでcurlを使う人はwikiの[Curl on Windows](http://wiki.dlang.org/Curl_on_Windows)のページを参照してみてください．

### 追加された便利ユーティリティ

- std.range.enumerate

Rubyでの`each_with_index`です．Rangeにインデックスを付与してくれます．引数はインデックスの初期値です．

```
foreach (lineNum, line; stdin.byLine().enumerate(1))
    stdout.writefln("line #%s: %s", lineNum, line);
```

- std.exception.handle

Rangeを処理する過程でエラーが起きた時に特別な処理を挟むためのRangeです．以下はchangelogの例ですが，invalidな文字があった時に文字を置き換える，と行ったことが出来ます.

```
auto str = "hello\xFFworld"; // 0xFFはUTF-8としてはinvalid
auto handled = str.handle!(UTFException, RangePrimitive.access, (e, r) => ' '); // UTFExceptionが起きたら空白で置き換える
assert(handled.equal("hello world"));
```

- std.algorithm.mutation.moveEmpalce

moveのEmplace版．moveは安全にmoveするために対象を`destory`するんですが，未初期化なオブジェクトを`destroy`するのは危険なため，初期化しないと行けないという二度手間がありました．それらを回避するために`destroy`しない版が追加されたという感じです．パフォーマンスも向上します．

# コミュニティやその他のプロジェクト

## D Foundationの設立

こちらもすでに言及しましたが，AndreiがD言語を加速させるためにFacebookをやめてD Foundationを立ち上げました．Visionをたてたり，今まで結構属人的だったものを，まとめてコミュニティを活性化させていこうという感じです．

## D言語の本

- [Learning D](https://www.packtpub.com/application-development/learning-d)

11月に出ました．Cとかの言語を知っている人向けに書かれていて，入門的な内容から始まって，CTFEとかRangeとか，プロダクションでよく使われる機能まで説明しているようです．

- [D Web Development](https://www.packtpub.com/web-development/d-web-development)

2015年に出ると思ったら2016年1月になってました．プレオーダー状態ですが，vibe.dを使ってのWebアプリケーション開発について書かれています．

## [DConf 2015](http://dconf.org/2015/)

D言語でストレージシステム書いてる人がいたり，Ciscoの中のネットワークソフトウェアのツールで使っている人がいたり，D言語使ってる人増えてるなーという感じですね．スライドやyoutubeに動画があがったりしているので，気になるトークは見てみましょう．

[DConf 2016](http://dconf.org/2016/index.html)もあります．

## vibe.d

相変わらず開発は活発です．最近libhttp2やBotanなどのパッケージが増えていて，それらを使ってのHTTP2サポートも進んでいるようです．もうD言語でのデファクトになってます．

## DUBパッケージ

elasticsearchやGELなどのライブラリとか，プロダクションで使われてるようなライブラリが増えてます．見てると非同期IO系のモジュールがちょくちょく出ているので，そろそろvibe.dの足回りとなるデファクトが決まって欲しいところです．libasyncが今のところ有力か．

# まとめ

dmd/druntime/phobosに関しては全部を列挙しているわけではないので，気になる方はchangelogを漁ってください．D Foundationが出来てAndreiがD言語に注力するようになったので，2016年は今まで以上に加速するんじゃないかと思います．
パッケージも色々と増えてるし，プロダクションでの利用も増えてる感じなので，今後コミュニティがもっと活発化するといいなぁと思いつつ，俺もちょくちょく便利ライブラリを体裁整えて公開しないとなぁと思っているところです．