dart, swift, kotlin のドキュメントコメントを比較してみた
この記事は, Flutter 大学アドベントカレンダー 2023 の 11 日目の記事です.
3言語のドキュメントコメント比較
ドキュメントコメントの記述ルールを, dart と swift, kotlin を比較して違いや共通点を整理します.
上記に挙げた3言語は, モバイルアプリ開発の個人的な主要言語になります. 各言語の公式 docs のドキュメントコメント記述ルールを読んで要約しました. 以下に折りたたんでおきますが, 読み飛ばして問題ないです.
dart ドキュメントコメント記述ルール要約
公式 docs として以下に記載されています.
要約すると
- インラインコメントは(//), ドキュメントコメントは(///)
- 文章で書く
- マークダウンで記述する
- 関数→動詞で始める, 真偽値以外→名詞句で書く, 真偽値→Whetherで始める
2023/11/22 のFlutter大学共同勉強会発表が参考になります.
【kosuke】Dartのドキュメンテーションについて
swift ドキュメントコメント記述ルール要約
公式 docs として以下に記載されています.
但し, コード内のドキュメントコメントの記載ルールという観点ではなく, Swift-DocC としてのAPIドキュメント作成という観点で書かれている印象を受けました.
要約すると
- ソースコメントは(//), ドキュメントコメントは(///)
- 前提として適切にAPIを作成すれば, 自己文書化されるはず.それでも抜け落ちる情報を付与してやる.
- 1行目は概要を記載する.
- markdownではなくプレーンテキストで.(びっくり!)
- 150 文字以下の単一の文または文の断片が望ましい.
- 技術用語, その他のシンボル名を含めない.
- 追加で記載するなら, 2行目は空白にして, 3行目から記載する.
- 3行目以降は複数行でOK.マークダウンが利用できる.
- プロパティ, メソッド, 列挙型のケースなどの説明を加える.
- パラメータセクション, もしくはパラメータフィールドを使って各パラメータの説明を設ける
以下のようなドキュメントコメントになるはずです.
/// Eat the provided specialty sloth food.
///
/// Sloths love to eat while they move very slowly through their rainforest
/// habitats. They're especially happy to consume leaves and twigs, which they
/// digest over long periods of time, mostly while they sleep.
///
/// When they eat food, a sloth's `energyLevel` increases by the food's `energy`.
///
/// - Parameters:
/// - food: The food for the sloth to eat.
/// - quantity: The quantity of the food for the sloth to eat.
///
/// - Returns: The sloth's energy level after eating.
///
/// - Throws: `SlothError.tooMuchFood` if the quantity is more than 100.
mutating public func eat(_ food: Food, quantity: Int) throws -> Int {...}
どんなフィールドを追加できるかは, 以下にまとまっていました.
kotlin ドキュメントコメント記述ルール要約
公式 docs として以下に記載されています.
Kotlin のドキュメントコメントは KDoc というそうです. Java の場合は Javadoc になります.要約すると
-
/**
で始まり**/
で終わる. - 1行目が要素の概要説明であり, 1行飛ばして3行目の次のテキストから詳細説明.
- ブロックタグ(
@
から始まる)で色々な情報を付与しよう! - マークダウン使えるよ.
以下のようなドキュメントコメントになるはずです.
/**
* A group of *members*.
*
* This class has no useful logic; it's just a documentation example.
*
* @param T the type of a member in this group.
* @property name the name of this group.
* @constructor Creates an empty group.
*/
class Group<T>(val name: String) {
/**
* Adds a [member] to this group.
* @return the new size of the group.
*/
fun add(member: T): Int { ... }
}
各言語の公開年度と簡単な説明, 公式 docs のドキュメントコメント記述ルール記載URL を記載すると, 以下のようになると思います.
言語名 | 公開年度 | 1文説明 | 公式 docs のドキュメントコメント記述ルールURL |
---|---|---|---|
dart | 2011年 | jsの代替言語 | https://dart.dev/effective-dart/documentation |
swift | 2014年 | Objective-Cからの世代交代 | https://www.swift.org/documentation/docc/writing-symbol-documentation-in-your-source-files |
kotlin | 2011年 | Javaの代替言語 | https://kotlinlang.org/docs/kotlin-doc.html |
記述ルールについては先人達が試行錯誤した結果なので, おおよそが共通してました. 具体的に言うと以下の点です.
- (当たり前だが)コードコメントとドキュメントコメントは別物.
- 1行目は概要説明を簡潔に.
- 2行目飛ばして3行目から詳細説明を.
- マークダウン使える.
相違点としては以下の点があります.
- タグやセクションの概念を dart は取り除いている.
考察
記述ルールはおおよそ共通していました. 1行目に概要, 3行目から詳細を書く方法は, コミットメッセージを書くときのルールにも通じる部分があります.
基本的にmarkdownが利用できましたが, 1行目には利用しないことが無難でしょう. markdown は github や slack, backlog などの主要なサービスで利用できる他, mdxjs や 多くのOSSのdocsを生成している静的サイトジェネレータで利用できるなど軽量マークアップ言語として確固たる地位を築いていることから採用されていると考え, とても便利です.
しかし, 使い過ぎには注意した方が良いでしょう. コードや全体設計がしっかりとしていればコメントに必要以上の構造化は不要なはずです. プレーンテキストの延長線上程度に使って, 度を超えて使ってしまった場合はそもそもの設計やコードを見直した方が良いです.
そもそもコードや設計が汚かったり, 開発体制が杜撰な結果生まれるコメントもあります. 読みやすいコードを書くことで, 不要なコメントを記載する必要をなくすことができます. 以下の書籍が参考になります.
dart が他言語と異なりタグやセクションを使わないという選択をとった事で, 生成される API ドキュメントの結果にも変化が発生しています.
params や throws が 1つずつタグ付けされ構造化されているか, 文章として包括的に説明するかの違いは, dart doc
と Swift-DocC の生成結果を比較すると分かります. (左がswift, 右がdart)
モバイルアプリのクライアント側の開発言語として3者を比較するならば, そもそも APIドキュメントを生成する必要性はあまりなく, ドキュメントコメントは開発者が直接コードを見る, または利用箇所からeditorの機能によって表示される説明として確認するに留まるでしょう. 私の認識では2023年現在,3言語の主たる用途はクライアント開発です. もちろん, サーバーサイドで3言語を使おうという試みがあることも存じてます.
APIドキュメントとして各パラメータの説明やタグ付けしたレイアウト調整, 検索機能を設ける場合, タグやセクションは必要だと思います. つまり, dart でもサーバーサイド開発で使うなら Effective-dart に従わずにタグやアノテーションをつけるべきだと個人的には考えてます.
この3言語に関わらず, サーバーサイドの開発を行うと言う前提ならば, ドキュメントコメントを書く価値はより高くなると考えます. なぜならば, APIドキュメントを生成する必要性が出てくるからです. APIドキュメントの生成で有名なところでは OpenAPI (旧 Swagger ) があります.
長くなるので以下に折りたたむ.
APIドキュメントを生成する必要性について語ったポエム
クライアント開発者目線からいうとドキュメントコメントはめちゃくちゃ大事だと考えます.
なんでかというと, 叩くAPIについての仕様書 = API ドキュメント が欲しいからです. 人力でスプレットシートを使って〜...とかやると, 更新もれて詰みます.改訂履歴とかも, 増えていくと追えなくなります.100行目を...とか書いてあっても, 列の追加されたりされると, 生合成合わなくて詰みます.
なので, APIドキュメントはコードに記述したドキュメントコメントから自動生成するのが一番です.更新漏れがないように, CD としてドキュメントコメントを更新して欲しいし, フロントがあるなら https://xxx.develop/docs/
とかのURLでアクセスしたいです.
dart なら dart doc
, swift なら Swift-DocC, kotlin なら dokka などがあります.
サーバーサイドの言語やフレームワークにあったものをご利用ください.また, OpenAPI等の言語に関係なく利用できるものを使うのも良いでしょう.
...とは言っても, サーバーサイドを変えるのは現実的に無理な場合もあるでしょう.
サーバー側がAPI仕様書を自動生成してくれない かつ API仕様書の更新漏れが多々発生している...そんな場合の対抗策として, PostmanでAPIを叩いた結果をコレクションしておくと API仕様書からもれている挙動などを見つけられます. また, なんかおかしいなと思った時に, 過去の叩いた結果と今叩いた結果を簡単に比較できます. そんな手間かけたくないんですがね...
コードから仕様書を作成する行為は, Protocol Buffers の protoc ファイルから各言語のコードを自動生成する行為に似てます. つまり, そんな面倒な事をいちいちやっちゃあいられないのだ. 無駄は省く設計に越したことはありません.
無駄を省くと言えば, 全てのコードにコメントを書くのは冗長で無駄であるでしょう. しかし, 必要な場所にはコメントをするべきです. そして、その場所は思っている以上に沢山あります. 普段コメントを書いていないと確かにコストがより多くかかってしまいますが, 1年くらい意識して書くようにすればそれほど重いコストではなくなります.
とは言っても, やはりちりつもで時間がかかってしまうのでだんだん書かなくなっていく... ここでの問題は, 訓練した上でも, 有効なコメントを記載するコストが許容できるより少し大きいことです. 解決策として, 道具の力を借りる事をお勧めします. copilot は, コードからコメントを生成してくれます. 開発者はそのコメントを少し手直しすれば良いだけなので, 以前よりも圧倒的なスピードでコメントを記載できます. 実際に私がそうでした. 導入できない環境の場合は, まずは訓練でコストを小さくするところから始めてみましょう.
後は, 細かいところで言うと ドキュメントコメントの付け方は タイピングのしやすさの為, /** **/
から ///
に変遷している気がしました. その上で kotlin が /** **/
なのは java の代替という歴史的経緯がある為なのかなーと思ってます. 個人的には, //
は インラインコメント, ///
がドキュメントコメントで, /* */
や /** **/
は ソースコードの一時的なコメントアウトに利用したいですね. 同じコメントアウトという作業でもそこに込められた意図が異なるので, それに合わせてコメントのシンタックスを使い分けたいです.
最後に
swift-DocC を使った経験があったので, kosukeさんの発表で改めて Effective dart を読んで「あれ, swiftだとパラメータもコメントするよな?」と思ったのがこの記事を書くきっかけになりました.kotlinのコメントルールは知らなかったし, こうして比較することで言語で共通するところはみんなの共通認識, 相違があるところは言語による考え方の違いなのかなー, と楽しむことができました.
気になった箇所とか間違い指摘とか感想あったらお気軽にコメントください!
Discussion
2023/12/14
大幅改訂しました.
記事のレイアウトを改めました. 大幅な加筆・修正を行いました.
加筆前に 後発 の dart は ... と記載しておりましたが誤りになります. dart, kotlin は 2011年, swift は 2014年 に生まれてます.