Files
hakorune/docs/private/papers/paper-m-method-postfix-catch/implementation-strategy.md

14 KiB
Raw Blame History

実装戦略 - メソッド後置例外処理

段階的実装ロードマップ

Phase 15.6: 段階的意思決定モデル(基盤確立)

目標

メソッドレベルでの段階的意思決定を可能にする catch/cleanup 構文を追加

核心概念:三段階意思決定

  1. Stage 1: 通常処理(メソッド本体)
  2. Stage 2: エラー処理catch ブロック)
  3. Stage 3: 最終調整cleanup ブロック)

構文設計

box StageDecisionBox {
    // ✅ 既存構文(互換維持)
    method traditional(arg) {
        return computation(arg)
    }
    
    // 🆕 段階的意思決定構文(安全モード)
    method safeStaged(arg) {
        return riskyOperation(arg)
    } catch (e) {
        me.logError(e)
        return defaultValue
    } cleanup {
        // リソース管理のみreturn禁止
        me.releaseResources()
    }
    
    // 🔥 段階的意思決定構文(表現モード)
    method expressiveStaged(arg) {
        return complexOperation(arg)
    } catch (e) {
        me.logError(e)
        return errorValue
    } cleanup returns {
        // 最終判断も可能return許可
        me.releaseResources()
        if me.detectSecurityThreat(arg) {
            return "SECURITY_BLOCKED"
        }
    }
}

技術的実装

パーサー拡張:

// src/parser/statements.rs に追加
fn parse_method_definition(&mut self) -> Result<ASTNode, ParseError> {
    // 既存のメソッドパース
    let method = self.parse_traditional_method()?;
    
    // 後置修飾子のチェック
    if self.current_token_is("catch") || self.current_token_is("cleanup") {
        let postfix = self.parse_method_postfix_modifiers()?;
        return Ok(ASTNode::MethodWithStaging { method, postfix });
    }
    
    Ok(method)
}

fn parse_method_postfix_modifiers(&mut self) -> Result<StagingModifiers, ParseError> {
    let mut catch_clause = None;
    let mut cleanup_clause = None;
    
    if self.consume_if("catch") {
        catch_clause = Some(self.parse_catch_clause()?);
    }
    
    if self.consume_if("cleanup") {
        // cleanup returns の検出
        let allow_returns = self.consume_if("returns");
        cleanup_clause = Some(self.parse_cleanup_clause(allow_returns)?);
    }
    
    Ok(StagingModifiers { catch_clause, cleanup_clause })
}

fn parse_cleanup_clause(&mut self, allow_returns: bool) -> Result<CleanupClause, ParseError> {
    let body = self.parse_block()?;
    
    // 安全性チェックcleanupreturnsなしでは return/throw を禁止
    if !allow_returns {
        self.validate_cleanup_safety(&body)?;
    }
    
    Ok(CleanupClause {
        body,
        allow_returns,
    })
}

fn validate_cleanup_safety(&self, block: &Block) -> Result<(), ParseError> {
    for stmt in &block.statements {
        match stmt {
            ASTNode::Return(_) => {
                return Err(ParseError::CleanupCannotReturn {
                    hint: "Use 'cleanup returns' if intentional final decision is needed"
                });
            }
            ASTNode::Throw(_) => {
                return Err(ParseError::CleanupCannotThrow {
                    hint: "cleanup blocks are for resource management only"
                });
            }
            _ => {}
        }
    }
    Ok(())
}

AST変換:

// メソッド後置をTryCatchに正規化
impl ASTNode {
    fn normalize_method_postfix(method: Method, postfix: PostfixModifiers) -> Method {
        Method {
            name: method.name,
            params: method.params,
            body: vec![ASTNode::TryCatch {
                try_body: method.body,
                catch_clauses: postfix.catch_clause.into_iter().collect(),
                finally_clause: postfix.finally_clause,
            }],
            return_type: method.return_type,
        }
    }
}

Bridge互換性:

  • 既存のResult-mode lowering完全再利用
  • ThrowCtx機構そのまま活用
  • PHI-off (edge-copy) 合流維持

仕様の明確化Phase 15.6

EBNF段階的意思決定構文

methodDecl := 'method' IDENT '(' params? ')' block stagingModifiers?

stagingModifiers := catchClause? cleanupClause?

catchClause := 'catch' '(' (IDENT IDENT | IDENT | ε) ')' block

cleanupClause := 'cleanup' cleanupMode block

cleanupMode := 'returns'     (* 表現モードreturn/throw許可 *)
             | ε             (* 安全モードreturn/throw禁止 *)

