11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

2023年 D言語まとめ

Last updated at Posted at 2023-11-30

はじめに

2023年12月、世界的にコロナ前の経済に戻ろうとする中、生成AIのブームなどを横目にD言語コミュニティも着実に進歩してきました。
言語的な強化、周辺ツールやC言語との連携、DConfなどのイベントにも触れながら、今年もその変遷を振り返っていきたいと思います!

ちなみにこの企画も6年目、過去の記事は以下のリンクからご覧ください!

まとめ

コンパイラ関連

DMD

概要

  • 2023年にリリースされたバージョンは 2.102.x から 2.105.x
    • 1年間で4回のリリースがありました。(11月現在)
    • 例年目標は2ヶ月に1回の頻度なのですが、10月分がスキップされています。恐らくDConfの開催時期と被ったためと思われます。
  • 言語としての新機能
    • scope で宣言された配列をスタックに割り当てるようになりました。
    • alias this = ...; の構文が使えるようになりました。
    • ユーザー定義属性(UDA)の解析がテンプレート引数のようになりました。
    • -preview=systemVariables が追加されました。
  • メモリ安全性のサポート強化
    • ランタイムにValgrind memcheckとの連携機能が実装されました。
    • GCが呼ぶファイナライザの循環でエラーメッセージが強化されました。
  • エラーメッセージの改善
    • static assert が複数引数を受け取り、 std.formattext のように使えるようになりました。
    • static assert を活用してライブラリのエラーメッセージが改善されました。(joiner, sort, permutation, clamp
    • 属性推論が失敗したときのメッセージが改善されました。
  • @nogc 対応
    • ランタイム機能のいくつかで @nogc がサポートされ、BetterCでも動くようになりました。(TraceInfo, core.sync.conditionnotify メソッド)
  • プラットフォームサポートの強化
    • OpenBSDの unistd.d やLinux input ヘッダのサポートが追加されました。
    • CPUの命令セットを扱う std.system.instructionSetArchitecturestd.system.ISA 追加されました。
  • Unicode 15 バージョンアップ
    • Unicodeのテーブル生成や書記素(grapheme)の操作アルゴリズムなどが更新され、Unicode 15に対応しました。
  • DUBの高速化
    • キャッシュの管理を見直すことにより、Dockerでのビルドキャッシュなどの面から高速化されました。
  • ImportC対応
    • ImportCに __check(assign-expression) が追加されました。
    • DUBでC言語のソースを参照するパスとして cSourcePathscImportPaths が SDL/JSON に追加されました。

2.102.x

  • 2022/02/01リリース
  • まとめ記事
  • コンパイラ変更点
    • 非推奨: extern (D) @system な関数定義の衝突が見逃されるケース
    • 非推奨: オーバーロード集合に対して __traits(getAttributes) を呼び出す機能
    • 非推奨: 空でない for 文の副作用のないインクリメント句
    • 強化: scope 宣言された配列変数に割り当てられた配列リテラルはスタックに確保
    • 強化: static assert は複数のメッセージ引数をサポート
    • 強化: -preview=systemVariables が追加
  • ランタイム変更点
    • 変更: Throwable.TraceInfo@nogc で生成されるようになった
    • 改善: GCが呼ぶファイナライザの循環エラーメッセージ
    • 改善: core.sync.conditionnotify メソッドが @nogc で動作するようになった
  • ライブラリ変更点
    • 強化: log 関数族に単精度および倍精度の実装が追加
    • 強化: Unicode Propertyにおける誤った値(COther)の修正
    • 強化: Unicodeテーブル生成がPhobosに組み込まれ、version 15 に更新
    • 強化: std.typecons.Uniquestruct のデストラクタを呼び出すようになった
  • DUB変更点
    • 強化: バイナリ出力は中央キャッシュに置かれるようになった
    • 変更: DUB APIの Package.metadataCache の setter と getter が削除
  • インストーラー変更点
    • 強化: バンドルされている VisualD のパッケージが更新
    • 強化: Windows 64bitでは、32bitのDMDより64bitを優先するように変更

2.103.x

  • 2023/04/01リリース
  • まとめ記事
  • コンパイラ変更点
    • 新機能: ImportCに__check(assign-expression)追加
    • 非推奨: クラスに対するalias this
    • 新機能: -preview=dip25がデフォルトで有効化
    • 変更: export int a;dllimportからdllexportに変更
    • 非推奨: __traits(isVirtualFunction)および__traits(getVirtualFunctions)
  • ライブラリ変更点
    • 強化: 書記素(grapheme)の走査ロジックをUnicodeバージョン15に更新
    • 強化: std.algorithm.iteration.joinerstd.algorithm.sorting.sortstatic assertメッセージ改善
  • DUB変更点
    • 強化: --color引数の値をautoneveralwaysに更新

2.104.x

  • 2023/06/02リリース
  • まとめ記事
  • コンパイラ変更点
    • 改善: 属性推論が失敗した時のエラーメッセージが改善されました。
    • エラー: ; を空文として使用することはエラーになりました。
    • 非推奨: in パラメータを extern(D)/extern(C++) 以外の関数で使用すること。
    • 非推奨: パラメータに対する in ref-preview=in を使用するため。
    • 非推奨: 修飾されたオブジェクトをスローすること。
    • 強化: ユーザー定義属性(UDA)は、テンプレート引数のように解析されるようになります。
  • ランタイム変更点
    • 改善: Bugzilla 11989: TickDuration を非推奨にする。
  • ライブラリ変更点
    • 改善: std.algorithm.comparison.clampstatic assert メッセージが改善されました。
    • 強化: std.typecons.Rebindable がすべてのタイプをサポートするようになりました。
    • 改善: Bugzilla 6106: replace 関数の変更の追跡を維持する。
    • 改善: Bugzilla 14478: isInputRange は非コピー可能な要素の範囲を許可するべき。
  • DUB変更点
    • 新機能: cSourcePathscImportPaths が SDL/JSON に追加されました。
    • 変更: パッケージの内部的な保管方法が変更されました。

2.105.z

  • 2023年8月リリース
  • まとめ記事
  • コンパイラ変更点
    • 新機能: alias this に代入スタイルの構文が許可
    • 変更: catch 節は、const または mutable な例外のみを取る必要
    • 削除: 関数での enum ストレージクラス指定不可
    • エラー: extern(C) 関数のオーバーロード禁止
    • 非推奨終了: public でオーバーロードされた private メソッドへのアクセス
  • ランタイム変更点
    • 新機能: druntime に Linux input ヘッダの翻訳追加
    • 新機能: ガベージコレクタに Valgrind memcheck ツールの統合
    • 改善: OpenBSDの unistd.dgetthrname(2)setthrname(2) 追加
    • 改善: 配列比較に float opCmp(...) 形式のサポート
  • ライブラリ変更点
    • 改善: std.algorithm.iteration.permutationsstatic assert メッセージ改善
    • 新機能: std.system.instructionSetArchitecturestd.system.ISA 追加
  • DUB変更点
    • 新機能: CLIフラグ --d-versions の利用可能

LDC

概要

  • 2022年にリリースされたバージョンは1.31.0から1.35.0まで(11月現在)
    • dmdで言うと 2.101.0 から 2.105.2 相当
    • おおむねdmdのマイナーバージョン更新から1か月でリリースされる傾向
  • LLVM16までサポートされた。
  • RISC-Vのサポートが追加された。(-mabi スイッチ)
  • その他スイッチやオプションの追加や強化が多数
    • セマンティック解析プラグインを利用する: --plugin
    • LLVMの変数ライフタイム注釈を有効にする: -femit-local-var-lifetime
    • IntelのControl-Flow Enforcement Technology (CET) を有効にする: --fcf-protection
    • GCCおよびClangと同様のオプション: -fno-delete-null-pointer-checks
    • LLVM IRでの値の名前を保持する新しいコマンドラインオプション -fno-discard-value-names が追加されました。

1.35.0

リリース日: 2023年10月15日
GitHub Releases: LDC 1.35.0リリースノート

主な更新
  1. フロントエンド、druntime、Phobosがバージョン2.105.2に更新されました。
  2. Windowsインストーラが、/CURRENTUSER スイッチなしで非管理者インストールをサポートするようになりました。
プラットフォームサポート関連
  • LoongArch64 の初期コンパイラサポートが追加されました。ただし、druntimeのサポートはまだ保留中です。
不具合修正
  1. ImportCでのstaticリンケージの修正。
  2. gccビルトインの利用可能化。
  3. Apple向けに特殊なasm("_" "<name>")マングリングのサポート。
  4. AArch64でのABI関連のICEを修正。
  5. v1.24で導入されたGC2Stack最適化のリグレッションを修正。
  6. サニタイザサポートでコンパイルする際のdruntime ABIの不一致を修正。
  7. Windowsで-ftime-trace JSONのバックスラッシュエスケープ漏れを修正。

1.34.0

リリース日: 2023年8月26日
GitHub Releases: LDC 1.34.0リリースノート

主な更新
  1. フロントエンド、druntime、Phobosがバージョン2.104.2に更新されました。
  2. LLVM 16のサポートが追加され、プリビルドパッケージはv16.0.6を使用します。ただし、LLVM 16で新たにデフォルトで有効化された関数特殊化に関して、Win64とmacOSでの誤コンパイルが発見されたため、全てのターゲットに対してデフォルトでこれらの特殊化を無効化する設定が追加されました。
プラットフォームサポート関連
  • LLVM 11.0から16.0までのサポートを追加し、LLVM 9および10のサポートを廃止しました。
  • 64ビットRISC-Vについて、非ベアメタルターゲットのデフォルトを-mattr=+m,+a,+f,+d,+c (「rv64gc」ABI)に変更しました。
不具合修正
  • ハーバードアーキテクチャ(例: AVR)上での関数ポインタ/デリゲートの問題を修正しました。

1.33.0

リリース日: 2023年7月23日
GitHub Releases: LDC 1.33.0リリースノート

主な更新
  1. フロントエンド、druntime、Phobosがバージョン2.103.1に更新され、新しいコマンドラインオプション -verror-supplements が追加されました。
  2. --plugin コマンドラインオプションがセマンティック解析プラグインに対応しました。
  3. 新しいツール ldc-build-plugin が追加され、ユーザープラグインのコンパイルを支援します。
  4. 新しいコマンドラインオプション -femit-local-var-lifetime で、変数のライフタイム(スコープ)注釈がLLVM IRコード生成に有効になりました。
  5. Cファイルは外部Cコンパイラを使用して自動的にプリプロセスされるようになりました。
  6. 複数のモジュールを単一のオブジェクトファイルにコンパイルする際のC(++)関数宣言の競合チェックが緩和されました。
  7. 新しいコマンドラインオプション --fcf-protection で、IntelのControl-Flow Enforcement Technology (CET)が有効化されました。
プラットフォームサポート関連
  • LLVM 9.0から15.0までのサポートを提供します。
不具合修正
  • 別々にコンパイルされたオブジェクトファイル間でのラムダマングルの競合を処理する問題を修正しました。ラムダ(およびそれらのネストされたグローバル変数)は、各参照オブジェクトファイル内で内部的に扱われるようになりました(C言語のstaticリンケージ)。

1.32.0

リリース日: 2023年3月12日
GitHub Releases: LDC 1.32.0リリースノート

主な更新
  1. フロントエンド、druntime、Phobosがバージョン2.102.2に更新されました。
  2. プリビルドパッケージのLLVMがバージョン15.0.7にアップデートされました。
  3. Apple、wasm、および全てのELFターゲットに対してリンカーレベルのデッドコード除去がデフォルトで有効化されました。
  4. ベクター比較 (==, !=, <, <=, >, >=) がベクターマスクを生成するようになりました。なお、同一性比較 (is, !is) は引き続きスカラーの bool を生成します。
  5. --ftime-trace 出力を容易に検査するための新しいツール timetrace2txt が導入されました。
  6. --ftime-trace がCTFE実行も追跡するようになり、CTFEの開始式とCTFE中の関数呼び出しが追跡されます。
プラットフォームサポート関連
  • LLVM 9.0から15.0までのサポートを提供します。
  • RISC-Vターゲットに対する -mabi オプションのサポートが追加されました。
不具合修正
  • 16バイトを超えるアライメントを持つ変数を含むGCクロージャーのアライメントが適切に行われるようになりました。
  • LLVM 13以降でのリグレッションを修正し、インラインアセンブリの一部のエラーがコンパイレーションを停止しない問題を解決しました。

1.31.0

リリース日: 2023年2月11日
GitHub Releases: LDC 1.31.0リリースノート

主な更新
  1. フロントエンド、druntime、Phobosがバージョン2.101.2に更新されました。
  2. ビットフィールドのサポートが追加されました。
  3. Apple M1上のmacOSで、-g を使用してのリンクが再び警告/エラーなしで動作するようになり、例外バックトレースのファイル:行デバッグ情報の修正が行われました。
  4. LLVM 15の予備的なサポートが追加され、新しいパスマネージャ(-passmanager)と不透明なIRポインタ(-opaque-pointers)のサポートが含まれています。
  5. GCCおよびClangと同様の新しいコマンドラインオプション -fno-delete-null-pointer-checks が追加されました。
  6. 新しいUDA ldc.attributes.callingConvention("...") で、デフォルトの呼び出し規約を上書きすることが可能になりました。
  7. LLVM IRでの値の名前を保持する新しいコマンドラインオプション -fno-discard-value-names が追加されました。
  8. dcomputeでのOpenCLイメージI/Oのサポートが追加されました。
プラットフォームサポート関連
  • 64ビットRISC-Vの初期ABIサポートが追加されました。
不具合修正
  1. dcomputeでのv1.29のリグレッション、具体的にはintrinsicの使用時の問題を修正しました。
  2. 64ビットシンボルオフセットの問題を修正しました。
  3. Linuxのマルチリブパッケージに欠けていた32ビットLTOバージョンのdruntimeとPhobosを追加しました。
  4. コンパイラクラッシュの問題を修正しました。

コミュニティ関連

DConf 2023

例年行っているD言語の国際イベント DConf が、昨年に引き続きイギリスでオフラインイベントとして開催されました。
開場はロンドンのリバプール近隣にある CodeNode というテックイベント向けの開場です。開場は最大400人収容だそうです。

DConf 2023は8/29~9/1の4日間開催で、前3日が公開発表のセッション期間、最終日はハッカソンとセミナーが行われています。
ゲストには、D言語のコア開発者に向けた啓発支援を行うコンサルティング会社から Saeed Sabeti 氏が参加されており、D言語開発者のキャリアやビジョンの描き方に関する基調講演を行っています。

  • 公式サイト
  • YouTubeプレイリスト
  • 概要
    • すべてのセッションはスライドと動画が公開されています。
    • 動画は全部で15本。45分程度の動画が多く、短ければ30分、長くても50分以内です。
    • 多くの動画でセクションが設定されており、トークのテーマごとにジャンプすることができます。
    • 一部動画は手動で字幕が付けられており、自動翻訳も見やすくなっています。
    • 会場のLivestreamが3日分あり、8時間以上フルタイムで見られるので海外カンファレンスの流れや雰囲気が掴めます。

セッション内容

別のカレンダー記事で一通り触れたく思うので、この場ではキーノートのみ簡単に整理します。

The Truth About D

DConf 2023の初日、2023年8月29日火曜日に開催されました。

英語の原題は "The Truth About D" で、日本語に訳すと「Dについての真実」になります。

スピーカーのSaeed Sabeti氏は、カナダ・バンクーバーのUcora Corporationで組織開発部門のディレクターとして働き、人間のモチベーション、チームダイナミクス、チームビルディング、および組織開発の分野についての専門家とのことです。現在は、スタッフの獲得、保持、モチベーション、生産性の問題に取り組むことで、リーダーや組織が基本的な目的に根ざした新しいマインドセットを開発するのを支援されています。

スピーカーとして見るとプログラミングカンファレンスではやや異質な立場ですが、プログラミング界における不確実性、競合言語の台頭に直面しているD言語が抱える課題に焦点を当てることで、個人の強化や組織論的な対策を提供するパートナーとして参加しています。

具体的には、IVY(Ideal Vision of Yourself、あなたにとっての理想のビジョン)という方法論を持っており、それを使ってD言語や開発者の潜在的な力を発揮させる道を模索する、という内容です。
自己啓発的な側面が強いですが、自分の理想を追い求めよう、というポジティブな面を引き出す力を持った面白いセッションであると思います。

セッション情報: https://dconf.org/2023/index.html#saeeds
動画: ビデオ (YouTube)
資料: スライド (PDF)

Crafting Self-Evident Code with D

DConf 2023の2日目、2023年8月30日水曜日に開催されました。

英語の原題は "Crafting Self-Evident Code with D" で、日本語に訳すと「Dで自明なコードを作る」といったところです。

スピーカーはD言語の作者でもあるWalter Bright氏です。Walter自身がC++を含む複数の言語のコンパイラを実装した経験を持つ専門家で、コンパイラ技術の全分野に精通しており、定期的にコンパイラやプログラミングに関する記事を執筆し、コンパイラ開発技術に関するトレーニングを提供している、というかなりのエキスパートです。

このセッションでは、コードを理解しやすく書くためのテクニックについて、Walterの長年の経験をもとに、D言語がどのようにして理解しやすいコードの記述を容易にするか、具体的なサンプルコードと共に語っています。
セッションでは、他人が見ても「これは簡単だ、誰でも書けたはずだ」と思わせるようなコードを目指すべきだと話しています。

ちなみにタイトルの「Self-Evident」というのは普通に翻訳すれば「自明」という意味なのですが、自明とはどういうことか、ダメなコードは何が分からないのか、実際サンプルコードを見るだけでコードが理解できるとはこういうことだ、と攻め気味のセッションです。ぜひ見てみてください。

セッション情報: https://dconf.org/2023/index.html#walterb
動画: ビデオ (YouTube)
資料: スライド (PDF)

You're Writing D Wrong

DConf 2023の3日目、2023年8月31日木曜日に開催されました。

英語の原題は "You're Writing D Wrong" で、日本語に訳すと「あなたはDを間違って書いている」です。マジか。

スピーカーはD言語の中心的な開発者である Átila Neves 氏です。Átila氏は粒子物理学の博士号を持ち、CERNでの研究に従事していました。その後C++でのプログラミングを中心に、Ciscoでは約7年間ネットワーキングソフトウェアの開発に従事しながら、ソフトウェアの品質とテストの分野でチームをリードしました。現在はスポンサーであるSymmetry InvestmentsでD言語のコンサルタント兼プログラマーとして働き、D言語の副メンテナーも務めています。

セッションでは、間違った記述の分類として、null や参照などのセマンティクスを挙げ、値セマンティクスがほしい、パフォーマンスのペナルティは避けたい、そのためにライブラリを書いた、と語り、様々なコーディングの注意点を挙げていきます。
たとえば、APIデザインは明示的にして private に注意する、リファクタリングのためにローカルな import を使う、auto を書かずに constscope を使う、unittest@safe pure なものにしよう、etc. といった感じです。

細部にまでこだわるコーディングのプロ、という印象が伝わってくる内容です。
コーディングにおける多くの価値観が共有されているので、コードを書くときは何に気を付けるべきか経験者が語る、といったセッションと思って見ていただくと学びがあると思います。

動画: ビデオ (YouTube)
※動画の切り出し等がまだのようなので、Livestreamの開始位置だけ共有します。
資料: まだ共有されていないようです。

話題・ニュース

2023年公開の公式ブログやフォーラムを使ったアナウンスを元に、いくつか興味深いニュースについて振り返ってみたいと思います。

D言語会議報告

D言語のコア開発者が行っている会議報告のサマリーがフォーラムで共有されています。
せっかくオープンなのでリンクをまとめてみました。D言語の今後について調べるときは、主にこのあたりを当たっていくことになりそうです。

内容は、実績や課題、今後の展望についての話がいろいろあり、オープンな開発姿勢が示されている内容なので興味があれば翻訳したりしてみてください。(回によってはサンプルコードが含まれたり、かなりのボリュームがあります)
OSS活動ではありますが、英語圏(主にアメリカ)の議事録ってこんな感じなんだ、というのもちょっと文化が分かって面白いかもしれません。

月例報告

個人的に気になるのは、以下のあたりでした。

  • Bugzillaで管理されているIssueのGitHubへの移行(2月分ほか)
  • GDCがLTS版として提供されるようになるかも(7月分)
  • ノースイースタン大学との産学連携でD言語を学ぶインターン獲得(8月分)
  • ループにおけるタプルアンパッキングの実装デモ(9月分)

四半期報告

D言語機能ロードマップの1つ「Editions」

D言語の安定性を上げるという目的から、非推奨機能などをまとめて管理するための新しいオプトイン枠組みが検討され始めました。
その名も「Language Editions」あるいは単に「Editions」と呼ばれる仕組みです。

7月の計画会議で提案され、9月に方向性ミーティングが行われています。

D言語の強化と後方互換性の維持を両立する必要があるため、周辺ツールも含めた機能となるようです。

Editionという名称は実はRustでも存在しています。
しかも、議論されているテーマやキーワードの多くで類似が見られます。

同じ課題を気にして対策しようと考えたのかもしれません。
後発として問題点を避けつつ、スッキリした無理のない機能になることを期待したいです。

写真管理ソフトウェア「Aspect」がD言語で開発されている話

本件のネタ元は、D言語作者のWalterが共有していたブログポストです。

Sönke Ludwig氏が勤務している企業の企業ブログ(技術ブログ)のポストで、開発している写真管理ソフトウェアの「Aspect」がD言語で書かれていること、その初期調査でC++で書かれたゲームエンジンをD言語に移植した話について語られています。

写真管理ソフトウェアのAspectは、GUIも含めてすべてD言語で書かれているそうです。
コンセプトとしては、写真管理のスタンダードな星レーティングやカラータグ、簡単な文字タグに限らない方法で整理と共有を実現するソフトとのこと。
具体的にはポートフォリオというネスト可能なグループ分けを多数持てる仕組みのようで、整理大好きな人には実に面白いソフトかもしれません。

実際の画面サンプルなどが見たい方向け、製品ページはこちらです: https://aspect.bildhuus.com

さて、記事のメインである、D言語採用に向けた初期調査としてのゲームエンジン移植の話に移ります。

元々ゲームエンジンの開発でC++の複雑な構文に嫌気が差し、ビルド時間が長いこともネックになっていた状況だったようです。
D言語のリリースからバージョン2になった2007年ころに目を付け、調査を開始したとのこと。

数か月かけてゲームエンジンをD言語に書き換える取り組みの結果、コードは約15万行になり、(元の行数は不明ですが、)短くなってビルド時間も改善したとのことです。

D言語の利点として、簡潔な構文、モジュールシステム、テンプレートとメタプログラミング機能、そして強力なパッケージおよびビルドシステムが挙げられ、これらは開発の効率を根本的に向上させた、と述べられています。
一方途中で直面した課題には、コンパイラの更新に伴う問題やモバイルプラットフォームのサポートがありましたが、時間とともにこれらの問題は大部分解決されたようです。

総評として以下2つの価値観が得られているようでした。

  1. 少ないコードは、変更が必要なコードが少ないことを意味し、バグの導入の機会を減らすことにつながる。
  2. ビルトインのユニットテストにより、コードベースが頑健で長期的な成長を可能にしている。

今後の重要なマイルストーンには、Metalベースのレンダリングのサポート、iOSおよびAndroidアプリの開発が含まれるようです。
あんまりイメージ無いかもしれませんが、D言語にはモバイルサポートもありますからね!やっていきましょう!

またこれを書いていて思いだしたのですが、昨年は気体力学のシミュレーションツールEilmerが25万行あって無理になってD言語に移植したという話があったのでした。
みんなこの辺りの規模で無理になる法則がありそうですね。

同じような理由で限界迎えているプロジェクト、あと数年で迎えそうなプロジェクト、皆さんの周りにありませんか?
D言語に書き換えると良くなるらしく、何やら初期調査が有効なようなので、おすすめです。

最後に

みなさん気になる強化やニュースはありましたか?

alias this などの構文、メッセージ改善、周辺ツールやC言語との連携(ビットフィールド)など、言語としての進歩が多数ありますので、ぜひ見返して試してみてください。
言語的にはLDCの強化ボリュームが例年よりもかなり大きい印象で、また言語機能のほうも波はありますが大きなボリュームだったように思います。

また、コミュニティ運営の面でも昨年から開発者ミーティングが継続され、運営や計画の面でもかなり安定した様子が見て取れる1年でした。
パートナーとしてUcoraの支援を受けて随分モチベーションが上がったという投稿も行われていたので、その効果かもしれません。

皆さまもぜひともモチベーション高く、D言語と共に素敵な年末を過ごしていただければと思います!

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?