D言語の更新まとめ 2019年7月版（dmd 2.087.0）

# はじめに
D言語の公式コンパイラである dmd が更新され、最新バージョンである `2.087.0` が 2019/07/01 にリリースされました。

奇数月の１日にリリースされるサイクルは継続しており、今回は特にリリース前に目立った問題も見つからずスムーズにリリースされた印象です。

が、いざリリースノートから新機能を追いかけると結構あれこれ入っていましたので、目立ったところちゃんと紹介しておきたいと思います。
（力不足で全部は書けていないので、コメントや編集リクエスト、関連記事等お待ちしております！）

ChangeLog原文は下記リンクを参照してください。

https://dlang.org/changelog/2.087.0.html

# 変更点目次
## コンパイラ変更点

- `function`のエイリアスを宣言するための新しい構文が追加されました
- DdocにMarkdownを参考とした機能が追加されました
- クラス宣言に対する`scope`修飾が非推奨となりました
- `this`と`super`を型として利用する機能が廃止されました
- 非推奨だったいくつか無効な整数リテラルがエラーになるよう変更されました
- fix Issue 16002 : `is(sym == module)`と`is(sym == package)`を追加されました
- ローカルの`template`がローカルシンボルを受け取れるよう拡張されました
- Windows: `mingw`ベースのランタイムとプラットフォーム用importライブラリが明示的に選択できるようになりました
- 浮動小数点型の`NaN`は`.init`と同じ値を使うようになりました
- クラスアロケーターとデアロケーターが廃止されました
- アクセスチェックの非推奨期間が終了、廃止されました
- `static this`でグローバルなimmutable型のデータを初期化することは非推奨となりました
- 構造体ですべての引数がデフォルトパラメーターを持つコンストラクタはエラーになるようになりました
- テンプレートのalias引数が基本型への変換を考慮するようになりました
- 32ビットのLinuxでは、x87以上の環境でfloatとdoubleにXMMレジスタを使用するようになりました

## ランタイム変更点

- FreeBSDの`sys/ttycom.h`を`core.sys.posix.sys.ttycom`として提供するようになります
- GCは複数のスレッドでヒープをマークするようになりました（parallel marking）
- `clone(2)`および定数と`unshare(2)`を`core.sys.linux.sched`に追加します

## ライブラリ変更点

- ASCIIテーブルに制御文字のテーブルを追加しました
- Linuxでプロセッサ数を数えるために`sched_getaffinity`を使うようになりました
- オーバーロードを追加します
    - `std.algorithm.sorting.schwartzSort!(alias transform, SwapStrategy ss, R)`
- Phobosは `-preview=dip1000`でコンパイルされました

# 注目トピック
## コンパイラ変更点
### 新機能：DdocにMarkdownを参考とした機能が追加されました

原文：https://dlang.org/changelog/2.087.0.html#ddoc_markdown

コンパイラに `-preview=markdown` というフラグが追加され、Document Commentの中でMarkdown記法を取り入れることができるようになりました！

たとえば以下のソースでコメント中に表を入れたり、形式を明示したコードを埋め込めるようになります。

標準ライブラリのドキュメントは結構えげつないボリュームなので、こういった見出しやコード埋め込み、表が活かされるケースは多そうです。
わたしもがんばってコメント書いていきます。。。


```bash:コンパイルコマンド
dmd app.d -preview=markdown -D
```

```d:app.d
/**
 * # 表の埋め込み
 * 
 * | C1  | C2  |
 * |:----|:----|
 * | A   | B   |
 *
 * # コードの埋め込み
 * 
 * ```cpp
 * #include &lt;iostream&gt;
 * 
 * int main()
 * {
 *     std::cout &lt;&lt; "Hello iostream" &lt;&lt; std::endl;
 *     return 0;
 * }
 * ```
 *
 * # 既存の形式と共存
 * 
 * Example:
 * ---
 * module app;
 * ---
 */
struct Test { }
```