ゲート/フラグ

  • NYASH_STAGING_DECISION=1(または NYASH_PARSER_STAGE3=1 と同梱)
  • NYASH_CLEANUP_SAFETY_MODE=strict|permissive (デフォルト: strict)

段階実行順序(時系列的意思決定)

  1. Stage 1: メソッド本体実行
  2. Stage 2: 例外発生時は catch ブロック実行
  3. Stage 3: 常に cleanup ブロック実行(安全モードまたは表現モード)

優先順位(段階的エスカレーション)

  • メソッド本体内のブロック後置catchが存在する場合、そちらが優先最も近い境界が先
  • 次にメソッドレベルcatch、最後に呼出し側外側のcatchへ伝播
  • cleanup は常に最終段階で実行(例外の有無に関わらず)

スコープ/束縛

  • catch (e)e はcatchブロック内ローカル。メソッド本体スコープには漏れない
  • cleanup ブロックはメソッド本体の変数スコープにアクセス可能

cleanup 実行順序と安全性

  • 安全モード (cleanup): return/throw禁止、純粋リソース管理のみ
  • 表現モード (cleanup returns): 最終判断可能、return/throwで段階3の意思決定
  • cleanup 内の return は最終的な戻り値となるStage 3 の決定権)

オーバーライド/署名

  • メソッドレベルcatch/cleanup はシグネチャに影響しない(戻り値型/引数は従来通り)
  • cleanup returns の場合は事実上の意思決定権を持つが、型システム上は透明
  • 将来: 段階効果ビットstaged effectsを導入し、継承階層での安全性を静的検査

エラー規約

  • 複数catchはMVPでは非対応構文受理する場合でも最初のみ使用
  • 順序は catchcleanup のみ許可。逆順・重複は構文エラー
  • cleanupcleanup returns の混在は禁止(一意性の保証)

実装コスト

  • パーサー: 約100行追加
  • AST: 約50行追加
  • Lowering: 0行既存再利用
  • テスト: 約200行

期待効果

  • メソッド呼び出し側のtry-catch不要
  • リソース管理の自動化
  • エラー処理の統一化

Phase 16.1: メソッド後置定義(革新的構文)

目標

メソッドの処理内容を先に書き、署名を後置する構文

構文

box ModernBox {
    // 🚀 後置メソッド定義
    {
        local result = heavyComputation(arg)
        return optimize(result)
    } method process(arg): ResultBox
    
    {
        return me.field1 + me.field2
    } method getSum(): IntegerBox catch (e) {
        return 0
    }
}

技術的実装

パーサー拡張:

fn parse_box_member(&mut self) -> Result<ASTNode, ParseError> {
    if self.current_token_is("{") {
        // ブロックから開始 = 後置定義の可能性
        let block = self.parse_block()?;
        
        if self.current_token_is("method") {
            let method_sig = self.parse_method_signature()?;
            let postfix = self.parse_optional_postfix()?;
            
            return Ok(ASTNode::PostfixMethod {
                body: block,
                signature: method_sig,
                postfix,
            });
        }
        
        // 他の後置修飾子もチェック
        return self.parse_other_postfix_constructs(block);
    }
    
    // 従来構文
    self.parse_traditional_member()
}

EBNFブロック先行・メソッド後置

postfixMethod := block 'method' IDENT '(' params? ')' ( 'catch' '(' (IDENT IDENT | IDENT | ε) ')' block )? ( 'finally' block )?

先読み/二段化方針

  • } 後のトークンを先読みして method|as|catch|finally を判定。method の場合は署名を読み、既に取得した block を try_body として束ねる。
  • ブロック内で参照する引数名は「前方宣言」扱いとし、パーサ内部で仮束縛テーブルを用意して解決する(実装は二段正規化で可)。

実装コスト

  • パーサー: 約150行追加
  • AST正規化: 約100行
  • ドキュメント: 大幅更新

期待効果

  • 思考の自然な流れ(処理→署名)
  • 複雑なメソッドの可読性向上
  • コードレビューの効率化

Phase 16.2: 究極統一構文(哲学的完成)

目標

Everything is Block + Modifierの完全実現

構文

box UnifiedBox {
    // 🔥 Everything is Block + Modifier
    {
        return "Hello " + me.name
    } as field greeting: StringBox
    
    {
        return me.items.count()  
    } as property size: IntegerBox
    
    {
        return complexCalculation(arg)
    } as method compute(arg): ResultBox catch (e) {
        return ErrorResult(e)
    }
    
    {
        return asyncOperation()
    } as async method fetch(): FutureBox finally {
        me.closeConnections()
    }
}

技術的実装

統一パーサー:

