Slide 1

Slide 1 text

D言語に入門した話 チャパティ

Slide 2

Slide 2 text

自己紹介 チャパティ (Twitter:@_shouth_kit) 情報工学課程4回 プログラムを書くのが好き ちゃぱえもんと呼ばれることもある

Slide 3

Slide 3 text

D言語って 知ってますか?

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

D言語の簡単な歴史 - 1999年に開発開始 - 2001年に最初のバージョンがリリース - 2007年にバージョン1.0に到達 紆余曲折を得て現在はD1は廃止され 現行のバージョンはD2

Slide 7

Slide 7 text

プログラム例: Hello world import std.stdio; int main() { writeln("Hello world!"); }

Slide 8

Slide 8 text

プログラム例: 基本的な制御構造 import std.stdio; int main() { for (int i = 1; i <= 100; i++) { if (i % 15 == 0) { writeln("FizzBuzz"); } else if (i % 3 == 0) { writeln("Fizz"); } else if (i % 5 == 0) { writeln("Buzz"); } else { writeln(i); } } }

Slide 9

Slide 9 text

ね,簡単でしょう?

Slide 10

Slide 10 text

メタプログラミング にっょぃ struct Vector(size_t D, T = double) if (__traits(isFloating, T)) { T[D] num; alias num this; T dot(const Vector rhs) { T res = 0; static foreach (i; iota(D)) res += num[i] * rhs.num[i]; return res; } static if (D == 3) { Vector cross(const Vector rhs) { return Vector([ num[0] * rhs.num[1] - num[1] * rhs.num[0], num[1] * rhs.num[2] - num[2] * rhs.num[1], num[2] * rhs.num[0] - num[0] * rhs.num[2] ]); } } } void main() { auto v0 = Vector!3([ 1, 2, 3 ]); auto v1 = Vector!3([ 4, 5, 6 ]); writeln(v0.cross(v1)); writeln(v0.dot(v1)); } メタプログラミング にっょぃ ↓こんな感じで呼べる

Slide 11

Slide 11 text

UFCS最強 struct Vector(size_t D, T = double) if (__traits(isFloating, T)) { T[D] num; alias num this; } T dot(size_t D, T = double) (const Vector!(D, T) lhs, const Vector!(D, T) rhs) { T res = 0; static foreach (i; iota(D)) res += lhs.num[i] * rhs.num[i]; return res; } Vector!(D, T) cross(size_t D, T = double) (const Vector!(D, T) lhs, const Vector!(D, T) rhs) if (D == 3) { return Vector!(D, T)([ lhs.num[0] * rhs.num[1] - lhs.num[1] * rhs.num[0], lhs.num[1] * rhs.num[2] - lhs.num[2] * rhs.num[1], lhs.num[2] * rhs.num[0] - lhs.num[0] * rhs.num[2] ]); } Uniform Function Call Syntax void main() { auto v0 = Vector!3([ 1, 2, 3 ]); auto v1 = Vector!3([ 4, 5, 6 ]); writeln(v0.cross(v1)); writeln(v0.dot(v1)); } ↓同じくこんな感じで呼べる

Slide 12

Slide 12 text

UFCS最強 import std.stdio; string repeat(string s, size_t times) { char[] res; for (size_t i = 0; i < times; i++) res ~= s; return cast(string) res; } void main() { "Hello world\n".repeat(3).write(); } 要はこんなことができる

Slide 13

Slide 13 text

CTFE最強 Compile Time Function Execution コンパイル時にインタプリタで実行してその計算結果 をバイナリに埋め込む 割と任意の処理がコンパイル時に実行できる

Slide 14

Slide 14 text

CTFE最強 Compile Time Function Execution 標準ライブラリには正規表現の文字列をコンパイル 時に解析するヤツとかある 私はこの機能を使ってコンパイル時 brainfuckインタ プリタを書きました

Slide 15

Slide 15 text

CTFE最強 Compile Time Function Execution この機能を掘り下げるとちょっと面白い 1. D言語をバイトコードにコンパイル 2. バイトコードをインタプリタが実行 3. 実行結果をコンパイラがバイナリに埋め込む ...という風に実現されているようです

Slide 16

Slide 16 text

微妙だと思う点もある あくまで私の主観ですが ...

Slide 17

Slide 17 text

それ言語レベルで実現しちゃったのか - unittest - version - debug - foreach_reverse

Slide 18

Slide 18 text

それ言語レベルで実現しちゃったのか - unittest - version - debug - foreach_reverse int multiply(int a, int b) { return a * b; } unittest { assert(multiply(2, 3) == 6); assert(multiply(7, 9) == 63); } Cでライブラリ毎にテスト方法がバラバラだった のをどうにかしたかったらしい

Slide 19

Slide 19 text

それ言語レベルで実現しちゃったのか - unittest - version - debug - foreach_reverse version (Windows) { // Windows用のコード } else { // それ以外 } Cのマクロをどうにかしたかったらしい

Slide 20

Slide 20 text

それ言語レベルで実現しちゃったのか - unittest - version - debug - foreach_reverse debug { // デバッグ用コード } これもCのマクロをどうにかしたかったらしい

Slide 21

Slide 21 text

それ言語レベルで実現しちゃったのか - unittest - version - debug - foreach_reverse int[] arr = [ 1, 2, 3, 4, 5 ]; foreach_reverse (i, e; arr) { // 逆向きに反復 } 「順方向」と「逆方向」を相補的なモノとして捉えたようだ

Slide 22

Slide 22 text

言語キメラ - Javaのclassに - C++のtemplateを合体させ - Cのマクロを分解して取り込んだ こんな感じの言語 決して悪いわけじゃないけど2022年基準で見ると微妙な気がする

Slide 23

Slide 23 text

質疑応答とか 一通り Origins of the D Programming Language を読み込んだので D言語の歴史とかも触りだけ話せます

Slide 24

Slide 24 text

参考 - Origins of the D Programming Language https://dl.acm.org/doi/pdf/10.1145/3386323 - Dlang Tour https://tour.dlang.org