183 lines
4.9 KiB
Markdown
183 lines
4.9 KiB
Markdown
# Everything is Thread-Safe Box - 統一スレッドセーフ設計の可能性
|
||
|
||
作成日: 2025-08-26
|
||
|
||
## 🎯 革命的な気づき
|
||
|
||
「Everything is Box」なら「Everything is Thread-Safe」も統一的に実現できるのではないか?
|
||
|
||
## 🤔 なぜSmalltalkにはできなかったのか?
|
||
|
||
### Smalltalkの「すべてがオブジェクト」
|
||
- **設計時代**: 1970年代(主にシングルスレッド時代)
|
||
- **焦点**: オブジェクト指向の純粋性
|
||
- **並行性**: 後付けで追加(Semaphore, Mutex等)
|
||
- **統一性の欠如**: スレッドセーフは個別対応
|
||
|
||
### 時代背景の違い
|
||
```
|
||
1970年代: CPUは1コア、並行性は特殊用途
|
||
2020年代: マルチコアが標準、並行性は必須
|
||
```
|
||
|
||
### Nyashが今できる理由
|
||
1. **最初から並行性を前提に設計**
|
||
2. **Arc<Mutex>パターンの成熟**(Rust由来)
|
||
3. **BoxBase革命で統一実装済み**
|
||
4. **現代的なメモリモデルの理解**
|
||
|
||
## 💡 統一スレッドセーフBox設計
|
||
|
||
### 現在の実装(Phase 8.6で統一済み)
|
||
```rust
|
||
// BoxBase + BoxCoreで統一
|
||
pub struct BoxBase {
|
||
pub id: u64,
|
||
}
|
||
|
||
pub trait BoxCore: Send + Sync {
|
||
fn box_id(&self) -> u64;
|
||
fn fmt_box(&self, f: &mut fmt::Formatter) -> fmt::Result;
|
||
}
|
||
|
||
// 各Boxが個別にArc<Mutex>実装
|
||
pub struct IntegerBox {
|
||
base: BoxBase,
|
||
value: i64,
|
||
}
|
||
```
|
||
|
||
### 提案:統一スレッドセーフ層
|
||
```rust
|
||
// すべてのBoxの共通ラッパー
|
||
pub struct ThreadSafeBox<T: BoxCore> {
|
||
inner: Arc<Mutex<T>>,
|
||
base: BoxBase,
|
||
}
|
||
|
||
// 自動的にすべてがスレッドセーフに!
|
||
impl<T: BoxCore> ThreadSafeBox<T> {
|
||
pub fn new(value: T) -> Self {
|
||
Self {
|
||
inner: Arc::new(Mutex::new(value)),
|
||
base: BoxBase::new(),
|
||
}
|
||
}
|
||
|
||
pub fn with<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
|
||
let mut guard = self.inner.lock().unwrap();
|
||
f(&mut *guard)
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🚀 MIRレベルでの実装戦略
|
||
|
||
### 現在のMIR命令(26命令)
|
||
```rust
|
||
pub enum MirInstruction {
|
||
// Box操作
|
||
BoxNew { box_type: String, args: Vec<MirValue> },
|
||
BoxCall { target: MirValue, method: String, args: Vec<MirValue> },
|
||
// ...
|
||
}
|
||
```
|
||
|
||
### スレッドセーフ対応の追加
|
||
```rust
|
||
pub enum MirInstruction {
|
||
// 既存の命令...
|
||
|
||
// 並行性制御命令
|
||
BoxLock { target: MirValue }, // Mutex取得
|
||
BoxUnlock { target: MirValue }, // Mutex解放
|
||
BoxAtomicOp { op: AtomicOp }, // 原子操作
|
||
|
||
// 非同期実行
|
||
SpawnTask { body: Vec<MirInstruction> },
|
||
AwaitTask { task_id: MirValue },
|
||
}
|
||
```
|
||
|
||
### 最適化の可能性
|
||
```rust
|
||
// コンパイル時解析で不要なロックを削除
|
||
if is_single_threaded_context() {
|
||
// ロック命令をスキップ
|
||
} else {
|
||
// 通常のロック処理
|
||
}
|
||
```
|
||
|
||
## 🌟 実装の利点
|
||
|
||
### 1. 完全な初心者フレンドリー
|
||
```nyash
|
||
// ユーザーは何も意識しなくていい!
|
||
box Counter {
|
||
init { count }
|
||
|
||
increment() {
|
||
me.count = me.count + 1 // 自動的にスレッドセーフ!
|
||
}
|
||
}
|
||
|
||
// 複数スレッドから同時に呼んでも安全
|
||
async {
|
||
counter.increment()
|
||
}
|
||
```
|
||
|
||
### 2. データ競合の完全排除
|
||
- コンパイル時に保証
|
||
- 実行時エラーなし
|
||
- デッドロックの静的検出も可能?
|
||
|
||
### 3. 性能の予測可能性
|
||
- すべてのBox操作が同じコスト
|
||
- 最適化の余地も統一的
|
||
- プロファイリングが容易
|
||
|
||
## 📊 他言語との比較
|
||
|
||
| 言語 | すべてがオブジェクト | 統一スレッドセーフ | 備考 |
|
||
|------|---------------------|-------------------|------|
|
||
| Smalltalk | ✅ | ❌ | 後付けで個別対応 |
|
||
| Ruby | ✅ | ❌ | GIL(Global Interpreter Lock) |
|
||
| Python | ✅ | ❌ | GILで擬似的に実現 |
|
||
| Java | ✅ | ❌ | synchronized個別指定 |
|
||
| **Nyash** | ✅ | ✅ | 統一Box設計で可能! |
|
||
|
||
## 🔥 実装の課題と解決策
|
||
|
||
### 課題1: パフォーマンスオーバーヘッド
|
||
**解決**:
|
||
- エスケープ解析でローカル変数は最適化
|
||
- 読み取り専用アクセスは共有ロック(RwLock)
|
||
- インライン展開で小さな操作は最適化
|
||
|
||
### 課題2: デッドロックの可能性
|
||
**解決**:
|
||
- 型システムでロック順序を保証
|
||
- タイムアウト付きロック
|
||
- デバッグモードでデッドロック検出
|
||
|
||
### 課題3: 既存コードとの互換性
|
||
**解決**:
|
||
- 段階的移行(フラグで切り替え)
|
||
- 従来モードとの共存
|
||
- 明示的なunsafeブロック
|
||
|
||
## 🎯 結論
|
||
|
||
**Everything is Thread-Safe Box**は:
|
||
1. Smalltalkができなかった統一並行性モデル
|
||
2. BoxBase統一により実現可能性が高い
|
||
3. MIRレベルでの実装も設計可能
|
||
4. 初心者に優しく、かつ高性能
|
||
|
||
これは「GCをデバッグツールとして使う」に続く、Nyashの第二の革命的特徴になる可能性がある。
|
||
|
||
---
|
||
|
||
*「すべてが箱なら、すべてが安全」- 究極のスレッドセーフ言語への道* |