enum BlockModifier {
    AsField { name: String, type_hint: Option<Type> },
    AsProperty { name: String, type_hint: Option<Type> },
    AsMethod { 
        name: String, 
        params: Vec<Parameter>,
        return_type: Option<Type>,
        is_async: bool,
    },
    WithCatch { param: Option<String>, body: Block },
    WithFinally { body: Block },
}

fn parse_block_with_modifiers(&mut self) -> Result<ASTNode, ParseError> {
    let block = self.parse_block()?;
    let mut modifiers = Vec::new();
    
    while let Some(modifier) = self.parse_optional_modifier()? {
        modifiers.push(modifier);
    }
    
    Ok(ASTNode::BlockWithModifiers { block, modifiers })
}

意味解析:

impl BlockWithModifiers {
    fn into_traditional_ast(self) -> Result<ASTNode, SemanticError> {
        match self.modifiers.primary_modifier() {
            BlockModifier::AsField { .. } => self.to_field(),
            BlockModifier::AsMethod { .. } => self.to_method(),
            BlockModifier::AsProperty { .. } => self.to_property(),
        }
    }
}

実装コスト

  • パーサー: 約300行大幅改造
  • 意味解析: 約200行
  • エラーメッセージ: 約100行
  • 移行ツール: 約500行

期待効果

  • データと振る舞いの完全統一
  • コンパイラ最適化の新機会
  • 言語学習コストの削減

互換性戦略

後方互換性の確保

box MixedBox {
    // ✅ 従来構文(永続サポート)
    field oldField: StringBox
    
    method oldMethod() {
        return traditional()
    }
    
    // ✅ 新構文(段階的導入)
    {
        return computed()
    } as field newField: StringBox
    
    method newMethod() {
        return modern()
    } catch (e) {
        return fallback()
    }
}

移行支援ツール

# 自動変換ツール
nyash-migrate --from traditional --to postfix src/

# 段階的移行
nyash-migrate --phase 15.6 src/  # メソッドレベルcatch/finally
nyash-migrate --phase 16.1 src/  # 後置定義
nyash-migrate --phase 16.2 src/  # 統一構文

性能への影響

実行時性能

  • 変化なし: AST正規化により従来と同じMIR生成
  • 最適化機会: 統一構文による新しい最適化パス

コンパイル時間

  • Phase 15.6: 影響なし(既存パス再利用)
  • Phase 16.1: +5-10%(パーサー複雑化)
  • Phase 16.2: +10-15%(意味解析追加)

メモリ使用量

  • AST: +10-15%(中間表現の追加)
  • 実行時: 変化なし同じMIR生成

テスト戦略

段階的テスト

# Phase 15.6 テスト
./test/method-postfix-catch/
├── basic-catch.nyash
├── basic-finally.nyash  
├── catch-and-finally.nyash
├── nested-methods.nyash
└── resource-management.nyash

# Phase 16.1 テスト  
./test/postfix-method-definition/
├── simple-postfix.nyash
├── complex-signature.nyash
├── with-catch.nyash
└── mixed-styles.nyash

# Phase 16.2 テスト
./test/unified-syntax/
├── field-method-property.nyash
├── async-methods.nyash
├── performance-comparison.nyash
└── migration-compatibility.nyash

回帰テストの確保

  • 全既存テストがPhase 15.6で継続PASS
  • 新構文と旧構文の等価性検証
  • パフォーマンス回帰の監視

リスク評価と対策

技術的リスク

  1. パーサー複雑化 → 段階的実装で複雑性管理
  2. エラーメッセージ → 専用のエラー報告機構
  3. IDE対応 → Language Server Protocol拡張

採用リスク

  1. 学習コスト → 段階的導入と豊富なドキュメント
  2. コミュニティ分裂 → 互換性維持と移行支援
  3. ツール対応 → 既存ツールとの互換性確保

対策

  • 保守的ロールアウト: 各フェーズで十分な検証期間
  • フィードバック収集: ベータユーザーからの積極的意見収集
  • フォールバック計画: 問題発生時の迅速な巻き戻し手順

成功指標

技術指標

  • 全既存テストがPASS100%
  • 新構文テストカバレッジ95%+
  • パフォーマンス劣化なし±3%以内)
  • コンパイル時間増加最小(+15%以下)

利用指標

  • メソッドレベル例外処理の採用率50%+
  • 後置定義構文の採用率30%+
  • 統一構文の採用率20%+
  • 開発者満足度向上Survey

影響指標

  • 例外関連バグの削減30%+
  • コードレビュー時間短縮20%+
  • 新規開発者の学習時間短縮25%+
  • 他言語からの影響検証(学術追跡)

最終更新: 2025年9月18日 実装責任者: ChatGPT (基盤実装) + 段階的拡張チーム 状態: Phase 15.6実装準備完了、Phase 16.x設計完了