はじめに
D言語の公式コンパイラである dmd が更新され、最新バージョンである 2.087.0
が 2019/07/01 にリリースされました。
奇数月の1日にリリースされるサイクルは継続しており、今回は特にリリース前に目立った問題も見つからずスムーズにリリースされた印象です。
が、いざリリースノートから新機能を追いかけると結構あれこれ入っていましたので、目立ったところちゃんと紹介しておきたいと思います。
(力不足で全部は書けていないので、コメントや編集リクエスト、関連記事等お待ちしております!)
ChangeLog原文は下記リンクを参照してください。
変更点目次
コンパイラ変更点
-
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記法を取り入れることができるようになりました!
たとえば以下のソースでコメント中に表を入れたり、形式を明示したコードを埋め込めるようになります。
標準ライブラリのドキュメントは結構えげつないボリュームなので、こういった見出しやコード埋め込み、表が活かされるケースは多そうです。
わたしもがんばってコメント書いていきます。。。
dmd app.d -preview=markdown -D
/**
* # 表の埋め込み
*
* | C1 | C2 |
* |:----|:----|
* | A | B |
*
* # コードの埋め込み
*
* ```cpp
* #include <iostream>
*
* int main()
* {
* std::cout << "Hello iostream" << std::endl;
* return 0;
* }
* ```
*
* # 既存の形式と共存
*
* Example:
* ---
* module app;
* ---
*/
struct Test { }
補足
- 普通のMarkdown+αとなるので、エスケープ等の注意が必要です
- 特に既存のDocCommentで
<>
を使っている場合、MarkdownではエスケープしないとHTMLタグと判定されてレイアウトが崩れる場合があります
- 特に既存のDocCommentで
- コードの形式は何でも指定できますが、シンタックスハイライト機能はありません
- 当該ノードには
class="code language-cpp"
という形式でクラスが付与されるため、 highlight.js などを使えば容易に色が付けられます - ちなみにDだけは自動でハイライトされます
- 当該ノードには
- ちなみに最小限のフラグしか付けないと、めっちゃでかいMarkdown書いても鬼速いです。
- 体感ではバイナリとHTMLを吐いてるのにHTMLしか吐かない静的サイトジェネレーターより全然速いので、CSSやjsのバンドルが如何に重いかが分かります。
非推奨または廃止される機能
今回は全7件です。前情報があったものもありますが結構多いですかね…?
- クラス宣言に対する
scope
修飾が非推奨となりました -
this
とsuper
を型として利用する機能が廃止されました - 非推奨だったいくつか無効な整数リテラルがエラーになるよう変更されました
- クラスアロケーターとデアロケーターが廃止されました
- アクセスチェックの非推奨期間が終了、廃止されました
-
static this
でグローバルなimmutable型のデータを初期化することは非推奨となりました - 構造体ですべての引数がデフォルトパラメーターを持つコンストラクタはエラーになるようになりました
クラス宣言に対するscope
修飾が非推奨となりました
クラス宣言時にscopeと付けることが非推奨になり、警告が出るようになります。
利用時にscope
変数で受け取ることはまだ可能で、こちらは利用しても問題ありません。
scope class Test { }
// Deprecation: scope as a type constraint is deprecated. Use scope at the usage site.
// 型修飾としてのscopeは非推奨です。利用するときにscopeを使ってください
class Test { }
void test()
{
scope obj = new Test;
// スコープを抜けるときにデストラクタが実行される
}
this
とsuper
を型として利用する機能が廃止されました
this
とsuper
は型として使えたんですね知らなかった…
これは1年前から警告が出ていたシリーズが廃止されたものになります。
それぞれtypeof(this)
とtypeof(super)
で代用することができます。
class Test
{
shared(this) other;
}
class Test
{
shared(typeof(this)) other;
}
非推奨だったいくつか無効な整数リテラルがエラーになるよう変更されました
これも1年前から警告だったシリーズです。
2進数や16進数の数字を省略すると0
として振舞っていたものがエラーになります。
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年半越しでエラーになったものです。
具体的には以下のようなコードで、他と比べると結構書きやすい内容かもしれません。
非推奨になった経緯は確認できなかったのですが、デフォルトコンストラクタと衝突するのがあまり良くなかった感じでしょうか。
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なんかと同じですね。計測が捗ります!
app "--DRT-gcopt=parallel:2"
なお、すべての設定項目を見るには以下のページを参照してください。(結構ある…これが沼…)
ライブラリ変更点
改善:Phobos(標準ライブラリ)は -preview=dip1000
でコンパイルされました
原文:https://dlang.org/changelog/2.087.0.html#phobos-dip1000
こちらもみんな大好きライフタイムに関する dip1000 の話題です。
DIP1000というのはScoped Pointer
というタイトルのついたD言語の改善提案ですが、その実、Rustの「ライフタイム」に近い「Reachability(到達可能性)」という概念を提唱したものとなっています。
細かい説明はドキュメントに譲ることとしますが、こちらは各種変数のスコープを代数的に計算可能な形で定義することで「無効な参照を発生させない」というのが主要なテーマとなっています。
(Algebra of Lifetimesといいます)
GCがあるゆえに普段は何も考えなくてもうまくプログラムが書けるわけですが、ひとたびスタック変数のアドレスを取るようなロジックを書き始めると「無効な参照」というのが結構発生するようになります。これをうまくチェックして予防していこう、というのがDIP1000の思想と目的となっています。
この機能はフラグをつけると @safe
や scope
で修飾している箇所でチェックが有効になるので、safeのほうは結構引っかかる方がいるかもしれません。1度フラグをつけてコンパイルしてみるとたまの破壊的変更が楽しめると思います!
フラグをつけるときは以下のようになります。
dmd app.d -preview=dip1000
まとめ
非推奨なコードや廃止になった機能が複数ある一方、GC高速化などの目立った強化も引き続き行われています。
2ヶ月に1度の定期リリースなので相変わらず結構な頻度ではあるわけですが、それでも毎度目玉になる強化が尽きないのはすごいですね。
最近はメルセデス・ベンツやAudi、その他D言語を使える開発者を募集している企業が目立って採用活動をするようになってきていますが、そちらで使われるサーバー系プログラムやツールで有効そうな強化が多いのかなと思います。
やはりお金はすごかった…!
今後も先進的な機能や改善を期待したいと思います!