218 lines
8.7 KiB
Plaintext
218 lines
8.7 KiB
Plaintext
|
|
Nyashプログラミング言語のInstanceBox統一Factory設計について深い技術相談
|
|||
|
|
|
|||
|
|
【背景】
|
|||
|
|
Phase 9.78: 統合BoxFactoryアーキテクチャ実装中
|
|||
|
|
- ✅ 完了: ビルトインBox統合(StringBox, IntegerBox等)
|
|||
|
|
- 🎯 現在: ユーザー定義Box統合設計検討中
|
|||
|
|
- 目標: 「フローの上ではすべて同じ」統一美学の実現
|
|||
|
|
|
|||
|
|
【現在のアーキテクチャ】
|
|||
|
|
```rust
|
|||
|
|
// 統一インターフェース
|
|||
|
|
pub trait BoxFactory: Send + Sync {
|
|||
|
|
fn create_box(&self, name: &str, args: &[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, RuntimeError>;
|
|||
|
|
fn box_types(&self) -> Vec<&str>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 統一レジストリ
|
|||
|
|
pub struct UnifiedBoxRegistry {
|
|||
|
|
factories: Vec<Arc<dyn BoxFactory>>, // 優先順: builtin > user > plugin
|
|||
|
|
type_cache: RwLock<HashMap<String, usize>>,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
【設計目標】
|
|||
|
|
```rust
|
|||
|
|
// すべて同じフロー - Everything is Box哲学の実装レベル体現
|
|||
|
|
registry.create_box("StringBox", args) // → BuiltinBoxFactory
|
|||
|
|
registry.create_box("FileBox", args) // → PluginBoxFactory
|
|||
|
|
registry.create_box("MyUserBox", args) // → UserDefinedBoxFactory
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
【設計候補比較検討】
|
|||
|
|
|
|||
|
|
## **Option A: 動的Factory登録戦略(複数Factory責務分離)**
|
|||
|
|
|
|||
|
|
**1. UserDefinedBoxFactory設計:**
|
|||
|
|
```rust
|
|||
|
|
pub struct UserDefinedBoxFactory {
|
|||
|
|
interpreter_ref: Weak<RefCell<NyashInterpreter>>, // 循環参照回避
|
|||
|
|
registered_types: RwLock<HashSet<String>>, // 動的登録済み型管理
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
impl BoxFactory for UserDefinedBoxFactory {
|
|||
|
|
fn create_box(&self, name: &str, args: &[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|||
|
|
// 1️⃣ box宣言取得
|
|||
|
|
let interpreter = self.interpreter_ref.upgrade().ok_or(...)?;
|
|||
|
|
let box_decl = interpreter.borrow().get_box_declaration(name)?;
|
|||
|
|
|
|||
|
|
// 2️⃣ InstanceBox作成(既存InstanceBox完全活用)
|
|||
|
|
let mut instance = InstanceBox::new(name, box_decl);
|
|||
|
|
|
|||
|
|
// 3️⃣ 継承チェーン処理(from Parent統合)
|
|||
|
|
if let Some(parent) = &box_decl.parent {
|
|||
|
|
self.handle_delegation_chain(&mut instance, parent, args)?;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 4️⃣ birth/pack/initライフサイクル(既存フロー完全活用)
|
|||
|
|
self.execute_constructor(&mut instance, args)?;
|
|||
|
|
|
|||
|
|
// 5️⃣ 統一インターフェースで返却
|
|||
|
|
Ok(Box::new(instance))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**2. 動的登録システム:**
|
|||
|
|
```rust
|
|||
|
|
impl NyashInterpreter {
|
|||
|
|
fn execute_box_declaration(&mut self, decl: &BoxDeclaration) {
|
|||
|
|
// box宣言の保存
|
|||
|
|
self.register_box_declaration(decl.name.clone(), decl.clone());
|
|||
|
|
|
|||
|
|
// 統合レジストリに動的登録
|
|||
|
|
let registry = get_global_unified_registry();
|
|||
|
|
registry.lock().unwrap().register_user_defined_type(decl.name.clone());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pub fn get_box_declaration(&self, name: &str) -> Option<&BoxDeclaration> {
|
|||
|
|
self.box_declarations.get(name)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**3. 統合レジストリ拡張:**
|
|||
|
|
```rust
|
|||
|
|
impl UnifiedBoxRegistry {
|
|||
|
|
pub fn register_user_defined_type(&mut self, type_name: String) {
|
|||
|
|
// UserDefinedBoxFactoryに型追加を通知
|
|||
|
|
if let Some(user_factory) = self.get_user_defined_factory() {
|
|||
|
|
user_factory.add_type(type_name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Option A メリット:**
|
|||
|
|
1. **責務分離**: 各Factory内で適切な実装(ビルトイン=直接生成、ユーザー=InstanceBox、プラグイン=FFI)
|
|||
|
|
2. **拡張性**: 新Factory種別の追加が容易
|
|||
|
|
3. **既存活用**: InstanceBox、birth/pack/init、継承システムを部分再利用
|
|||
|
|
|
|||
|
|
**Option A 課題:**
|
|||
|
|
1. **循環参照**: Factory→Interpreter→Registry→Factory の複雑な依存関係
|
|||
|
|
2. **ライフタイム**: Weak参照でのinterpreter_ref管理の複雑性
|
|||
|
|
3. **動的登録**: box宣言解析時の動的型登録の複雑性
|
|||
|
|
|
|||
|
|
## **Option B: InstanceBox統一Factory戦略(単一Factory完全統一)**
|
|||
|
|
|
|||
|
|
```rust
|
|||
|
|
/// すべてのBox型をInstanceBoxとして統一処理
|
|||
|
|
pub struct UnifiedInstanceBoxFactory {
|
|||
|
|
builtin_registry: HashMap<String, BuiltinCreator>,
|
|||
|
|
interpreter_context: Option<Weak<RefCell<NyashInterpreter>>>,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
impl BoxFactory for UnifiedInstanceBoxFactory {
|
|||
|
|
fn create_box(&self, name: &str, args: &[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|||
|
|
match self.determine_box_type(name) {
|
|||
|
|
BoxType::Builtin => {
|
|||
|
|
// ビルトインBoxもInstanceBoxでラップして統一
|
|||
|
|
let builtin_box = self.create_builtin_box(name, args)?;
|
|||
|
|
Ok(Box::new(InstanceBox::from_builtin(builtin_box)))
|
|||
|
|
},
|
|||
|
|
BoxType::UserDefined => {
|
|||
|
|
// ユーザー定義BoxをInstanceBoxとして作成
|
|||
|
|
let declaration = self.get_user_box_declaration(name)?;
|
|||
|
|
Ok(Box::new(InstanceBox::from_declaration(declaration, args)?))
|
|||
|
|
},
|
|||
|
|
BoxType::Plugin => {
|
|||
|
|
// プラグインBoxもInstanceBoxでラップ
|
|||
|
|
let plugin_box = self.create_plugin_box(name, args)?;
|
|||
|
|
Ok(Box::new(InstanceBox::from_plugin(plugin_box)))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
impl InstanceBox {
|
|||
|
|
/// ビルトインBoxからInstanceBox作成
|
|||
|
|
pub fn from_builtin(builtin: Box<dyn NyashBox>) -> Self {
|
|||
|
|
Self {
|
|||
|
|
box_type_name: builtin.type_name().to_string(),
|
|||
|
|
inner_value: Some(builtin),
|
|||
|
|
fields: HashMap::new(),
|
|||
|
|
methods: HashMap::new(),
|
|||
|
|
// ... 統一フィールド
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// ユーザー定義宣言からInstanceBox作成
|
|||
|
|
pub fn from_declaration(decl: &BoxDeclaration, args: &[Box<dyn NyashBox>]) -> Result<Self, RuntimeError> {
|
|||
|
|
let mut instance = Self::new(&decl.name);
|
|||
|
|
|
|||
|
|
// 1. 継承チェーン処理
|
|||
|
|
if let Some(parent) = &decl.parent {
|
|||
|
|
instance.setup_delegation_chain(parent)?;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. フィールド初期化
|
|||
|
|
for field in &decl.init_fields {
|
|||
|
|
instance.fields.insert(field.clone(), Box::new(NullBox::new()));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. メソッド登録
|
|||
|
|
for method in &decl.methods {
|
|||
|
|
instance.methods.insert(method.name.clone(), method.clone());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 4. birth/pack/initコンストラクタ実行
|
|||
|
|
instance.execute_constructor(args)?;
|
|||
|
|
|
|||
|
|
Ok(instance)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// プラグインBoxからInstanceBox作成
|
|||
|
|
pub fn from_plugin(plugin: Box<dyn NyashBox>) -> Self {
|
|||
|
|
Self {
|
|||
|
|
box_type_name: plugin.type_name().to_string(),
|
|||
|
|
inner_value: Some(plugin),
|
|||
|
|
plugin_wrapped: true,
|
|||
|
|
// ... 統一フィールド
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Option B メリット:**
|
|||
|
|
1. **完全統一**: すべてのBox型が同じInstanceBox経由で処理される
|
|||
|
|
2. **Everything is Box**: 哲学に最も忠実な実装
|
|||
|
|
3. **単純性**: 1つのFactoryですべて処理、理解しやすい
|
|||
|
|
4. **一貫性**: ビルトイン・ユーザー定義・プラグインが完全に同じフロー
|
|||
|
|
5. **拡張性**: 新Box種別も同じInstanceBoxパターン
|
|||
|
|
|
|||
|
|
**Option B 課題:**
|
|||
|
|
1. **InstanceBox肥大化**: すべてを扱うため複雑になる可能性
|
|||
|
|
2. **パフォーマンス**: ビルトインBoxもラップすることのオーバーヘッド
|
|||
|
|
3. **既存互換**: 現在のInstanceBox実装との整合性
|
|||
|
|
|
|||
|
|
【深い比較質問】
|
|||
|
|
1. **設計哲学**: Option AとOption B、どちらがNyashの「Everything is Box」哲学により適合しますか?
|
|||
|
|
2. **実装複雑性**: 循環参照を持つOption Aと、InstanceBox統一のOption B、どちらが保守しやすいですか?
|
|||
|
|
3. **パフォーマンス**: Option BのビルトインBoxラッピングのオーバーヘッドは許容範囲ですか?
|
|||
|
|
4. **拡張性**: 将来の新Box種別追加において、どちらのアプローチが柔軟ですか?
|
|||
|
|
5. **既存互換**: 現在のInstanceBox実装と最も整合性が取れるのはどちらですか?
|
|||
|
|
6. **コードの美しさ**: 「上からフローが綺麗に分かれる」観点でどちらが優れていますか?
|
|||
|
|
7. **他の選択肢**: これら以外にさらに優れた第三の設計アプローチはありますか?
|
|||
|
|
|
|||
|
|
【特に重要な判断ポイント】
|
|||
|
|
- Option Aは「責務分離」を重視(各Factory専門化)
|
|||
|
|
- Option Bは「統一性」を重視(すべてInstanceBox経由)
|
|||
|
|
- どちらがNyashの長期的な設計により適合するか?
|
|||
|
|
|
|||
|
|
【Nyashの設計哲学】
|
|||
|
|
- Everything is Box: すべてがBoxオブジェクト
|
|||
|
|
- 明示性重視: 隠れた魔法的動作を避ける
|
|||
|
|
- 安全性優先: Rust実装によるメモリ安全性
|
|||
|
|
- 統一性重視: 一貫したインターフェース設計
|
|||
|
|
|
|||
|
|
専門的な視点から、この設計の妥当性と改善点について詳細に分析してください。
|