#### 補足
- 普通のMarkdown＋αとなるので、エスケープ等の注意が必要です
    - 特に既存のDocCommentで`<>`を使っている場合、MarkdownではエスケープしないとHTMLタグと判定されてレイアウトが崩れる場合があります
- コードの形式は何でも指定できますが、シンタックスハイライト機能はありません
    - 当該ノードには `class="code language-cpp"`という形式でクラスが付与されるため、 [highlight.js](https://highlightjs.org/) などを使えば容易に色が付けられます
    - ちなみにDだけは自動でハイライトされます
- ちなみに最小限のフラグしか付けないと、めっちゃでかいMarkdown書いても鬼速いです。
    - 体感ではバイナリとHTMLを吐いてるのにHTMLしか吐かない静的サイトジェネレーターより全然速いので、CSSやjsのバンドルが如何に重いかが分かります。

### 非推奨または廃止される機能

今回は全7件です。前情報があったものもありますが結構多いですかね…？

- クラス宣言に対する`scope`修飾が非推奨となりました
- `this`と`super`を型として利用する機能が廃止されました
- 非推奨だったいくつか無効な整数リテラルがエラーになるよう変更されました
- クラスアロケーターとデアロケーターが廃止されました
- アクセスチェックの非推奨期間が終了、廃止されました
- `static this`でグローバルなimmutable型のデータを初期化することは非推奨となりました
- 構造体ですべての引数がデフォルトパラメーターを持つコンストラクタはエラーになるようになりました

#### クラス宣言に対する`scope`修飾が非推奨となりました

クラス宣言時にscopeと付けることが非推奨になり、警告が出るようになります。

利用時に`scope`変数で受け取ることはまだ可能で、こちらは利用しても問題ありません。

```d:警告
scope class Test { }
// Deprecation: scope as a type constraint is deprecated.  Use scope at the usage site.
// 型修飾としてのscopeは非推奨です。利用するときにscopeを使ってください
```

```d:OK
class Test { }

void test()
{
    scope obj = new Test;
    // スコープを抜けるときにデストラクタが実行される
}
```


#### `this`と`super`を型として利用する機能が廃止されました

`this`と`super`は型として使えたんですね知らなかった…

これは1年前から警告が出ていたシリーズが廃止されたものになります。
それぞれ`typeof(this)`と`typeof(super)`で代用することができます。

```d:今後はエラー
class Test
{
    shared(this) other;
}
```

```d:対処
class Test
{
    shared(typeof(this)) other;
}
```

#### 非推奨だったいくつか無効な整数リテラルがエラーになるよう変更されました

これも1年前から警告だったシリーズです。
2進数や16進数の数字を省略すると`0`として振舞っていたものがエラーになります。

```d:エラー
auto a = 0b;  // Error: `0b` isn't a valid integer literal, use `0b0` instead
auto a = 0x;  // Error: `0x` isn't a valid integer literal, use `0x0` instead
```

#### クラスアロケーターとデアロケーターが廃止されました
1年以上前から非推奨扱いで滅多に使うことがない機能だと思いますが、今回からコンパイルエラーになります。

機能的には独自確保したメモリにインスタンスを割り当てるというものですが、`core.lifetime`モジュールの`emplace`関数を使うことで代替できます。

詳細：https://dlang.org/deprecate.html#Class%20allocators%20and%20deallocators


#### アクセスチェックの非推奨期間が終了、廃止されました

原文：https://dlang.org/changelog/2.087.0.html#remove_visibility

（ちょっと調べる気力がなかったので置いておきます…）

#### `static this`でグローバルなimmutable型のデータを初期化することは非推奨となりました
ほぼバグだったシリーズです。

`static this() { }`というのはモジュールに書く静的コンストラクタのことです。

種類として `static this() { }` と `shared static this() { }` がありますが、前者はスレッド毎に実行、後者はグローバルに1度だけ、という違いがあります。

今回問題になったのは前者で、スレッド毎にグローバル変数を初期化していたという問題です。
非推奨もやむなし、という感じですね。

#### 構造体ですべての引数がデフォルトパラメーターを持つコンストラクタはエラーになるようになりました

こちらは`2.070.0`で非推奨となっており、実に3年半越しでエラーになったものです。

具体的には以下のようなコードで、他と比べると結構書きやすい内容かもしれません。
非推奨になった経緯は確認できなかったのですが、デフォルトコンストラクタと衝突するのがあまり良くなかった感じでしょうか。

```d:サンプル
struct Oops
{
    this (int universe = 42) {}
}
```

## ランタイム変更点
### 改善：GCは複数のスレッドでヒープをマークするようになりました

原文：https://dlang.org/changelog/2.087.0.html#gc_parallel

みんな大好き高速化のお話です。この度GCの停止時間が短くなるparallel markingが実装されました！
（GCは状況によって適切な実装が色々変わりますし、種類も様々なので細かいお話は抜きにしておきます）

こちら既定で有効となるので、コンパイラを更新するだけで結構速くなるかもしれません。
ぜひ更新して計測チャレンジしてみてください！

なお既定で有効になるので、当然無効化したり設定変更も可能です。
GC周りの設定を変更する方法は大きく2つあります。

- プログラムの実行時に `"--DRT-gcopt=XXX"` という引数を指定する
    * プログラムに渡される引数からは除外されるので実行内容には影響はありません
- プログラム中に `extern(C) __gshared string[] rt_options = [ "gcopt=parallel:2" ];`という変数を宣言しておく
    * プログラムの性質から最適なパラメーターが分かっているときは事前に埋め込むことができます

なお、おすすめは実行時に色々変えられる引数指定の方です。Javaなんかと同じですね。計測が捗ります！

```bash:実行例
app "--DRT-gcopt=parallel:2"
```

なお、すべての設定項目を見るには以下のページを参照してください。（結構ある…これが沼…）

https://dlang.org/spec/garbage.html#gc_config


## ライブラリ変更点
### 改善：Phobos（標準ライブラリ）は `-preview=dip1000` でコンパイルされました

原文：https://dlang.org/changelog/2.087.0.html#phobos-dip1000

こちらもみんな大好きライフタイムに関する [dip1000](https://github.com/dlang/DIPs/blob/65dac43690047e02b575adaae8f7c45e53c575ae/DIPs/other/DIP1000.md) の話題です。

DIP1000というのは`Scoped Pointer`というタイトルのついたD言語の改善提案ですが、その実、Rustの「ライフタイム」に近い「Reachability（到達可能性）」という概念を提唱したものとなっています。

細かい説明はドキュメントに譲ることとしますが、こちらは各種変数のスコープを代数的に計算可能な形で定義することで「無効な参照を発生させない」というのが主要なテーマとなっています。
（Algebra of Lifetimesといいます）

GCがあるゆえに普段は何も考えなくてもうまくプログラムが書けるわけですが、ひとたびスタック変数のアドレスを取るようなロジックを書き始めると「無効な参照」というのが結構発生するようになります。これをうまくチェックして予防していこう、というのがDIP1000の思想と目的となっています。

この機能はフラグをつけると `@safe` や `scope` で修飾している箇所でチェックが有効になるので、safeのほうは結構引っかかる方がいるかもしれません。1度フラグをつけてコンパイルしてみるとたまの破壊的変更が楽しめると思います！

フラグをつけるときは以下のようになります。

```bash:コンパイルフラグ
dmd app.d -preview=dip1000
```

# まとめ
非推奨なコードや廃止になった機能が複数ある一方、GC高速化などの目立った強化も引き続き行われています。

2ヶ月に1度の定期リリースなので相変わらず結構な頻度ではあるわけですが、それでも毎度目玉になる強化が尽きないのはすごいですね。

最近はメルセデス・ベンツやAudi、その他D言語を使える開発者を募集している企業が目立って採用活動をするようになってきていますが、そちらで使われるサーバー系プログラムやツールで有効そうな強化が多いのかなと思います。
やはりお金はすごかった…！

今後も先進的な機能や改善を期待したいと思います！