実例こそ最高のドキュメント
(rakhim.exotext.com)- 開発者がドキュメントを検索するとき、95%は簡単な実例だけで十分だが、公式ソースで実例を見つけられるのは5%に過ぎない
- 公式の技術ドキュメントは基本的にそのエコシステムに深く没入した人を対象に書かれており、複数のプロジェクトや言語を行き来する開発者にとってはコンテキストを復元するのにかなりの精神的エネルギーが必要
- Pythonの
max()関数のドキュメントを見ると、関数定義の構文や概念を理解するために必要な前提知識が多いが、簡単な実例5行があればすぐに理解できる - Clojureコミュニティのclojuredocs.orgは、ユーザー投稿の実例によって実用的なドキュメントを提供しており、関連関数まで含めて実際の活用度を高めた模範例
- 主要なソフトウェアプロジェクトですら4種類のドキュメントを提供していることはまれで、開発者がチュートリアルを探すのは、案内が必要だからではなく実例が必要だから
ドキュメント検索時における実例の重要性
- 開発者がドキュメントを探すとき、95%のケースではたった1つの実例で十分
- しかし、公式ソースで実例を見つけられるのは5%に過ぎない
- ほとんどの公式技術ドキュメントはエコシステムに深く没入した人を主な対象として書かれている
- 多くの開発者は日常的に複数の「世界」を頭の中でジャグリングしなければならない
- プロジェクト、言語、フレームワーク間の切り替えが頻繁
- コンテキストを復元し、状況を理解するのにかなりの精神的エネルギーを消費
Pythonドキュメントの事例分析
- Python 3ドキュメントの
max()関数の例max(iterable, /, *, key=None): 最大の項目を返す- その後に5つの短い段落で説明が続く
- このドキュメントを理解するために知っておくべきPythonの知識
- 関数定義における
*の意味 - 関数定義における
/の意味 - "positional-only parameter separator"という概念
- iterableの概念
- keyword-only argumentsの概念
keyパラメータの一般的な意味
- 関数定義における
- テキストを読まないとどんな値を渡し、関数を実際にどう呼び出すのか理解できない
簡単な実例の効果
- 重要な詳細を簡潔さのために省略できない点は認める
- しかし、多くの開発者がそのページを探す理由は、単にmax関数にカスタムのソート関数(key)を渡す方法を素早く見つけたいから
- 次のような例があればすぐに欲しい情報を得られる
max(4, 6) # → 6 max([1, 2, 3]) # → 3 max(['x', 'y', 'abc'], key=len) # → 'abc' max([]) # ValueError: max() arg is an empty sequence max([], default=5) # → 5 - 実例を通じて簡単かつ直感的に理解できる
Clojureコミュニティの模範事例
- clojuredocs.orgはClojureコミュニティ主体のプロジェクト
- ユーザーが組み込み関数に対する実例を投稿
- 日常のコーディングで欠かせないリソース
- 例示ページ: into, spit, map などを参照
- 実例の特徴
- その関数だけでなく関連関数も含む
- 実際の活用度と実用性を高める
現在のドキュメント化の限界
- 主要なソフトウェアプロジェクトですら4種類のドキュメントを提供していることはまれ
- 参考: Divioのドキュメントシステム
- 「Documentation」リンクをクリックするのをためらう理由
- 多くは簡潔だが読みにくい自動生成APIリファレンスだから
- 開発者がチュートリアルを探す本当の理由
- 案内が必要なのではなく、実例が必要だから
- チュートリアルには実例が含まれているため、より有用
8件のコメント
正直、JavaやPythonを中心に当てはまる話のように思います。言語至上主義や、パラダイム的に孤立した文化が強いエコシステムでもありますしね。
Pythonを基準にすればよく当てはまる内容ですが、さまざまな言語を学んでいると、5%というのはかなり誇張のように感じます。
コードこそがドキュメントなGoへどうぞ〜
うちはREADMEがなくても、テストコードを読んで開発します
自分だけ頭が悪くて公式ドキュメントを理解できないのかと思っていました(笑)
本当に、サンプルを置いて軽く説明してくれるだけですぐ理解できるのに……
PHPは良い例であり、同時に最悪の例でもありますね。
公式ドキュメントにユーザー投稿コンテンツを掲載できるので、さまざまなコード例を確認できるという点では良い例ですが、
...PHPは組み込み関数まわりの微妙なBCが多く、しかも寄稿された例がどれも大昔のバージョンのものばかりで、実際の挙動と微妙に異なるものが混ざっていて、混乱を増幅させるだけだという点では最悪の例…笑…
昔の iOS や Cocoa の開発ドキュメントを見ると、ユースケースのセクションが別にありましたが、それこそが正しいドキュメント化の方法ではないでしょうか。サンプル、関数シグネチャ、動作説明のすべてが必要です。
公式ドキュメントの貧弱さを昔はStack Overflowやググることで補っていたなら、最近はLLMがそれを埋めている気がしますね。
Hacker Newsの意見
昔のPythonの最も良かった点は、ライブラリのドキュメントを開くと関数の引数と戻り値が明確に整理されていたことだった。最近は多くのJavaScriptやPythonライブラリのドキュメントが例だけしか載せていないことが多くて残念だ。素早く何かを作るには例が良いが、問題を修正したりライブラリを学習したりするには引数の説明が必須だ。例がボーナスとしてあるのは良いが、それがすべてになってはいけない
実際にあなたが欲しいのは型定義だ。型定義は良いドキュメントの役割を果たす。型システムのツールがすでに多くの情報をエディタやIDE上ですぐ見せてくれるので、わざわざドキュメントを探して読むことは減った。最近、例中心のドキュメントが増えたのは、そうしたワークフローの変化のためだ。どうせ型ツールが提供する情報を、ドキュメントに重ねて書く必要はないという判断からだ。私はドキュメントを見るとき、細かな引数よりも「このツールはどんな問題を解決してくれるのか」に関心がある。例はその可能性を示すのに非常に優れている。特定の問題を解決したいとき、例を見ればそのツールが役に立つかを素早く判断できる。--- 型システムがあるなら、私はまず例を見たい。型システムがないなら 1) 不満だ。2) まず例を見て、そのあとで詳細な引数/戻り値/データ構造の説明が欲しい
良いドキュメントには両方必要だ。まず詳細を説明し、その次に多様な例を加えて内容を確認できるようにすればよい。ときには例だけで十分なこともあるが、オプションの組み合わせが多すぎると、すべてを例で見せるのはほぼ不可能だ。だから各オプションの説明を先に提供し、そのうえでできるだけ多様なケースの例を用意して、読者が応用できるようにすべきだ。そして良いドキュメントを作るのは非常に難しく、今では本当にめったに見られない
私は完全には同意しない。Javadocスタイルのドキュメントは型とインラインdocstringに基づくプログラミング用ドキュメントだ。必ず必要ではあるが、わざわざWebに行くよりコードそのものを見るほうが効率的だ。例やQuickStartのようなガイドは絶対に必要だ。それがライブラリの参入障壁を下げてくれる。コードだけ見てもAPIの使い方は簡単には分からない。昔、多くのJavaライブラリがJavadocしか提供しておらず、使い方が分からず不便だった経験がある
しっかりコメントされた例が最高だと思う。でも伝統的なドキュメントの代わりにはなれない
もしかして、他の人が自分とは違う学習スタイルを持っているかもしれないと考えたことはあるだろうか。例がドキュメントの一部であるべきだということに、なぜ抵抗があるのか理解できない。例はさまざまな状況でコンテキスト切り替えの摩擦を減らしてくれるからだ
Unixのmanページにも例がぜひ必要だ。たいていはすでにツールをよく知っている人向けの参照資料としてしか書かれておらず、初心者にはまったく役に立たない。良いドキュメントにはその両方が必要だ
完全に同意する。すべてのmanページ作者に、慣例的なセクションとしてEXAMPLEがあることを思い出してほしい。man(1)公式ドキュメント を参照するとよい
私はそういう問題を感じたことはない。まずコードを書いてみながらコマンドや用語を覚え、エラーの返り値やその原因、パラメータの意味などを一つずつ見ていく。例がなくても、ドキュメントが完全なら十分だ。一方で、何の説明もなく例だけが提供されるのは本当に最悪だ。パラメータが何なのか、何を意味するのかすら分からないドキュメントなんてありえない
以前、Stack Overflowでも似たような試みがあったのが良かった。Stack Overflow Documentation という名前で、2016年から2017年までベータ運用されていた。例中心のドキュメントを作ろうとしていたが終了した。それでもコミュニティが残したコンテンツは今でもCC BY-SAで公開されている
cheat.shを見てみるといい。私はスクリプトの中で
curl cheat.sh/"$1"としてそのまま使っている意外に多くのmanページに例があることにはいつも驚かされる。それでも、もっと包括的に改善できる余地はかなりある
例は初心者やたまに使う人にだけ良いものではない。熟練者にも、すべてのパラメータ構成が載った正規のドキュメントが必要だ。たとえばrequestsのドキュメントは、Google検索するといつもQuickstartのような例ばかりのページに飛ばされて不便だ。HTTP GETは誰でも分かるが、他のオプションが何か、timeoutの扱いやraise_for_statusが204を無視するのかは見つけにくい。両方必要だが、開発者の時間が足りないなら、まずは正しいドキュメントを用意するほうを選ぶだろう。requests Quickstartの例リンク
例を見ると、リファレンススタイルのドキュメントよりも挙動をずっと理解しやすい。人は名前付けから概念整理、文書化まで何もかも得意ではない。最近も、あるパラメータが特定条件でしか動かない問題で何時間も苦労した。コードを追うには複雑すぎたし、LLMでさえそのパラメータは文書化されていないと誤って教えてきた。結局、サンプルコードを作りながら望む挙動を見つけるのが最も効率的だった。例は多くの重要な内容を圧縮して素早く検証できる。一方、APIドキュメントはすべてを網羅しようとして保守も大変になり、肝心なことだけを伝えられない。そして明確でない限り、私はライブラリの挙動を決して信用しない。READMEで明確に挙動が示されているか、型で規定されていないなら、いつでも変更されうることを念頭に置く。結局、呼び出し側のコードはできるだけ防御的に書く
例は初心者だけでなく、誰にとっても重要だ。5秒の例で、1時間分のドキュメント読みと試行錯誤に匹敵する効率が得られる。gitのいくつかのドキュメントがまさにそうだし、本質的には単純でも説明が難しい関数でも同じだ。開発者が一つしか作れないとしても、例とドキュメントの両方を出すくらいの余力は十分あるはずだ。両方提供すべきで、よほど自明な場合だけ例外にできる
同意する。良いドキュメントは、ほとんどプログラムの挙動全体を明確に定義する必要があり、例だけでその役割を果たすのは難しい
両方を同時に持つことはできる。例と技術ドキュメントは両立しない関係ではない
Perlについて何か言う人もいるだろうが、Perlのドキュメントは本当に助けになる。いつもSYNOPSISセクションが前のほうにあって、すぐ使えるサンプルコードが載っている。そのあとに説明、リファレンス、追加の例が続く。例: bigratドキュメント, Archive::Tarドキュメント。プロジェクトのドキュメントを書くならPerlスタイルを参考にするとよい。そしてそのスタイル自体も よく整理されている
両方必要だ。例を見ればすぐ感覚がつかめて統合もしやすいし、細かなパラメータや設定値の説明は、ツールの複雑な問題解決や全体理解に役立つ。どちらか一方でも欠けると本当に不便だ。ただし、とても単純なライブラリなら、例だけですべてを説明できることもある
Diátaxisフレームワークは、ドキュメントにはさまざまな種類があり、それぞれ用途があることをよく示している。どれが「最高」なのではなく、異なるニーズに応じて使われることが重要だ。Diátaxis公式サイト
この話こそ一番上に来るべきだ。これほど多くの議論のあとでようやくDiátaxisへの言及が出てきたのには少しいら立った。例はドキュメントの核心ではあるが、独立した「ドキュメントの種類」というより、重要な「ドキュメント技法」に近いという見方だ
その通り! 例(あるいはチュートリアル)はシステム教育の一つの柱だ。誰が最初に作ったのかは定かではないが、リンク先は記事末尾の著者リンクと似ている。> 「メジャーなプロジェクトでさえ、4種類のドキュメントをすべて備えていることはまれだ。だから『Documentation』リンクをクリックするのをためらうことがある」私は説明中心のドキュメントが好きだ。構造や、なぜそう動くのかを理解すれば、例でもチュートリアルでも受け入れやすくなる。優れたテクニカルライターや教育者が最初からこの枠組みをうまく整えてくれれば効果は大きい。一方、APIリファレンスは主にラッパーや互換実装を作るときに最も必要になる。もともと多くのプロジェクトは非公開APIリファレンスから始まり、ドキュメント化とはそれを外部に公開することだった。divio documentationシステムを参照
Diátaxisの考え方は素晴らしい。ただ、実際のプロジェクトに持ち込むのは簡単ではない。プロジェクトごとに必要なドキュメントの比率は違うし、すべての形式を一つのWebサイトで提供するのは非効率だ。コミュニティの成長や専門性に応じてその比率も変わり続ける。もう少し実践的な方法があればと思う。ドキュメント化は難しい課題で、いつかより良い解決策が出てきてほしい。今のところ、時間と専門性への投資で品質が決まり、たいていはそれが不足しているのが現実だ
UnityやUnrealでこういう問題を本当によく感じる。特にUnrealのノードドキュメントは、ノードのスクリーンショットと名称を繰り返しているだけで、実際にどう使うのかをまったく教えてくれないことが多い。Unityも、ある関数のまともな使い方を知りたくてドキュメントを探しても、内容がまったくないことがある。できることなら、自分でUnityのドキュメントに例を寄稿したいくらいだ
Unrealのひどいドキュメントのせいで、私も膨大な時間を無駄にしている。彼らは「コードこそドキュメント」という雰囲気だが、Blueprint向けの「ノードのスクリーンショット説明」は本当に笑ってしまうレベルだ
私はImageMagickをよく使うのだが、いつも例を探してGoogleで検索していた。そこで個人的にまとめていたノートを、小さなコマンド例集にまとめた。各引数の説明も詳しく追加した。このブログ記事のように例だけではなく、説明も一緒に必要だと思う。まだ草案段階だが、リサイズ、最適化、レイヤー処理のような日常的な作業にはすでにとても役立っている。自分のノート公開リンク
コード例はユニットテストとして実行できるので、ドキュメントが古くなったり壊れたりするのを防げる。自然言語にはできない利点だ
過激な意見だが、あるメソッドの仕様がシグネチャといくつかの代表的な例だけで直感的に推測できないなら、そのメソッドは多くのことをやりすぎている。身動きの取れない抽象化や複雑な例外などは学びたくない
Java系やオブジェクト指向の文化では、とりわけ無意味な説明文や形式的なドキュメントが多く、その雰囲気を受け継いだPython系のフレームワークでも、やはりサンプルがひどく乏しい。
無意味なドキュメント化の例
add(left, right) - 左辺と右辺を足す
肝心のパラメータのデータ型や、返されうる例外、結果値の形、動作構造のようなものは説明していない。
C言語のmanページのようなものなら、短い説明だけでも関数名やパラメータ名から推測して、とにかく使うことはできる。