概要
- プログラムは 入力途中でも有効 であるべきという原則の重要性
- Pythonのリスト内包表記やC言語の関数呼び出しの エディタ補助の難しさ
- RustやJavaScriptの 左から右への構築 による補完性の高さ
- API設計とプログレッシブディスクロージャー の観点からの比較
- 良いAPI設計 がユーザー体験を大きく向上させる事例の紹介
プログラムは入力途中でも有効であるべき
- Pythonのリスト内包表記 は、書き始めの段階でエディタの補完が機能しない問題
- 例:
[line.split() for line in text.splitlines()]のlineは宣言前で補完不可 split()メソッドが存在するかも書き終わるまで不明
- 例:
- エディタの補完機能 は変数や型が明確になった時点でしか有効にならない現状
- Rustの例 では、左から右へとプログラムを構築することで、逐次的に補完が可能
- 例:
text.lines().map(|line| line.split_whitespace()) lineを宣言した瞬間からメソッド補完が可能
- 例:
- Haskell の例(
map words $ lines text)は原則から外れるが、最もエレガント
プログレッシブディスクロージャーとAPI設計
- プログレッシブディスクロージャー :必要な複雑さだけをタイミングよく提示する設計原則
- 例:Wordで画像を挿入した時にだけ画像回り込みオプションが出現
- C言語の関数呼び出し は、構造体にメソッドがないため、関数名を知っていなければならない不便さ
- 例:
FILE *fileの場合、file.readのように補完できず、freadなど関数名を探す必要 - 関連する
closeメソッドの存在を直感的に知ることができない
- 例:
- Pythonや他言語 でも同様の発見性の低さが課題
- 例:
len,length,size,countなど長さ取得関数の命名が統一されていない
- 例:
JavaScriptとRustの良い例
- JavaScript では、
text.split(" ").map(word => word.length)のように、左から右へと構築しながら補完が機能word.lと入力した時点でlengthが補完候補に出現map関数も型に合ったものだけが補完
- Rust も同様に、チェーン式で型安全かつ補完が効く
- Python は関数型スタイル(
map(len, text.split()))で可読性は高いが、発見性や補完性で劣る
複雑なロジックにおける可読性
- Pythonの複雑な内包表記 は、ネストや条件式が増えると可読性が著しく低下
- 例:
len(list(filter(lambda line: ... , diffs)))のように括弧や条件の対応が分かりづらい
- 例:
- JavaScript では、
diffs.filter(...).lengthのように左から右へ意味が明確に伝わる- ロジックの流れが直線的で理解しやすい
結論:良いAPI設計の重要性
- プログラムは常に有効な状態であるべき という設計思想
- 入力途中でも型やメソッドが明確になり、エディタ補完やREPLでの即時確認が可能
- API設計 はユーザー体験を大きく左右
- 左から右へと構築できるAPIは、発見性・補完性・可読性が高い
- より良いAPIとエディタ体験 を目指すことの重要性