Files
hakorune/docs/private/roadmap/language-evolution/discoverability-analysis.md

380 lines
9.5 KiB
Markdown
Raw Normal View History

# 🔍 Hakorune 機能発見性Discoverability問題の深層分析
**問題**: ChatGPTですら、こんな冗長コードを書いてしまう
```nyash
hex_digit(ch) {
if ch == "0" { return 0 }
if ch == "1" { return 1 }
if ch == "2" { return 2 }
// ... 続く16行
}
```
**本来あるべき姿**(既に実装済み機能で書ける):
```nyash
// 方法1: match式Phase 12.7実装済み)
hex_digit(ch) {
return match ch {
"0" => 0, "1" => 1, "2" => 2, "3" => 3,
"4" => 4, "5" => 5, "6" => 6, "7" => 7,
"8" => 8, "9" => 9, "a" => 10, "b" => 11,
"c" => 12, "d" => 13, "e" => 14, "f" => 15,
_ => 0
}
}
// 方法2: Mapリテラル実装済み
static box HexUtils {
hex_map: MapBox
birth() {
me.hex_map = new MapBox()
me.hex_map.set("0", 0)
me.hex_map.set("1", 1)
// ...
}
hex_digit(ch) {
return me.hex_map.get(ch)
}
}
// 方法3: indexOfStringBox実装済み
hex_digit(ch) {
local hex_chars = "0123456789abcdef"
return hex_chars.indexOf(ch)
}
```
---
## 📊 根本原因分析5つの問題
### **問題1: ドキュメント導線の弱さ**
**現状**:
```
docs/reference/language/LANGUAGE_REFERENCE_2025.md (1,500行)
機能は書いてある
でも「いつ使うか」が分からない
```
**不足している情報**:
- ❌ 「こういう場合はmatch式を使う」
- ❌ 「配列ルックアップ vs Map vs match の使い分け」
- ❌ 「Anti-Patternやってはいけない書き方
### **問題2: サンプルコード不足**
**現状**:
```
apps/examples/ ← 基本的なサンプルのみ
apps/tests/ ← テストケースはあるが学習用ではない
```
**不足**:
- ❌ Cookbook/Recipe集したい時は
- ❌ Best Practice集
- ❌ イディオム集(慣用句)
### **問題3: AI学習データの不足**
**現状**:
```
ChatGPT/Claudeの学習データ:
- JavaScript: 大量
- Python: 大量
- Rust: 中程度
- Nyash/Hakorune: ほぼゼロ
```
**結果**: JavaScriptパターンで書いてしまう
```javascript
// JavaScript風冗長
if (x == "a") return 1
if (x == "b") return 2
```
### **問題4: 糖衣構文の発見性**
**実装済みだが知られていない機能**:
- ✅ match式Phase 12.7
- ✅ Lambda式
- ✅ ?演算子Result伝播
- ✅ Mapリテラル
- ✅ 配列メソッドindexOf/find等
**問題**: 「機能がある」ことは分かっても、「いつ使うべきか」が分からない
### **問題5: Linter/Static Analysis不足**
**現状**: コード品質チェックがない
```nyash
// これを書いても警告が出ない(出るべき)
if ch == "0" { return 0 }
if ch == "1" { return 1 }
// ... 続く
```
**理想**: Linterが検出
```
Warning: Consider using match expression instead of if-else chain
→ Suggested refactoring:
match ch { "0" => 0, "1" => 1, ... }
```
---
## 🎯 解決策5つの柱
### **解決策1: Cookbook/Recipe集の作成** 🔴 最優先
**構成案**:
```markdown
docs/cookbook/
├── README.md
├── patterns/
│ ├── lookup-table.md # ルックアップテーブル実装
│ ├── string-parsing.md # 文字列解析
│ ├── error-handling.md # エラー処理パターン
│ └── collections.md # コレクション操作
├── anti-patterns/
│ ├── if-chain.md # if連鎖のアンチパターン
│ ├── manual-loop.md # 手動ループのアンチパターン
│ └── null-check.md # null チェックのアンチパターン
└── refactoring/
├── if-to-match.md # if → match変換
├── loop-to-map.md # ループ → map/filter変換
└── manual-to-builtin.md # 手動実装 → ビルトイン変換
```
**例**: `docs/cookbook/patterns/lookup-table.md`
```markdown
# ルックアップテーブルパターン
## ❌ Anti-Patternやってはいけない
```nyash
hex_digit(ch) {
if ch == "0" { return 0 }
if ch == "1" { return 1 }
// ... 冗長
}
```
## ✅ Pattern 1: match式推奨、シンプルなルックアップ
```nyash
hex_digit(ch) {
return match ch {
"0" => 0, "1" => 1, "2" => 2, ...
_ => 0
}
}
```
## ✅ Pattern 2: indexOf文字列ベース
```nyash
hex_digit(ch) {
return "0123456789abcdef".indexOf(ch)
}
```
## ✅ Pattern 3: MapBox複雑な値
```nyash
static box HexMap {
map: MapBox
birth() {
me.map = new MapBox()
me.map.set("zero", 0)
// ...
}
}
```
## 使い分け
- シンプルなルックアップ → match式
- 連続文字 → indexOf
- 複雑な値/初期化 → MapBox
```
---
### **解決策2: Quick Reference拡充** 🟡
**現状**: 文法中心
**改善**: Use Case中心に再構成
```markdown
# Use Case別 Quick Reference
## 文字列解析
- hex変換 → indexOf/match
- split → string.split()
- 正規表現 → RegexBox
## ルックアップ
- 固定値 → match
- 動的 → MapBox
- 連続 → indexOf
## 繰り返し処理
- 変換 → array.map()
- フィルタ → array.filter()
- 集約 → array.reduce()
```
---
### **解決策3: サンプルコード集の充実** 🟡
**追加すべきサンプル**:
```
apps/examples/
├── cookbook/
│ ├── hex_parser.hkr # hex解析の正しい書き方
│ ├── json_parser.hkr # JSON解析
│ ├── state_machine.hkr # ステートマシン
│ └── validator.hkr # バリデーション
├── best-practices/
│ ├── match_vs_if.hkr # match vs if使い分け
│ ├── map_vs_array.hkr # Map vs Array選択
│ └── error_handling.hkr # エラー処理パターン
└── anti-patterns/
├── if_chain_bad.hkr # ❌ 悪い例
└── if_chain_good.hkr # ✅ 良い例
```
---
### **解決策4: Linter/フォーマッター導入** 🟢
**Phase 18-20で実装検討**:
```bash
# Linter実行
$ hakorune lint my_code.hkr
Warning: Inefficient if-else chain detected
--> my_code.hkr:10:5
|
10 | if ch == "0" { return 0 }
11 | if ch == "1" { return 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^ Consider using match expression
|
= help: match ch { "0" => 0, "1" => 1, ... }
```
**検出すべきAnti-Pattern**:
1. If-else連鎖match式推奨
2. 手動ループmap/filter推奨
3. 未使用変数
4. 型不一致opt-in型チェック時
---
### **解決策5: AI学習用データ整備** 🟢
**コンテキスト注入用ファイル**:
```
docs/for-ai/
├── PATTERNS.md # 推奨パターン集
├── ANTI_PATTERNS.md # アンチパターン集
├── IDIOMS.md # 慣用句集
└── COMMON_MISTAKES.md # よくある間違い
```
**CLAUDE.mdに追加**:
```markdown
## 🤖 AI開発者への注意事項
### ❌ やってはいけないパターン
1. If-else連鎖 → match式を使う
2. 手動for文 → map/filter/reduce
3. null手動チェック → ?演算子
### ✅ 推奨パターン
1. ルックアップ → match/indexOf/MapBox
2. 変換 → array.map()
3. エラー処理 → Result + ?演算子
```
---
## 📅 実装優先順位
### **Phase 17即座** 🔴
1. **Cookbook/Recipe集作成**
- `docs/cookbook/patterns/lookup-table.md`
- `docs/cookbook/anti-patterns/if-chain.md`
- `docs/cookbook/refactoring/if-to-match.md`
2. **CLAUDE.md拡充**
- AI開発者への注意事項セクション追加
- よくあるアンチパターン明記
### **Phase 18-19** 🟡
3. **サンプルコード集**
- `apps/examples/cookbook/` 作成
- ベストプラクティス実装例
4. **Quick Reference再構成**
- Use Case中心に再編成
### **Phase 20-22** 🟢
5. **Linter/フォーマッター**
- Anti-Pattern検出
- 自動リファクタリング提案
---
## 🎯 期待される効果
### **短期効果Phase 17**
- ✅ AIChatGPT/Claudeがアンチパターンを避ける
- ✅ 新規開発者が正しい書き方を学べる
- ✅ コードレビュー時の指摘減少
### **中期効果Phase 18-19**
- ✅ サンプルコードからコピペで正しいコード
- ✅ 言語機能の利用率向上
- ✅ コード品質の一貫性向上
### **長期効果Phase 20-22**
- ✅ Linterが自動で品質保証
- ✅ リファクタリングが容易
- ✅ 技術的負債の削減
---
## 💡 名言化
> **「機能があっても、使われなければ意味がない」**
>
> Hakoruneは強力な機能を持つ。
> しかし、その使い方が伝わらなければ宝の持ち腐れ。
>
> **Cookbook/Recipe集で「発見性」を高める**ことが、
> 次のPhaseの最重要課題。
---
## 🎊 まとめ
ChatGPTが冗長なif連鎖を書いてしまった問題は、
**言語機能の不足ではなく、発見性Discoverabilityの問題**。
**解決策5本柱**:
1. 🔴 Cookbook/Recipe集作成Phase 17、最優先
2. 🟡 Quick Reference拡充Phase 17-18
3. 🟡 サンプルコード集Phase 18-19
4. 🟢 Linter/フォーマッターPhase 20-22
5. 🟢 AI学習用データ整備Phase 17-19
**Phase 17で即座に着手すべき**:
- `docs/cookbook/` ディレクトリ作成
- Anti-Pattern集の整備
- CLAUDE.mdへのAI開発者向け注意事項追加
これにより、「つよつよ機能」が「実際に使われる」ようになりますにゃ!