# 開発プラクティス ## 🔍 技術判断の鉄則 ### アーキテクチャ質問への対処手順 1. **実証ファイル確認**: `file app`, `nm app`, `ls target/` 2. **既存コード確認**: 関連ソース読み取り 3. **仮説検証**: 推測でなく実証ベース 4. **結論**: 確認済み事実のみ回答 ### よくある質問の実証方法 - **JIT/LLVMのABI**: → `file string_len_app` でELF確認 - **MIR命令数**: → `grep "enum MirInstructionKind" src/mir/*.rs` - **プラグイン実装**: → `ls plugins/*/target/release/` - **C ABI統一**: → `nm app | grep nyash` でシンボル確認 ## 🏗️ 設計原則 ### 📦 Everything is Box - 内部実装でも箱原理を貫く #### 1. **単一責任の箱** ```rust // ✅ 良い例:各モジュールが単一の責任を持つ MirBuilder: AST → MIR変換のみ(最適化しない) MirOptimizer: MIRの最適化のみ(変換しない) VM: 実行のみ(最適化しない) // ❌ 悪い例:複数の責任が混在 BuilderOptimizer: 変換も最適化も実行も... ``` #### 2. **明確なインターフェース** ```rust // ✅ エフェクトは単純に enum Effect { Pure, // 副作用なし ReadOnly, // 読み取りのみ SideEffect // 書き込み/IO/例外 } // ❌ 複雑な組み合わせは避ける PURE.add(IO) // これがpureかどうか分からない! ``` #### 3. **段階的な処理パイプライン** ``` AST → Builder → MIR → Optimizer → VM ↑ ↑ ↑ ↑ ↑ 明確な入力 明確な出力 不変保証 最適化のみ 実行のみ ``` ### 🎯 カプセル化の徹底 #### 1. **内部状態を隠蔽** ```rust // ✅ 良い例:内部実装を隠す pub struct MirOptimizer { debug: bool, // 設定のみ公開 enable_typeop_net: bool, // 設定のみ公開 // 内部の複雑な状態は隠蔽 } impl MirOptimizer { pub fn new() -> Self { ... } pub fn with_debug(self) -> Self { ... } pub fn optimize(&mut self, module: &mut MirModule) { ... } } ``` #### 2. **変更の局所化** - 新機能追加時:1つのモジュールのみ変更 - バグ修正時:影響範囲が明確 - テスト:各モジュール独立でテスト可能 ### 🌟 美しさの基準 #### 1. **読みやすさ > 賢さ** ```rust // ✅ 単純で分かりやすい if effect == Effect::Pure { can_eliminate = true; } // ❌ 賢いが分かりにくい can_eliminate = effect.0 & 0x01 == 0x01 && !(effect.0 & 0xFE); ``` #### 2. **一貫性** - 命名規則の統一 - エラー処理の統一 - コメントスタイルの統一 ### 🚀 大規模化への備え #### 1. **モジュール分割の原則** ``` src/ ├── ast/ # AST定義のみ ├── parser/ # パース処理のみ ├── mir/ # MIR定義と基本操作 │ ├── builder.rs # AST→MIR変換 │ └── optimizer.rs # MIR最適化 ├── backend/ # 実行バックエンド │ ├── interpreter.rs # インタープリター │ ├── vm.rs # VM実行 │ └── codegen_c.rs # C言語生成 ``` #### 2. **テストの階層化** - 単体テスト:各モジュール内で完結 - 統合テスト:モジュール間の連携 - E2Eテスト:全体の動作確認 #### 3. **設定の外部化** ```rust // ✅ フラグで挙動を制御(再コンパイル不要) optimizer.enable_typeop_safety_net(flag); // ❌ ハードコードされた挙動 #[cfg(feature = "typeop_safety_net")] ``` ### 💡 デバッグとメンテナンス #### 1. **段階的なデバッグ出力** ```bash NYASH_BUILDER_DEBUG=1 # Builder のみ NYASH_OPT_DEBUG=1 # Optimizer のみ NYASH_VM_DEBUG=1 # VM のみ ``` #### 2. **問題の早期発見** - 各段階でのアサーション - 不変条件の明示的チェック - 診断機能の組み込み ### 🎭 複雑さの管理 **複雑さは避けられないが、管理はできる** 1. 複雑な部分を局所化 2. インターフェースは単純に 3. ドキュメントで意図を明示 **判断基準:3ヶ月後の自分が理解できるか?** ## 🤝 プロアクティブ開発方針 ### 🎯 エラー対応時の姿勢 エラーを見つけた際は、単に報告するだけでなく: 1. **🔍 原因分析** - エラーの根本原因を探る 2. **📊 影響範囲** - 他のコードへの影響を調査 3. **💡 改善提案** - 関連する問題も含めて解決策を提示 4. **🧹 機会改善** - デッドコード削除など、ついでにできる改善も実施 ### ⚖️ バランスの取り方 - **積極的に分析・提案**するが、最終判断はユーザーに委ねる - 「ChatGPTさんに任せてる」と言われても、分析結果は共有する - 複数のAIが協調する場合でも、各自の視点で価値を提供する ### 📝 例 ``` ❌ 受動的: 「エラーをファイルに出力しました」 ✅ 能動的: 「エラーをファイルに出力しました。主な原因は型の不一致(7箇所)で、 instance_id()のメソッド呼び出し修正で5つ解決できそうです。 また、関連してclone_boxの実装にも同様の問題を発見しました。」 ```