docs: reorganize into 説明書/予定/archive; update docs/README.md and CLAUDE.md; move root .nyash to local_tests; consolidate native-plan notes into README + archive
This commit is contained in:
547
docs/archive/GETTING_STARTED.md
Normal file
547
docs/archive/GETTING_STARTED.md
Normal file
@ -0,0 +1,547 @@
|
||||
# 🚀 Getting Started with Nyash - Practical Guide
|
||||
|
||||
**最終更新: 2025年8月8日**
|
||||
|
||||
## 🎯 5分でNyashを理解する
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく、シンプルで強力なプログラミング言語です。
|
||||
このガイドでは、実際にコードを書きながらNyashの機能を学んでいきます。
|
||||
|
||||
## ⚡ クイックスタート
|
||||
|
||||
### **1. 環境構築**
|
||||
```bash
|
||||
# リポジトリのクローン
|
||||
git clone [repository-url]
|
||||
cd nyash/nyash-rust
|
||||
|
||||
# ビルド
|
||||
cargo build
|
||||
|
||||
# 実行
|
||||
./target/debug/nyash your_program.nyash
|
||||
```
|
||||
|
||||
### **2. はじめてのNyashプログラム**
|
||||
`hello.nyash`を作成:
|
||||
```nyash
|
||||
print("Hello, Nyash World!")
|
||||
print("Everything is Box! 🎉")
|
||||
```
|
||||
|
||||
実行:
|
||||
```bash
|
||||
./target/debug/nyash hello.nyash
|
||||
```
|
||||
|
||||
出力:
|
||||
```
|
||||
Hello, Nyash World!
|
||||
Everything is Box! 🎉
|
||||
```
|
||||
|
||||
## 📚 基本構文チュートリアル
|
||||
|
||||
### **Step 1: 変数と初期化**
|
||||
```nyash
|
||||
# 🎯 新機能:初期化付き変数宣言
|
||||
local name = "Alice"
|
||||
local age = 25
|
||||
local height = 165.5
|
||||
local isStudent = true
|
||||
|
||||
print("Name: " + name)
|
||||
print("Age: " + age)
|
||||
print("Height: " + height)
|
||||
print("Student: " + isStudent)
|
||||
|
||||
# 複数変数の同時宣言・初期化
|
||||
local x = 10, y = 20, z = 30
|
||||
print("Sum: " + (x + y + z)) # 60
|
||||
|
||||
# 混合宣言(初期化あり・なし)
|
||||
local initialized = 42, uninitialized, another = "test"
|
||||
uninitialized = "assigned later"
|
||||
print("Values: " + initialized + ", " + uninitialized + ", " + another)
|
||||
```
|
||||
|
||||
### **Step 2: 演算子の使用**
|
||||
```nyash
|
||||
local a = 10
|
||||
local b = 3
|
||||
|
||||
# 算術演算子
|
||||
print("Addition: " + (a + b)) # 13
|
||||
print("Subtraction: " + (a - b)) # 7
|
||||
print("Multiplication: " + (a * b)) # 30
|
||||
print("Division: " + (a / b)) # 3.3333333333333335
|
||||
|
||||
# 論理演算子(自然言語ライク)
|
||||
local hasPermission = true
|
||||
local isLoggedIn = true
|
||||
local canAccess = hasPermission and isLoggedIn
|
||||
print("Can access: " + canAccess) # true
|
||||
|
||||
local isDenied = not canAccess
|
||||
print("Is denied: " + isDenied) # false
|
||||
|
||||
# 比較演算子
|
||||
print("a > b: " + (a > b)) # true
|
||||
print("a == b: " + (a == b)) # false
|
||||
```
|
||||
|
||||
### **Step 3: 制御構造**
|
||||
```nyash
|
||||
function testControlFlow() {
|
||||
local score = 85
|
||||
|
||||
# if文
|
||||
if score >= 90 {
|
||||
print("Grade: A")
|
||||
} else if score >= 80 {
|
||||
print("Grade: B") # これが実行される
|
||||
} else {
|
||||
print("Grade: C or below")
|
||||
}
|
||||
|
||||
# ループ(統一構文)
|
||||
local count = 0
|
||||
loop(count < 3) {
|
||||
print("Count: " + count)
|
||||
count = count + 1
|
||||
if count == 2 {
|
||||
print("Breaking at 2")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testControlFlow()
|
||||
```
|
||||
|
||||
### **Step 4: Box(クラス)の定義**
|
||||
```nyash
|
||||
box Person {
|
||||
init { name, age, email } # フィールド定義(カンマ必須!)
|
||||
|
||||
# コンストラクタ(引数サポート)
|
||||
Person(n, a, e) {
|
||||
me.name = n
|
||||
me.age = a
|
||||
me.email = e
|
||||
print("Person created: " + me.name)
|
||||
}
|
||||
|
||||
# メソッド
|
||||
introduce() {
|
||||
print("Hi, I'm " + me.name + ", age " + me.age)
|
||||
}
|
||||
|
||||
getInfo() {
|
||||
return me.name + " (" + me.age + ") - " + me.email
|
||||
}
|
||||
|
||||
# デストラクタ
|
||||
fini() {
|
||||
print("Person destroyed: " + me.name)
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
person = new Person("Bob", 30, "bob@example.com")
|
||||
person.introduce()
|
||||
print("Info: " + person.getInfo())
|
||||
```
|
||||
|
||||
## 🏭 実践例:Calculator アプリ
|
||||
|
||||
完全なCalculatorアプリを実装:
|
||||
|
||||
```nyash
|
||||
# 📱 Calculator App - Nyash版
|
||||
|
||||
box Calculator {
|
||||
init { history }
|
||||
|
||||
Calculator() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧮 Calculator initialized!")
|
||||
}
|
||||
|
||||
add(a, b) {
|
||||
local result = a + b
|
||||
me.addToHistory("ADD", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
subtract(a, b) {
|
||||
local result = a - b
|
||||
me.addToHistory("SUB", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
multiply(a, b) {
|
||||
local result = a * b
|
||||
me.addToHistory("MUL", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
divide(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero!")
|
||||
return 0
|
||||
}
|
||||
local result = a / b
|
||||
me.addToHistory("DIV", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
addToHistory(op, a, b, result) {
|
||||
local record = op + ": " + a + " " + op + " " + b + " = " + result
|
||||
me.history.push(record)
|
||||
}
|
||||
|
||||
showHistory() {
|
||||
print("📊 Calculation History:")
|
||||
local size = me.history.size()
|
||||
local i = 0
|
||||
loop(i < size) {
|
||||
print(" " + (i + 1) + ". " + me.history.get(i))
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧹 History cleared!")
|
||||
}
|
||||
}
|
||||
|
||||
# ✨ Calculator使用例
|
||||
calc = new Calculator()
|
||||
|
||||
print("=== Basic Operations ===")
|
||||
print("10 + 5 = " + calc.add(10, 5))
|
||||
print("10 - 3 = " + calc.subtract(10, 3))
|
||||
print("4 * 7 = " + calc.multiply(4, 7))
|
||||
print("15 / 3 = " + calc.divide(15, 3))
|
||||
print("10 / 0 = " + calc.divide(10, 0)) # ゼロ除算エラーテスト
|
||||
|
||||
print("")
|
||||
calc.showHistory()
|
||||
|
||||
print("")
|
||||
print("=== Complex Calculations ===")
|
||||
local complex1 = calc.add(calc.multiply(3, 4), calc.divide(20, 4))
|
||||
print("(3 * 4) + (20 / 4) = " + complex1)
|
||||
|
||||
calc.showHistory()
|
||||
```
|
||||
|
||||
## ⚡ 並行処理の実践
|
||||
|
||||
```nyash
|
||||
# 🚀 Parallel Processing Example
|
||||
|
||||
function heavyComputation(iterations) {
|
||||
print("⚙️ Starting computation with " + iterations + " iterations...")
|
||||
|
||||
local sum = 0
|
||||
local i = 0
|
||||
loop(i < iterations) {
|
||||
sum = sum + (i * i)
|
||||
i = i + 1
|
||||
|
||||
# 進捗表示(1000回毎)
|
||||
if (i % 1000) == 0 {
|
||||
print(" Progress: " + i + "/" + iterations)
|
||||
}
|
||||
}
|
||||
|
||||
print("✅ Computation completed: " + sum)
|
||||
return sum
|
||||
}
|
||||
|
||||
function parallelDemo() {
|
||||
print("🚀 Starting parallel computations...")
|
||||
|
||||
# 3つのタスクを並行実行
|
||||
future1 = nowait heavyComputation(5000)
|
||||
future2 = nowait heavyComputation(3000)
|
||||
future3 = nowait heavyComputation(4000)
|
||||
|
||||
print("⏳ All tasks started. Waiting for results...")
|
||||
|
||||
# 結果を待機して取得
|
||||
result1 = await future1
|
||||
result2 = await future2
|
||||
result3 = await future3
|
||||
|
||||
local total = result1 + result2 + result3
|
||||
print("🎉 All tasks completed!")
|
||||
print("Total sum: " + total)
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
# 実行
|
||||
parallelDemo()
|
||||
```
|
||||
|
||||
## 🏗️ Static Box(名前空間)の活用
|
||||
|
||||
```nyash
|
||||
# 🏗️ Utility Classes with Static Boxes
|
||||
|
||||
static box MathUtils {
|
||||
init { PI, E }
|
||||
|
||||
static {
|
||||
me.PI = 3.14159265359
|
||||
me.E = 2.71828182846
|
||||
}
|
||||
|
||||
square(x) {
|
||||
return x * x
|
||||
}
|
||||
|
||||
circleArea(radius) {
|
||||
return me.PI * me.square(radius)
|
||||
}
|
||||
|
||||
power(base, exp) {
|
||||
local result = 1
|
||||
local i = 0
|
||||
loop(i < exp) {
|
||||
result = result * base
|
||||
i = i + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
static box StringUtils {
|
||||
init { EMPTY }
|
||||
|
||||
static {
|
||||
me.EMPTY = ""
|
||||
}
|
||||
|
||||
reverse(str) {
|
||||
# 簡易的な実装例
|
||||
return "REVERSED:" + str
|
||||
}
|
||||
|
||||
isEmpty(str) {
|
||||
return str == me.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
print("π = " + MathUtils.PI)
|
||||
print("Circle area (r=5): " + MathUtils.circleArea(5))
|
||||
print("2^8 = " + MathUtils.power(2, 8))
|
||||
|
||||
print("Empty check: " + StringUtils.isEmpty(""))
|
||||
print("Reverse: " + StringUtils.reverse("Hello"))
|
||||
```
|
||||
|
||||
## 🐛 デバッグ機能の活用
|
||||
|
||||
```nyash
|
||||
# 🐛 Debug Features Showcase
|
||||
|
||||
box DebugExample {
|
||||
init { data, counter }
|
||||
|
||||
DebugExample() {
|
||||
me.data = "example"
|
||||
me.counter = 0
|
||||
}
|
||||
|
||||
process() {
|
||||
me.counter = me.counter + 1
|
||||
return "Processed #" + me.counter
|
||||
}
|
||||
}
|
||||
|
||||
function debuggingDemo() {
|
||||
# DebugBoxでトラッキング開始
|
||||
DEBUG = new DebugBox()
|
||||
DEBUG.startTracking()
|
||||
|
||||
print("🔍 Creating objects for debugging...")
|
||||
|
||||
# オブジェクトを作成してトラッキング
|
||||
obj1 = new DebugExample()
|
||||
obj2 = new DebugExample()
|
||||
|
||||
DEBUG.trackBox(obj1, "Primary Object")
|
||||
DEBUG.trackBox(obj2, "Secondary Object")
|
||||
|
||||
# 処理実行
|
||||
result1 = obj1.process()
|
||||
result2 = obj2.process()
|
||||
result3 = obj1.process()
|
||||
|
||||
print("Results: " + result1 + ", " + result2 + ", " + result3)
|
||||
|
||||
# デバッグレポート表示
|
||||
print("")
|
||||
print("=== Memory Report ===")
|
||||
print(DEBUG.memoryReport())
|
||||
|
||||
print("")
|
||||
print("=== Full Debug Dump ===")
|
||||
print(DEBUG.dumpAll())
|
||||
|
||||
# デバッグ情報をファイルに保存
|
||||
DEBUG.saveToFile("debug_output.txt")
|
||||
print("🎉 Debug information saved to debug_output.txt")
|
||||
}
|
||||
|
||||
debuggingDemo()
|
||||
```
|
||||
|
||||
## 📦 ファイル組織とモジュール
|
||||
|
||||
### **プロジェクト構造**
|
||||
```
|
||||
my_nyash_project/
|
||||
├── main.nyash # メインプログラム
|
||||
├── utils/
|
||||
│ ├── math.nyash # 数学ユーティリティ
|
||||
│ ├── string.nyash # 文字列ユーティリティ
|
||||
│ └── debug.nyash # デバッグ関数
|
||||
└── models/
|
||||
├── person.nyash # Personクラス
|
||||
└── calculator.nyash # Calculatorクラス
|
||||
```
|
||||
|
||||
### **main.nyash**
|
||||
```nyash
|
||||
# 📦 Module System Example
|
||||
|
||||
include "utils/math.nyash"
|
||||
include "utils/string.nyash"
|
||||
include "models/person.nyash"
|
||||
include "models/calculator.nyash"
|
||||
|
||||
function main() {
|
||||
print("🚀 Multi-module Nyash Application")
|
||||
|
||||
# 各モジュールの機能を使用
|
||||
person = new Person("Alice", 25, "alice@example.com")
|
||||
person.introduce()
|
||||
|
||||
calc = new Calculator()
|
||||
result = calc.add(10, 20)
|
||||
print("Calculation result: " + result)
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
## 🎯 ベストプラクティス
|
||||
|
||||
### **1. 変数命名**
|
||||
```nyash
|
||||
# ✅ Good
|
||||
local userName = "alice"
|
||||
local totalAmount = 1000
|
||||
local isComplete = true
|
||||
|
||||
# ❌ Avoid
|
||||
local x = "alice"
|
||||
local amt = 1000
|
||||
local flag = true
|
||||
```
|
||||
|
||||
### **2. Box設計**
|
||||
```nyash
|
||||
# ✅ Good: 明確な責任分離
|
||||
box UserAccount {
|
||||
init { username, email, balance }
|
||||
|
||||
UserAccount(u, e) {
|
||||
me.username = u
|
||||
me.email = e
|
||||
me.balance = 0
|
||||
}
|
||||
|
||||
deposit(amount) {
|
||||
me.balance = me.balance + amount
|
||||
}
|
||||
}
|
||||
|
||||
# ❌ Avoid: 責任の混在
|
||||
box EverythingBox {
|
||||
# 多すぎる責任を持たせない
|
||||
}
|
||||
```
|
||||
|
||||
### **3. エラーハンドリング**
|
||||
```nyash
|
||||
function safeOperation(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero")
|
||||
return 0
|
||||
}
|
||||
return a / b
|
||||
}
|
||||
```
|
||||
|
||||
### **4. パフォーマンス考慮**
|
||||
```nyash
|
||||
# ✅ 効率的:static box使用
|
||||
result = MathUtils.calculate(data)
|
||||
|
||||
# ✅ 効率的:初期化付き宣言
|
||||
local result = heavyCalculation(), cache = new MapBox()
|
||||
|
||||
# ⚠️ 注意:不要なオブジェクト生成を避ける
|
||||
loop(i < 1000) {
|
||||
# 毎回new しない設計を心がける
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 次のステップ
|
||||
|
||||
### **学習順序**
|
||||
1. ✅ **基本構文** - このガイドで完了
|
||||
2. **並行処理** - `test_async_*.nyash`を参考に
|
||||
3. **Static Box応用** - ユーティリティクラス作成
|
||||
4. **デバッグ技法** - DebugBox完全活用
|
||||
5. **アプリケーション開発** - 実践的なプロジェクト
|
||||
|
||||
### **サンプルプログラム**
|
||||
```bash
|
||||
# 実装済みサンプル
|
||||
./target/debug/nyash test_local_init.nyash # 初期化付き変数
|
||||
./target/debug/nyash app_dice_rpg.nyash # RPGバトルゲーム
|
||||
./target/debug/nyash app_statistics.nyash # 統計計算
|
||||
./target/debug/nyash test_async_parallel.nyash # 並行処理
|
||||
```
|
||||
|
||||
### **リファレンス**
|
||||
- `docs/LANGUAGE_OVERVIEW_2025.md` - 言語全体概要
|
||||
- `docs/TECHNICAL_ARCHITECTURE_2025.md` - 技術仕様
|
||||
- `CLAUDE.md` - 開発者向け詳細情報
|
||||
|
||||
## 🎉 おめでとうございます!
|
||||
|
||||
このガイドでNyashの主要機能を学習しました!
|
||||
|
||||
**習得内容:**
|
||||
- ✅ 基本構文(変数・演算子・制御構造)
|
||||
- ✅ Box(クラス)定義とオブジェクト指向
|
||||
- ✅ 並行処理・非同期プログラミング
|
||||
- ✅ Static Box・名前空間システム
|
||||
- ✅ デバッグ機能・開発支援ツール
|
||||
- ✅ 実践的なアプリケーション開発
|
||||
|
||||
**Nyashでプログラミングの新しい可能性を探究してください!** 🚀
|
||||
|
||||
---
|
||||
*Getting Started Guide v1.0*
|
||||
*Everything is Box - Start Simple, Think Big*
|
||||
332
docs/archive/LANGUAGE_OVERVIEW_2025.md
Normal file
332
docs/archive/LANGUAGE_OVERVIEW_2025.md
Normal file
@ -0,0 +1,332 @@
|
||||
# 🚀 Nyash Programming Language - Complete Overview 2025
|
||||
|
||||
**最終更新: 2025年8月8日**
|
||||
|
||||
## 📖 概要
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく革新的なプログラミング言語です。
|
||||
わずか数日の集中開発により、production-readyレベルの実用的プログラミング言語として完成しました。
|
||||
|
||||
## 🎯 核心哲学: "Everything is Box"
|
||||
|
||||
```nyash
|
||||
# すべてのデータがBoxとして統一的に表現される
|
||||
number = 42 # IntegerBox
|
||||
text = "hello" # StringBox
|
||||
flag = true # BoolBox
|
||||
array = new ArrayBox() # ArrayBox
|
||||
debug = new DebugBox() # DebugBox
|
||||
```
|
||||
|
||||
## ✅ 完全実装済み機能 (Production Ready)
|
||||
|
||||
### 🔧 **言語基盤**
|
||||
- **データ型**: StringBox, IntegerBox, BoolBox, ArrayBox, MapBox, NullBox
|
||||
- **演算子**: `+`, `-`, `*`, `/`, `not`, `and`, `or`, `==`, `!=`, `<`, `>`, `<=`, `>=`
|
||||
- **制御構文**: `if/else`, `loop(condition)`, `break`
|
||||
- **変数宣言**: `local x`, `local x = value`, `outbox x = value`
|
||||
|
||||
### 🎭 **オブジェクト指向**
|
||||
```nyash
|
||||
box MyClass {
|
||||
init { name, value }
|
||||
|
||||
MyClass(n, v) { # コンストラクタ引数サポート
|
||||
me.name = n
|
||||
me.value = v
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return me.value
|
||||
}
|
||||
}
|
||||
|
||||
# 継承とインターフェース
|
||||
box Child from Parent interface IComparable {
|
||||
# 実装...
|
||||
}
|
||||
```
|
||||
|
||||
### ⚡ **並行処理・非同期**
|
||||
```nyash
|
||||
# 真の非同期実行(別スレッド)
|
||||
future1 = nowait heavyComputation(50000)
|
||||
future2 = nowait heavyComputation(30000)
|
||||
|
||||
# await演算子で結果取得
|
||||
result1 = await future1
|
||||
result2 = await future2
|
||||
```
|
||||
|
||||
### 🏭 **Static Boxシステム**
|
||||
```nyash
|
||||
static box Math {
|
||||
init { PI, E }
|
||||
|
||||
static {
|
||||
me.PI = 3.14159
|
||||
me.E = 2.71828
|
||||
}
|
||||
|
||||
add(a, b) { return a + b }
|
||||
multiply(a, b) { return a * b }
|
||||
}
|
||||
|
||||
# シングルトン・名前空間として動作
|
||||
result = Math.add(10, 20) # 30
|
||||
pi = Math.PI # 3.14159
|
||||
```
|
||||
|
||||
### 💾 **メモリ管理**
|
||||
```nyash
|
||||
box Resource {
|
||||
init { handle }
|
||||
|
||||
fini() { # デストラクタ
|
||||
print("Resource cleaned up")
|
||||
}
|
||||
}
|
||||
|
||||
# 自動メモリ管理 + 明示的解放
|
||||
resource = new Resource()
|
||||
# スコープ終了時に自動的にfini()が呼ばれる
|
||||
```
|
||||
|
||||
### 🧪 **デバッグシステム**
|
||||
```nyash
|
||||
DEBUG = new DebugBox()
|
||||
DEBUG.startTracking()
|
||||
DEBUG.trackBox(myObject, "重要オブジェクト")
|
||||
print(DEBUG.memoryReport())
|
||||
DEBUG.saveToFile("debug.txt")
|
||||
```
|
||||
|
||||
### 📦 **モジュールシステム**
|
||||
```nyash
|
||||
include "math_utils.nyash" # ファイルインクルード
|
||||
include "graphics.nyash" # 機能の組み込み
|
||||
```
|
||||
|
||||
## 🎮 実装済みアプリケーション
|
||||
|
||||
### 1. **🎲 サイコロRPGバトルゲーム**
|
||||
- ターン制戦闘システム
|
||||
- クリティカルヒット・防御システム
|
||||
- リアルタイムHPバー表示
|
||||
- DebugBox戦闘ログ統合
|
||||
|
||||
### 2. **📊 統計計算アプリケーション**
|
||||
- 平均・分散・標準偏差計算
|
||||
- 三角関数・対数・指数関数
|
||||
- 数学的統計処理
|
||||
|
||||
### 3. **🧮 LISPインタープリター**
|
||||
- S式パーサー
|
||||
- ConsBox/SymbolBox実装
|
||||
- 動的評価エンジン
|
||||
- メタプログラミング実証
|
||||
|
||||
### 4. **⚡ 並行処理デモ**
|
||||
- マルチスレッド計算タスク
|
||||
- 進捗表示による並行動作の可視化
|
||||
- await演算子による結果統合
|
||||
|
||||
## 🌟 技術的革新
|
||||
|
||||
### 1. **GlobalBox革命**
|
||||
従来のスコープチェーン概念を廃止し、GlobalBox単一管理システムを実現:
|
||||
- すべてのグローバル関数/変数がGlobalBoxで管理
|
||||
- `local`変数による一時的スコープ
|
||||
- メモリ効率30%改善
|
||||
|
||||
### 2. **SharedState非同期アーキテクチャ**
|
||||
```rust
|
||||
pub struct SharedState {
|
||||
global_box: Arc<Mutex<InstanceBox>>,
|
||||
box_declarations: Arc<RwLock<HashMap<String, BoxDeclaration>>>,
|
||||
static_functions: Arc<RwLock<HashMap<String, HashMap<String, ASTNode>>>>,
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **Everything is Box統一性**
|
||||
- TypeBox: 型情報もBoxとして表現
|
||||
- MethodBox: 関数ポインタ・イベントハンドラー実現
|
||||
- DebugBox: デバッグ情報の統一管理
|
||||
|
||||
## 📋 構文仕様書
|
||||
|
||||
### **変数宣言**
|
||||
```nyash
|
||||
# 基本宣言
|
||||
local x, y, z
|
||||
|
||||
# 初期化付き宣言(2025年8月8日実装完了)
|
||||
local result = 10 + 20
|
||||
local name = "Hello" + " World"
|
||||
local a = 100, b = 200, c = 300
|
||||
|
||||
# 混合宣言
|
||||
local init = 42, uninit, another = "test"
|
||||
|
||||
# outbox変数(static関数内で所有権移転)
|
||||
outbox product = new Item()
|
||||
```
|
||||
|
||||
### **制御構文**
|
||||
```nyash
|
||||
# 条件分岐
|
||||
if condition {
|
||||
# 処理
|
||||
} else {
|
||||
# else処理
|
||||
}
|
||||
|
||||
# ループ(統一構文)
|
||||
loop(condition) {
|
||||
# ループ本体
|
||||
if exitCondition {
|
||||
break
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **演算子**
|
||||
```nyash
|
||||
# 算術演算子
|
||||
result = a + b - c * d / e
|
||||
|
||||
# 論理演算子(キーワード版推奨)
|
||||
canAccess = level >= 5 and hasKey
|
||||
canEdit = isAdmin or (isModerator and hasPermission)
|
||||
isInvalid = not (input and verified)
|
||||
|
||||
# 比較演算子
|
||||
equal = (a == b)
|
||||
different = (x != y)
|
||||
greater = (score > threshold)
|
||||
```
|
||||
|
||||
### **Box定義**
|
||||
```nyash
|
||||
box ClassName from ParentClass interface IInterface {
|
||||
init { field1, field2, field3 } # カンマ必須!
|
||||
|
||||
# コンストラクタ
|
||||
ClassName(param1, param2) {
|
||||
me.field1 = param1
|
||||
me.field2 = param2
|
||||
me.field3 = calculateDefault()
|
||||
}
|
||||
|
||||
# メソッド
|
||||
methodName(params) {
|
||||
return me.field1 + params
|
||||
}
|
||||
|
||||
# デストラクタ
|
||||
fini() {
|
||||
print("Cleanup: " + me.field1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Static Box**
|
||||
```nyash
|
||||
static box UtilityClass {
|
||||
init { CONSTANT1, CONSTANT2 }
|
||||
|
||||
static {
|
||||
me.CONSTANT1 = "value"
|
||||
me.CONSTANT2 = 42
|
||||
}
|
||||
|
||||
utilityMethod(param) {
|
||||
return param * me.CONSTANT2
|
||||
}
|
||||
}
|
||||
|
||||
# 使用法
|
||||
result = UtilityClass.utilityMethod(10)
|
||||
const = UtilityClass.CONSTANT1
|
||||
```
|
||||
|
||||
## 🚀 パフォーマンス特性
|
||||
|
||||
### **メモリ効率**
|
||||
- GlobalBox統一管理によるメモリ使用量削減
|
||||
- 自動参照カウント + 明示的デストラクタ
|
||||
- SharedState による効率的な並行処理
|
||||
|
||||
### **実行速度**
|
||||
- 変数解決アルゴリズム簡素化
|
||||
- コンパイル済みRustベースの高速実行
|
||||
- 並行処理によるCPUリソース最大活用
|
||||
|
||||
### **開発効率**
|
||||
- シンプルな構文による高い可読性
|
||||
- 包括的なDebugBox機能
|
||||
- "Everything is Box"による概念の統一性
|
||||
|
||||
## 🎯 言語の強み
|
||||
|
||||
### 1. **学習コストの低さ**
|
||||
- 統一された"Box"概念
|
||||
- 直感的なメソッド呼び出し
|
||||
- 自然言語に近い論理演算子
|
||||
|
||||
### 2. **実用性**
|
||||
- モダンな並行処理サポート
|
||||
- 堅牢なメモリ管理
|
||||
- 実際のアプリケーション開発可能
|
||||
|
||||
### 3. **拡張性**
|
||||
- モジュールシステム
|
||||
- 継承・インターフェースサポート
|
||||
- 外部ライブラリ統合準備完了
|
||||
|
||||
## 🔮 開発ロードマップ
|
||||
|
||||
### **Phase 3: 高度機能拡張**
|
||||
- ジェネリクス実行時特殊化完成
|
||||
- スレッドプール・タイムアウト機能
|
||||
- WebAssembly出力対応
|
||||
|
||||
### **Phase 4: エコシステム構築**
|
||||
- GUI フレームワーク(WindowBox等)
|
||||
- HTTP/ネットワークライブラリ
|
||||
- ファイルI/O・データベースアクセス
|
||||
|
||||
### **Phase 5: プロダクション対応**
|
||||
- パッケージマネージャー
|
||||
- IDE統合・Language Server
|
||||
- デバッガー・プロファイラー
|
||||
|
||||
## 📊 言語比較
|
||||
|
||||
| 機能 | Nyash | Python | JavaScript | Rust |
|
||||
|------|-------|--------|------------|------|
|
||||
| 学習コスト | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
|
||||
| 並行処理 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
||||
| メモリ安全性 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
||||
| 開発速度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
|
||||
| 実行速度 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
## 🎉 まとめ
|
||||
|
||||
Nyashは「Everything is Box」哲学により、シンプルさと強力さを両立した革新的プログラミング言語として完成しました。
|
||||
|
||||
**主要達成項目:**
|
||||
- ✅ 基本言語機能完備
|
||||
- ✅ オブジェクト指向完全サポート
|
||||
- ✅ 並行処理・非同期機能実装
|
||||
- ✅ Static Box・名前空間システム
|
||||
- ✅ 現代的構文(初期化付き変数宣言等)
|
||||
- ✅ 実用アプリケーション複数完成
|
||||
- ✅ 包括的デバッグ・開発支援機能
|
||||
|
||||
**Nyashは実験的言語から実用的プログラミング言語への転換を果たし、今後のさらなる進化への強固な基盤を確立しました。**
|
||||
|
||||
---
|
||||
*開発期間: 2025年8月6日-8日(わずか3日間での集中開発)*
|
||||
*開発者: Claude Code + 人間のコラボレーション*
|
||||
*哲学: "Everything is Box" - シンプルさの中に無限の可能性を*
|
||||
120
docs/archive/MAPBOX_HANG_BUG_REPORT.md
Normal file
120
docs/archive/MAPBOX_HANG_BUG_REPORT.md
Normal file
@ -0,0 +1,120 @@
|
||||
# MapBox 3引数メソッド呼び出しハングバグ レポート
|
||||
|
||||
## 🐛 バグ概要
|
||||
|
||||
**問題**: MapBoxオブジェクトを作成した後、3つ以上の引数を持つメソッド呼び出しでプログラムが無限ハングする
|
||||
|
||||
**影響範囲**: MapBox作成後の複雑なメソッド呼び出しチェーン全般
|
||||
|
||||
## 🔍 根本原因
|
||||
|
||||
### 問題のコード
|
||||
`src/interpreter/methods/collection_methods.rs:131-134`
|
||||
|
||||
```rust
|
||||
// 引数を評価
|
||||
let mut arg_values = Vec::new();
|
||||
for arg in arguments {
|
||||
arg_values.push(self.execute_expression(arg)?); // ← 全引数を事前評価
|
||||
}
|
||||
```
|
||||
|
||||
### 正常動作する他のBox(例:StringBox)
|
||||
`src/interpreter/methods/basic_methods.rs:27`
|
||||
|
||||
```rust
|
||||
let delimiter_value = self.execute_expression(&arguments[0])?; // ← 必要時に1つずつ評価
|
||||
```
|
||||
|
||||
## 📊 調査結果
|
||||
|
||||
### ハングするケース
|
||||
```nyash
|
||||
box MessageHub {
|
||||
init { handlers }
|
||||
|
||||
setup() {
|
||||
me.handlers = new MapBox() // ← MapBox作成
|
||||
}
|
||||
|
||||
deliver(messageType, data, from) {
|
||||
// 3引数メソッド呼び出し → ハング
|
||||
print("Message: " + from + " -> " + messageType + " = " + data)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 正常動作するケース
|
||||
```nyash
|
||||
// MapBoxを使用しない場合 → 正常
|
||||
// 2引数以下の場合 → 正常
|
||||
// MapBox作成前の3引数呼び出し → 正常
|
||||
```
|
||||
|
||||
## 🛠️ 修正方法
|
||||
|
||||
### 推奨修正内容
|
||||
`src/interpreter/methods/collection_methods.rs:128-145`を以下に変更:
|
||||
|
||||
```rust
|
||||
pub(in crate::interpreter) fn execute_map_method(&mut self, map_box: &MapBox, method: &str, arguments: &[ASTNode])
|
||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
|
||||
match method {
|
||||
"set" => {
|
||||
if arguments.len() != 2 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("set() expects 2 arguments, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
// 必要時評価
|
||||
let key_value = self.execute_expression(&arguments[0])?;
|
||||
let val_value = self.execute_expression(&arguments[1])?;
|
||||
Ok(map_box.set(key_value, val_value))
|
||||
}
|
||||
"get" => {
|
||||
if arguments.len() != 1 {
|
||||
return Err(RuntimeError::InvalidOperation {
|
||||
message: format!("get() expects 1 argument, got {}", arguments.len()),
|
||||
});
|
||||
}
|
||||
// 必要時評価
|
||||
let key_value = self.execute_expression(&arguments[0])?;
|
||||
Ok(map_box.get(key_value))
|
||||
}
|
||||
// 他のメソッドも同様に修正...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ✅ 期待効果
|
||||
|
||||
1. **ハング問題完全解決**: MapBox+3引数の組み合わせが正常動作
|
||||
2. **性能向上**: 不要な引数評価の排除
|
||||
3. **一貫性向上**: 他のBox型と同じ評価方式に統一
|
||||
|
||||
## 🧪 テスト計画
|
||||
|
||||
修正後、以下のテストケースで動作確認:
|
||||
|
||||
```nyash
|
||||
// テスト1: MapBox + 3引数メソッド呼び出し
|
||||
local hub = new MessageHub()
|
||||
hub.setup() // MapBox作成
|
||||
alice.send("hello", "Hi there!") // 3引数チェーン → 正常動作期待
|
||||
|
||||
// テスト2: 複雑なフィールドアクセス
|
||||
me.messageHub.deliver(messageType, data, me.nodeId) // 正常動作期待
|
||||
```
|
||||
|
||||
## 📝 補足
|
||||
|
||||
- **緊急度**: 高(基本的なMapBox機能が使用不能)
|
||||
- **回避策**: 2引数+Messageオブジェクト方式で一時対応可能
|
||||
- **互換性**: 修正は既存コードに影響なし(内部実装のみ変更)
|
||||
|
||||
---
|
||||
|
||||
**作成日**: 2025-01-09
|
||||
**調査者**: Claude Code Assistant
|
||||
**検証環境**: Nyash Rust Implementation
|
||||
254
docs/archive/P2P_IMPLEMENTATION_ISSUE.md
Normal file
254
docs/archive/P2P_IMPLEMENTATION_ISSUE.md
Normal file
@ -0,0 +1,254 @@
|
||||
# 🌐 P2PBox完全実装 - AI大会議仕様準拠
|
||||
|
||||
## 📋 Issue概要
|
||||
|
||||
**目標**: NyaMeshP2Pライブラリ実現のためのP2P通信システムを、AI大会議で決定した最新仕様に従って完全実装する
|
||||
|
||||
**重要**: 既存の `src/boxes/intent_box.rs` と `src/boxes/p2p_box.rs` は**古い設計**のため、**完全に作り直し**が必要
|
||||
|
||||
## 🎯 AI大会議決定事項
|
||||
|
||||
### ✅ 採用仕様
|
||||
- **構造化IntentBox**: `name` + `payload` 形式のメッセージBox
|
||||
- **個別送信のみ**: `send(to, message)` 固定API
|
||||
- **明示的デリゲーション**: `from Parent.method()` 統一構文
|
||||
|
||||
### ❌ 除外仕様
|
||||
- **ブロードキャスト**: 安全性のため完全除外(無限ループリスク回避)
|
||||
- **関数オーバーロード**: `send(a)` vs `send(a,b)` 分岐不採用
|
||||
|
||||
## 🏗️ 新アーキテクチャ設計
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
||||
│ P2PBox │◄──►│ MessageBus │◄──►│ Transport │
|
||||
│ (ユーザーAPI) │ │ (ローカル配送) │ │ (送受信層) │
|
||||
└─────────────┘ └──────────────┘ └─────────────┘
|
||||
▲ ▲ ▲
|
||||
│ │ │
|
||||
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
||||
│ IntentBox │ │ ハンドラ管理 │ │ InProcess │
|
||||
│ (構造化MSG) │ │ ノード登録 │ │ WebSocket │
|
||||
└─────────────┘ └──────────────┘ │ WebRTC │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## 📦 段階的実装計画
|
||||
|
||||
### 🎯 **Phase 1: 基盤実装**
|
||||
|
||||
#### **Step 1: IntentBox(構造化メッセージ)**
|
||||
**ファイル**: `src/boxes/intent_box.rs` (完全作り直し)
|
||||
|
||||
```rust
|
||||
// 新しいIntentBox設計
|
||||
pub struct IntentBoxData {
|
||||
pub name: String, // "chat.message", "file.share"等
|
||||
pub payload: serde_json::Value, // 任意のJSON data
|
||||
}
|
||||
pub type IntentBox = Arc<Mutex<IntentBoxData>>;
|
||||
```
|
||||
|
||||
**実装要件**:
|
||||
- Arc<Mutex>統一パターン準拠
|
||||
- BoxCore + NyashBox実装
|
||||
- serde_json::Value使用
|
||||
|
||||
**テストコード**:
|
||||
```nyash
|
||||
// tests/phase2/intent_box_test.nyash
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
local console = new ConsoleBox()
|
||||
console.log("Name: " + msg.name) // "chat.message"
|
||||
console.log("Text: " + msg.payload.text) // "Hello P2P!"
|
||||
```
|
||||
|
||||
#### **Step 2: MessageBus(プロセス内シングルトン)**
|
||||
**ファイル**: `src/messaging/message_bus.rs` (新規作成)
|
||||
|
||||
```rust
|
||||
pub struct MessageBusData {
|
||||
nodes: HashMap<String, BusEndpoint>, // ノード登録
|
||||
subscribers: HashMap<String, Vec<IntentHandler>>, // ハンドラー管理
|
||||
}
|
||||
pub type MessageBus = Arc<Mutex<MessageBusData>>;
|
||||
|
||||
impl MessageBusData {
|
||||
pub fn global() -> MessageBus // シングルトンアクセス
|
||||
pub fn register_node(&mut self, id: String, endpoint: BusEndpoint)
|
||||
pub fn route(&self, to: &str, intent: IntentBox) -> Result<(), SendError>
|
||||
}
|
||||
```
|
||||
|
||||
#### **Step 3: Transport trait(送受信抽象化)**
|
||||
**ファイル**: `src/transport/mod.rs` (新規作成)
|
||||
|
||||
```rust
|
||||
pub trait Transport: Send + Sync {
|
||||
fn node_id(&self) -> &str;
|
||||
fn send(&self, to: &str, intent: IntentBox, opts: SendOpts) -> Result<(), SendError>;
|
||||
fn on_receive(&mut self, callback: Box<dyn Fn(IntentEnvelope) + Send + Sync>);
|
||||
}
|
||||
```
|
||||
|
||||
### 🎯 **Phase 2: InProcess実装**
|
||||
|
||||
#### **Step 4: InProcessTransport**
|
||||
**ファイル**: `src/transport/inprocess.rs` (新規作成)
|
||||
|
||||
```rust
|
||||
pub struct InProcessTransport {
|
||||
node_id: String,
|
||||
bus: MessageBus, // MessageBus::global()を使用
|
||||
}
|
||||
|
||||
impl Transport for InProcessTransport {
|
||||
// Bus経由の高速ローカル配送実装
|
||||
}
|
||||
```
|
||||
|
||||
### 🎯 **Phase 3: P2PBox統合**
|
||||
|
||||
#### **Step 5: P2PBox基本実装**
|
||||
**ファイル**: `src/boxes/p2p_box.rs` (完全作り直し)
|
||||
|
||||
```rust
|
||||
pub struct P2PBoxData {
|
||||
node_id: String,
|
||||
transport: Arc<dyn Transport>,
|
||||
bus: MessageBus, // 全P2PBoxで共有
|
||||
}
|
||||
pub type P2PBox = Arc<Mutex<P2PBoxData>>;
|
||||
|
||||
impl P2PBoxData {
|
||||
pub fn new(node_id: String, kind: TransportKind) -> P2PBox
|
||||
pub fn on(&self, intent_name: &str, handler: IntentHandler) -> Result<(), P2PError>
|
||||
pub fn send(&self, to: &str, intent: IntentBox) -> Result<(), SendError>
|
||||
// ブロードキャストメソッドは実装しない
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 包括的テスト要件
|
||||
|
||||
### **基本動作テスト**
|
||||
**ファイル**: `test_p2p_basic_new.nyash`
|
||||
|
||||
```nyash
|
||||
// 2つのノード作成
|
||||
local node_a = new P2PBox("alice", transport: "inprocess")
|
||||
local node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// 受信ハンドラ設定
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
local console = new ConsoleBox()
|
||||
console.log("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// メッセージ送信
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // → "From alice: Hello P2P!"
|
||||
```
|
||||
|
||||
### **エラーハンドリングテスト**
|
||||
```nyash
|
||||
// 存在しないノードへの送信
|
||||
local result = node_a.send("nonexistent", msg)
|
||||
// → SendError::NodeNotFound
|
||||
|
||||
// 不正なIntentBox
|
||||
local invalid_msg = "not an IntentBox"
|
||||
local result = node_a.send("bob", invalid_msg)
|
||||
// → 型エラー
|
||||
```
|
||||
|
||||
### **パフォーマンステスト**
|
||||
```nyash
|
||||
// 大量メッセージ送信テスト
|
||||
local start_time = new TimeBox()
|
||||
loop(i < 1000) {
|
||||
local msg = new IntentBox("test.performance", { id: i })
|
||||
node_a.send("bob", msg)
|
||||
i = i + 1
|
||||
}
|
||||
local end_time = new TimeBox()
|
||||
// 実行時間計測
|
||||
```
|
||||
|
||||
## 📁 必要なディレクトリ構成
|
||||
|
||||
```
|
||||
src/
|
||||
├── boxes/
|
||||
│ ├── intent_box.rs # 完全作り直し
|
||||
│ └── p2p_box.rs # 完全作り直し
|
||||
├── messaging/ # 新規作成
|
||||
│ └── message_bus.rs # MessageBus実装
|
||||
└── transport/ # 新規作成
|
||||
├── mod.rs # Transport trait
|
||||
└── inprocess.rs # InProcessTransport
|
||||
```
|
||||
|
||||
## 🔧 実装時の重要注意点
|
||||
|
||||
### **Arc<Mutex>統一パターン厳守**
|
||||
```rust
|
||||
// ✅ 正しい統一パターン
|
||||
pub type IntentBox = Arc<Mutex<IntentBoxData>>;
|
||||
pub type MessageBus = Arc<Mutex<MessageBusData>>;
|
||||
pub type P2PBox = Arc<Mutex<P2PBoxData>>;
|
||||
|
||||
// ❌ 避けるべき
|
||||
pub struct IntentBox { ... } // Arcなし
|
||||
```
|
||||
|
||||
### **BoxCore実装必須**
|
||||
```rust
|
||||
impl BoxCore for IntentBox {
|
||||
fn box_id(&self) -> u64 { self.lock().unwrap().base.id }
|
||||
fn parent_type_id(&self) -> Option<TypeId> { None }
|
||||
fn fmt_box(&self, f: &mut fmt::Formatter) -> fmt::Result { ... }
|
||||
fn as_any(&self) -> &dyn Any { self }
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any { self }
|
||||
}
|
||||
```
|
||||
|
||||
### **エラーハンドリング設計**
|
||||
```rust
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SendError {
|
||||
NodeNotFound(String), // 宛先ノードが見つからない
|
||||
NetworkError(String), // ネットワークエラー
|
||||
SerializationError(String), // JSON変換エラー
|
||||
BusError(String), // MessageBusエラー
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 成功の定義
|
||||
|
||||
以下のテストが全て通過すること:
|
||||
|
||||
1. **基本通信**: ノード間でIntentBoxメッセージ送受信
|
||||
2. **ハンドラ登録**: `on()` でイベントリスナー正常動作
|
||||
3. **エラーハンドリング**: 不正な送信先・データで適切エラー
|
||||
4. **パフォーマンス**: 1000メッセージ/秒以上の送信性能
|
||||
5. **メモリ安全性**: valgrind等でメモリリーク検出なし
|
||||
|
||||
## 📚 参考ドキュメント
|
||||
|
||||
- **[P2P_GUIDE.md](docs/P2P_GUIDE.md)** - 設計詳細・使用例
|
||||
- **[CURRENT_TASK.md](CURRENT_TASK.md)** - 実装状況・優先順位
|
||||
- **[ai_conference_overload_decision.md](ai_conference_overload_decision.md)** - AI大会議決定事項
|
||||
- **[docs/reference/override-delegation-syntax.md](docs/reference/override-delegation-syntax.md)** - デリゲーション構文仕様
|
||||
|
||||
## 🚀 実装開始
|
||||
|
||||
**Priority**: High
|
||||
**Assignee**: Copilot
|
||||
**Labels**: enhancement, p2p, breaking-change
|
||||
**Milestone**: P2P Phase 2 Complete
|
||||
|
||||
**最初に取り組むべき**: Step 1 IntentBox の完全作り直し
|
||||
|
||||
---
|
||||
|
||||
🎉 **この実装により、Nyashは本格的なP2P通信システムを持つ現代的プログラミング言語になります!**
|
||||
314
docs/archive/README.ja.md
Normal file
314
docs/archive/README.ja.md
Normal file
@ -0,0 +1,314 @@
|
||||
# 🐱 Nyash プログラミング言語
|
||||
**次世代ブラウザーネイティブ開発体験**
|
||||
|
||||
*[🇺🇸 English Version / 英語版はこちら](README.md)*
|
||||
|
||||
[](#)
|
||||
[](#philosophy)
|
||||
[](#webassembly)
|
||||
[](https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html)
|
||||
[](#license)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **今すぐNyashを体験!**
|
||||
|
||||
**インストール不要、設定不要 - ブラウザーを開くだけ!**
|
||||
|
||||
👉 **[🎮 Nyashブラウザープレイグラウンド起動](https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html)** 👈
|
||||
|
||||
体験できる機能:
|
||||
- 🎨 **アーティスト協同制作デモ** - 複数Boxインスタンスの連携
|
||||
- ⚡ **非同期計算処理** - シンプルな並列処理
|
||||
- 🎮 **Canvas ゲームグラフィック** - ブラウザーでの直接グラフィック描画
|
||||
- 🔍 **ライブデバッグ可視化** - プログラムのメモリ状態をリアルタイム表示
|
||||
|
||||
---
|
||||
|
||||
## ✨ **Nyashが革命を起こす理由**
|
||||
|
||||
### 🎯 **メモリ安全性の革命**
|
||||
```nyash
|
||||
// 従来の言語: 手動メモリ管理、クラッシュ、セキュリティ問題
|
||||
// Nyash: Everything is Box - 自動的、安全、エレガント
|
||||
|
||||
static box Main {
|
||||
init { player, enemies, canvas }
|
||||
|
||||
main() {
|
||||
me.player = new PlayerBox("勇者", 100)
|
||||
me.canvas = new WebCanvasBox("game", 800, 600)
|
||||
|
||||
// メモリは自動管理 - クラッシュなし、メモリリークなし!
|
||||
me.player.render(me.canvas)
|
||||
return "ゲーム安全実行中!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🌐 **ブラウザーファースト設計**
|
||||
- **ゼロインストール**: WebAssembly経由でWebブラウザーで直接実行
|
||||
- **Web API内蔵**: Canvas、DOM、ストレージ - すべてが言語ネイティブ機能
|
||||
- **リアルタイム協業**: コードを即座に共有、どこでも実行
|
||||
- **モバイル対応**: スマートフォン、タブレット、すべての現代デバイスで動作
|
||||
|
||||
### 🎨 **創作プログラミングが簡単に**
|
||||
```nyash
|
||||
// コードでアートを作る - 自然に!
|
||||
box Artist {
|
||||
init { name, color }
|
||||
|
||||
paintMasterpiece(canvas) {
|
||||
canvas.fillCircle(100, 100, 50, me.color)
|
||||
canvas.fillText("Art by " + me.name, 10, 200, "24px Arial", me.color)
|
||||
}
|
||||
}
|
||||
|
||||
// 複数のアーティストが協力
|
||||
picasso = new Artist("ピカソ", "red")
|
||||
monet = new Artist("モネ", "blue")
|
||||
// 各Boxが独自の状態と動作を維持!
|
||||
```
|
||||
|
||||
### ⚡ **非同期処理の簡潔性**
|
||||
```nyash
|
||||
// 複雑さなしの並列処理
|
||||
nowait future1 = heavyComputation(10000)
|
||||
nowait future2 = renderGraphics()
|
||||
|
||||
// 実行中に他の作業を...
|
||||
setupUI()
|
||||
|
||||
// 準備ができたら結果を取得
|
||||
result1 = await future1
|
||||
result2 = await future2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ **革命的アーキテクチャ**
|
||||
|
||||
### Everything is Box 哲学
|
||||
Nyashのすべての値は **Box** - 統一された、メモリ安全なコンテナです:
|
||||
|
||||
| 従来の言語 | Nyash |
|
||||
|-----------|-------|
|
||||
| `int x = 42;` | `x = new IntegerBox(42)` |
|
||||
| `string name = "Hello";` | `name = new StringBox("Hello")` |
|
||||
| 複雑なcanvas設定 | `canvas = new WebCanvasBox("game", 800, 600)` |
|
||||
| 手動メモリ管理 | 自動Boxライフサイクル管理 |
|
||||
|
||||
### Static Box Main パターン
|
||||
```nyash
|
||||
// クリーンで予測可能なプログラム構造
|
||||
static box Main {
|
||||
init { database, ui, gameState } // すべてのフィールドを事前宣言
|
||||
|
||||
main() {
|
||||
// 論理的順序で初期化
|
||||
me.database = new DatabaseBox("save.db")
|
||||
me.ui = new UIManagerBox()
|
||||
me.gameState = new GameStateBox()
|
||||
|
||||
// プログラムロジックここに
|
||||
return runGameLoop()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 視覚的デバッグ統合
|
||||
```nyash
|
||||
debug = new DebugBox()
|
||||
debug.startTracking()
|
||||
|
||||
player = new PlayerBox("勇者")
|
||||
debug.trackBox(player, "メインキャラクター")
|
||||
|
||||
// ブラウザーでリアルタイムメモリ可視化!
|
||||
print(debug.memoryReport()) // ライブ統計、デバッグ地獄なし
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎮 **創作コーディングに最適**
|
||||
|
||||
### ゲーム開発
|
||||
- **内蔵Canvas API**: 外部ライブラリなしでグラフィック
|
||||
- **入力ハンドリング**: マウス、キーボード、タッチ - すべてネイティブ
|
||||
- **オーディオサポート**: 音楽と効果音用のSoundBox
|
||||
- **物理準備済み**: 数学演算最適化
|
||||
|
||||
### 教育的プログラミング
|
||||
- **視覚的フィードバック**: コードの効果を即座に確認
|
||||
- **メモリ可視化**: プログラムの動作を理解
|
||||
- **設定バリアなし**: 学生はブラウザーで即座にコーディング
|
||||
- **段階的学習**: 簡単なスクリプトから複雑なアプリケーションまで
|
||||
|
||||
### Webアプリケーション
|
||||
- **直接DOM制御**: WebDisplayBoxでHTML操作
|
||||
- **フレームワーク不要**: 言語がネイティブでWeb相互作用を処理
|
||||
- **リアルタイム更新**: 変更が即座に反映
|
||||
- **クロスプラットフォーム**: 同じコード、どこでも
|
||||
|
||||
---
|
||||
|
||||
## 📖 **言語の特徴**
|
||||
|
||||
### クリーンで表現力豊かな構文
|
||||
```nyash
|
||||
// 自然なオブジェクト指向プログラミング
|
||||
box Player {
|
||||
init { name, health, inventory }
|
||||
|
||||
Player(playerName) {
|
||||
me.name = playerName
|
||||
me.health = 100
|
||||
me.inventory = new ArrayBox()
|
||||
}
|
||||
|
||||
takeDamage(amount) {
|
||||
me.health = me.health - amount
|
||||
if me.health <= 0 {
|
||||
me.respawn()
|
||||
}
|
||||
}
|
||||
|
||||
respawn() {
|
||||
me.health = 100
|
||||
print(me.name + " がリスポーンしました!")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 強力な演算子
|
||||
```nyash
|
||||
// 明確性のための自然言語演算子
|
||||
isAlive = health > 0 and not poisoned
|
||||
canCast = mana >= spellCost or hasItem("魔法の指輪")
|
||||
gameOver = playerDead or timeUp
|
||||
|
||||
// 内蔵数学演算
|
||||
distance = sqrt((x2 - x1)^2 + (y2 - y1)^2)
|
||||
angle = atan2(deltaY, deltaX)
|
||||
```
|
||||
|
||||
### ジェネリックプログラミング
|
||||
```nyash
|
||||
// 型安全なジェネリックコンテナ
|
||||
box Container<T> {
|
||||
init { value }
|
||||
|
||||
Container(item) { me.value = item }
|
||||
getValue() { return me.value }
|
||||
}
|
||||
|
||||
numbers = new Container<IntegerBox>(42)
|
||||
texts = new Container<StringBox>("こんにちは")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ **使い始める**
|
||||
|
||||
### ブラウザー開発(推奨)
|
||||
```bash
|
||||
# 1. リポジトリクローン
|
||||
git clone https://github.com/moe-charm/nyash.git
|
||||
cd nyash
|
||||
|
||||
# 2. WebAssemblyバージョンビルド
|
||||
cd projects/nyash-wasm
|
||||
./build.sh
|
||||
|
||||
# 3. ブラウザーでプレイグラウンドを開く
|
||||
# 任意の現代ブラウザーでnyash_playground.htmlを開く
|
||||
```
|
||||
|
||||
### ネイティブ開発
|
||||
|
||||
#### 🐧 Linux/WSL
|
||||
```bash
|
||||
# ネイティブバージョンビルド
|
||||
cargo build --release
|
||||
|
||||
# プログラムをローカルで実行
|
||||
./target/release/nyash program.nyash
|
||||
|
||||
# 例を試す
|
||||
./target/release/nyash test_async_demo.nyash
|
||||
./target/release/nyash app_dice_rpg.nyash
|
||||
```
|
||||
|
||||
#### 🪟 Windows版 (クロスコンパイル)
|
||||
```bash
|
||||
# クロスコンパイラーインストール
|
||||
cargo install cargo-xwin
|
||||
|
||||
# Windows実行ファイルビルド
|
||||
cargo xwin build --target x86_64-pc-windows-msvc --release
|
||||
|
||||
# 生成された実行ファイル (916KB)
|
||||
target/x86_64-pc-windows-msvc/release/nyash.exe
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **対象ユーザー**
|
||||
|
||||
- 🎨 **クリエイター**: アーティスト、ゲーム開発者
|
||||
- 🎓 **教育者**: プログラミング講師、学生
|
||||
- 🌐 **Web開発者**: インタラクティブコンテンツ制作者
|
||||
- 🔬 **研究者**: 新しいプログラミングパラダイムの探求者
|
||||
|
||||
---
|
||||
|
||||
## 🤝 **貢献**
|
||||
|
||||
Nyashはオープンソースで、貢献を歓迎しています!
|
||||
|
||||
- **Issues**: バグ報告、機能リクエスト
|
||||
- **Pull Requests**: コード改善、新しい例
|
||||
- **ドキュメント**: ガイドと例の改善支援
|
||||
- **コミュニティ**: Nyash作品を共有!
|
||||
|
||||
## 📄 **ライセンス**
|
||||
|
||||
MIT ライセンス - 個人および商用利用無料。
|
||||
|
||||
---
|
||||
|
||||
## 🔗 **リンク**
|
||||
|
||||
- **[🎮 今すぐ試す - ブラウザープレイグラウンド](https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html)**
|
||||
- **[📚 ドキュメント](docs/)**
|
||||
- **[🎯 例](examples/)**
|
||||
- **[💬 コミュニティディスカッション](https://github.com/moe-charm/nyash/discussions)**
|
||||
|
||||
## 👨💻 **作者**
|
||||
|
||||
**Moe Charm** - プログラミング言語デザイナー・開発者
|
||||
- 🐙 GitHub: [@moe-charm](https://github.com/moe-charm)
|
||||
- 🐦 Twitter/X: [@CharmNexusCore](https://x.com/CharmNexusCore)
|
||||
- ☕ 開発サポート: [coff.ee/moecharmde6](http://coff.ee/moecharmde6)
|
||||
|
||||
*AI支援と献身的開発で革新的プログラミング言語を創造 🤖*
|
||||
|
||||
---
|
||||
|
||||
## 🤖 **プロジェクトのサポート**
|
||||
|
||||
Nyashは最先端のAI協業で開発されています!
|
||||
|
||||
継続的な開発をサポートしたい場合:
|
||||
|
||||
**☕ [開発サポート](http://coff.ee/moecharmde6)** - イノベーションの燃料を!
|
||||
|
||||
*Claude Code による支援 - 高度なAI開発ツールは無料ではありません! 🤖*
|
||||
|
||||
あなたのサポートはプロジェクトの維持、新機能の開発、プログラミング言語設計の境界を押し広げることに役立ちます。すべての貢献が違いを生みます! 🙏
|
||||
|
||||
---
|
||||
|
||||
*❤️、🤖 Claude Code、そしてEverything is Box哲学で構築*
|
||||
|
||||
**Nyash - すべての値がBoxであり、すべてのBoxが物語を語る場所。**
|
||||
97
docs/archive/README.md
Normal file
97
docs/archive/README.md
Normal file
@ -0,0 +1,97 @@
|
||||
# 📚 Nyash Documentation
|
||||
|
||||
**NyashプログラミングLexicalAnalyzer言語の公式ドキュメント** | 最終更新: 2025-08-12
|
||||
|
||||
---
|
||||
|
||||
## 🚀 すぐ始める
|
||||
|
||||
### 👶 **初心者向け**
|
||||
- **[Getting Started](GETTING_STARTED.md)** - 環境構築から最初のプログラムまで
|
||||
|
||||
### 📖 **言語を学ぶ**
|
||||
- **[Language Guide](LANGUAGE_GUIDE.md)** - 言語仕様・構文・完全ガイド
|
||||
|
||||
### 🌐 **P2P通信**
|
||||
- **[P2P Guide](P2P_GUIDE.md)** - P2P通信システム完全ガイド
|
||||
|
||||
---
|
||||
|
||||
## 📋 詳細リファレンス
|
||||
|
||||
### **[reference/](reference/)**
|
||||
- **[language-reference.md](reference/language-reference.md)** - 言語仕様完全リファレンス
|
||||
- **[override-delegation-syntax.md](reference/override-delegation-syntax.md)** - デリゲーション・override構文仕様
|
||||
- **[design-philosophy.md](reference/design-philosophy.md)** - 明示的デリゲーション革命の設計思想
|
||||
- **[builtin-boxes.md](reference/builtin-boxes.md)** - ビルトインBox型詳細リファレンス
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ 過去資料・開発履歴
|
||||
|
||||
### **[archive/](archive/)**
|
||||
- **[development/](archive/development/)** - 過去のドキュメント・開発履歴
|
||||
- **[p2p/](archive/p2p/)** - P2P詳細設計書・AI相談記録
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Nyashとは
|
||||
|
||||
**「Everything is Box」哲学**に基づく革新的プログラミング言語
|
||||
|
||||
```nyash
|
||||
// シンプルで強力な構文
|
||||
local greeting = "Hello, Nyash!"
|
||||
print(greeting)
|
||||
|
||||
// すべてがBox - 統一された美しい世界
|
||||
local numbers = new ArrayBox()
|
||||
numbers.push(42)
|
||||
numbers.push(3.14)
|
||||
|
||||
// P2P通信もBox!
|
||||
local node = new P2PBox("alice", transport: "inprocess")
|
||||
node.send("bob", new IntentBox("chat", { text: "Hello P2P!" }))
|
||||
```
|
||||
|
||||
### ✨ **主な特徴**
|
||||
- **🔧 Production Ready**: Phase 1完了、実用レベルの言語機能
|
||||
- **🌐 P2P Native**: P2P通信がビルトイン (Phase 2実装中)
|
||||
- **🛡️ Memory Safe**: Rust実装による完全メモリ安全性
|
||||
- **📦 Everything is Box**: 統一されたオブジェクトモデル
|
||||
- **⚡ Simple & Powerful**: 学習コストが低く、表現力が高い
|
||||
|
||||
### 📊 **実装状況 (2025-08-12)**
|
||||
|
||||
#### ✅ **Phase 1完了**
|
||||
- FloatBox, ArrayBox改良, Cross-type演算子
|
||||
- 包括的テストスイート (188行)
|
||||
- デリゲーション革命 (`from`構文完成)
|
||||
|
||||
#### 🚧 **Phase 2実装中**
|
||||
- IntentBox (構造化メッセージ)
|
||||
- P2PBox (P2P通信ノード)
|
||||
- MessageBus (プロセス内シングルトン)
|
||||
|
||||
#### 🎯 **最終目標**
|
||||
**NyaMeshP2Pライブラリ実現** - Nyash言語による本格的P2P通信ライブラリ
|
||||
|
||||
---
|
||||
|
||||
## 🤝 コミュニティ
|
||||
|
||||
### 開発方針
|
||||
- **ドキュメントファースト**: ソースより先にドキュメント確認
|
||||
- **AI協働開発**: Gemini先生・ChatGPT先生・Copilot連携
|
||||
- **段階的実装**: Phase 1→2→3の確実な進歩
|
||||
|
||||
### 貢献方法
|
||||
1. **Issue報告**: バグ・要望をGitHub Issuesで報告
|
||||
2. **ドキュメント改善**: typo修正・内容追加のPull Request歓迎
|
||||
3. **コード貢献**: 新機能実装・バグ修正のPull Request歓迎
|
||||
|
||||
---
|
||||
|
||||
**🎉 Welcome to the world of "Everything is Box"!**
|
||||
|
||||
*Nyashで新しいプログラミングの世界を体験しよう!*
|
||||
103
docs/archive/ai_conference_overload_decision.md
Normal file
103
docs/archive/ai_conference_overload_decision.md
Normal file
@ -0,0 +1,103 @@
|
||||
# 🎊 AI大会議決定: 関数オーバーロード不採用 + ブロードキャスト除外
|
||||
|
||||
**日時**: 2025-08-12
|
||||
**参加**: Gemini先生・ChatGPT先生
|
||||
**議題**: Nyash P2PBox における関数オーバーロード採用可否
|
||||
|
||||
---
|
||||
|
||||
## 🏆 **最終決定**
|
||||
|
||||
### ❌ **関数オーバーロード不採用**
|
||||
- `send(a)` `send(a,b)` のような引数数による分岐は実装しない
|
||||
- 理由: Nyashの「明示性重視」哲学と矛盾、初学者混乱、実装複雑化
|
||||
|
||||
### ❌ **ブロードキャスト機能除外**
|
||||
- `broadcast(message)` 機能は実装しない
|
||||
- 理由: ネットワーク負荷・セキュリティリスク・初学者誤用防止
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **確定API仕様**
|
||||
|
||||
### ✅ **最終P2PBox API** (ブロードキャスト除外版)
|
||||
```nyash
|
||||
// 基本の個別送信(必須)
|
||||
node.send("bob", message)
|
||||
|
||||
// オプション付き個別送信(将来実装)
|
||||
node.send_with_options("bob", message, opts)
|
||||
```
|
||||
|
||||
### **使用例**
|
||||
```nyash
|
||||
// 基本使用
|
||||
local node_a = new P2PBox("alice", transport: "inprocess")
|
||||
local node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// 受信ハンドラ
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
print("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// 個別送信のみ
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // ✅ 個別送信
|
||||
// node_a.broadcast(msg) // ❌ ブロードキャストは存在しない
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎓 **AI両先生の見解**
|
||||
|
||||
### **Gemini先生**
|
||||
- **結論**: オーバーロード不採用
|
||||
- **理由**: 「明示性は最高の利便性」、初学者混乱防止
|
||||
- **推奨**: 明示的メソッド名分離
|
||||
|
||||
### **ChatGPT先生**
|
||||
- **結論**: オーバーロード不採用
|
||||
- **理由**: 技術実装複雑化、Arc<Mutex>との不整合
|
||||
- **推奨**: Rust単一backend + 明示的API
|
||||
|
||||
### **ブロードキャスト除外理由** (実戦経験に基づく重要判断)
|
||||
|
||||
**🚨 実体験による重要な教訓:**
|
||||
- **C++ nyameshでの悪夢**: AIが無意識にブロードキャストを使用
|
||||
- **無限ループ地獄**: sendデータがばらまかれ、反射して無限ループ発生
|
||||
- **何度も経験**: この問題を繰り返し体験した深刻な実害
|
||||
|
||||
**📋 技術的除外理由:**
|
||||
1. **無限ループリスク**: ブロードキャストデータの反射による暴走
|
||||
2. **P2P本質**: P2P通信は本来1対1が基本、ブロードキャスト不要
|
||||
3. **後付け可能**: 必要になったら最後に安全に追加可能
|
||||
4. **初学者保護**: 危険な機能による事故防止
|
||||
5. **AIセーフティ**: AI使用時の予期しない暴走防止
|
||||
|
||||
---
|
||||
|
||||
## 🌟 **この決定の価値**
|
||||
|
||||
### **Nyashアイデンティティ確立**
|
||||
- **明示性重視**: 何が起こるかが明確
|
||||
- **初学者ファースト**: 混乱のない学習体験
|
||||
- **安全性優先**: 危険な機能は除外
|
||||
- **シンプル美**: 必要十分な機能のみ
|
||||
|
||||
### **技術的優位性**
|
||||
- **実装シンプル**: 保守しやすいコード
|
||||
- **Rust整合性**: 言語実装との自然な統合
|
||||
- **Arc<Mutex>最適化**: 統一アーキテクチャとの親和性
|
||||
- **現代的設計**: Go・Rustと同じ先進路線
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **次のアクション**
|
||||
|
||||
1. **P2P_GUIDE.md確認**: ブロードキャスト言及の除去確認
|
||||
2. **LANGUAGE_GUIDE.md更新**: AI大会議結果反映
|
||||
3. **P2PBox実装開始**: 確定仕様でIntentBox実装開始
|
||||
|
||||
---
|
||||
|
||||
**🎉 「便利な悪魔の誘惑を退け、真の明示性を選択」 - Nyashの哲学勝利!**
|
||||
41
docs/archive/build_error.txt
Normal file
41
docs/archive/build_error.txt
Normal file
@ -0,0 +1,41 @@
|
||||
P2PBox ビルドエラー詳細 (2025-08-11)
|
||||
=====================================
|
||||
|
||||
エラー概要:
|
||||
- ライブラリのビルド: ✅ 成功
|
||||
- テストの実行: ✅ 成功
|
||||
- nyashバイナリのビルド: ❌ モジュールインポートエラー
|
||||
|
||||
エラー詳細:
|
||||
|
||||
error[E0432]: unresolved imports `crate::Transport`, `crate::TransportKind`, `crate::create_transport`
|
||||
--> src/boxes/p2p_box.rs:16:13
|
||||
|
|
||||
16 | use crate::{Transport, TransportKind, create_transport};
|
||||
| ^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ no `create_transport` in the root
|
||||
| | |
|
||||
| | no `TransportKind` in the root
|
||||
| no `Transport` in the root
|
||||
|
||||
error[E0432]: unresolved imports `crate::get_global_message_bus`, `crate::BusMessage`, `crate::MessageBus`
|
||||
--> src/boxes/p2p_box.rs:17:13
|
||||
|
|
||||
17 | use crate::{get_global_message_bus, BusMessage, MessageBus};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ no `MessageBus` in the root
|
||||
|
||||
error[E0432]: unresolved import `crate::TransportKind`
|
||||
--> src/interpreter/objects.rs:13:5
|
||||
|
|
||||
13 | use crate::TransportKind;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ no `TransportKind` in the root
|
||||
|
||||
解決案:
|
||||
1. src/boxes/p2p_box.rs でインポートパスを修正:
|
||||
use crate::transport_trait::{Transport, TransportKind, create_transport};
|
||||
use crate::message_bus::{get_global_message_bus, BusMessage, MessageBus};
|
||||
|
||||
2. src/interpreter/objects.rs でインポートパスを修正:
|
||||
use crate::transport_trait::TransportKind;
|
||||
|
||||
これは単純なモジュールパスの問題で、機能的な問題ではありません。
|
||||
P2PBoxの実装自体は完全に動作しています。
|
||||
328
docs/archive/build_errors.txt
Normal file
328
docs/archive/build_errors.txt
Normal file
@ -0,0 +1,328 @@
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad.rs` found to be present in multiple build targets:
|
||||
* `bin` target `simple_notepad`
|
||||
* `example` target `simple_notepad`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_explorer_with_icons.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_explorer_icons`
|
||||
* `example` target `nyash_explorer_with_icons`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_notepad_jp.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad_jp`
|
||||
* `example` target `nyash_notepad_jp`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad_v2.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad`
|
||||
* `example` target `simple_notepad_v2`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad_ascii.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad_ascii`
|
||||
* `example` target `simple_notepad_ascii`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/test_icon_extraction.rs` found to be present in multiple build targets:
|
||||
* `bin` target `test_icon_extraction`
|
||||
* `example` target `test_icon_extraction`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_explorer.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_explorer`
|
||||
* `example` target `nyash_explorer`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/debug_notepad.rs` found to be present in multiple build targets:
|
||||
* `bin` target `debug_notepad`
|
||||
* `example` target `debug_notepad`
|
||||
Checking nyash-rust v0.1.0 (/mnt/c/git/nyash-project/nyash)
|
||||
warning: unused import: `Display`
|
||||
--> src/boxes/buffer/mod.rs:35:23
|
||||
|
|
||||
35 | use std::fmt::{Debug, Display};
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: unused import: `std::future::Future`
|
||||
--> src/boxes/future/mod.rs:7:5
|
||||
|
|
||||
7 | use std::future::Future;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::pin::Pin`
|
||||
--> src/boxes/future/mod.rs:8:5
|
||||
|
|
||||
8 | use std::pin::Pin;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `crate::boxes::map_box::MapBox`
|
||||
--> src/boxes/http/mod.rs:9:5
|
||||
|
|
||||
9 | use crate::boxes::map_box::MapBox;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused imports: `Arc` and `Mutex`
|
||||
--> src/boxes/http/mod.rs:11:17
|
||||
|
|
||||
11 | use std::sync::{Arc, Mutex};
|
||||
| ^^^ ^^^^^
|
||||
|
||||
warning: unused import: `Mutex`
|
||||
--> src/boxes/regex/mod.rs:9:22
|
||||
|
|
||||
9 | use std::sync::{Arc, Mutex};
|
||||
| ^^^^^
|
||||
|
||||
warning: unused macro definition: `debug_fuel`
|
||||
--> src/parser/expressions.rs:38:14
|
||||
|
|
||||
38 | macro_rules! debug_fuel {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_macros)]` on by default
|
||||
|
||||
warning: unused macro definition: `debug_fuel`
|
||||
--> src/parser/mod.rs:51:14
|
||||
|
|
||||
51 | macro_rules! debug_fuel {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: unused imports: `AddBox`, `DivideBox`, `MultiplyBox`, and `SubtractBox`
|
||||
--> src/interpreter/mod.rs:10:75
|
||||
|
|
||||
10 | use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, AddBox, SubtractBox, MultiplyBox, DivideBox, CompareBox, ArrayB...
|
||||
| ^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/interpreter/objects.rs:13:5
|
||||
|
|
||||
13 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `StringBox`
|
||||
--> src/interpreter/methods/collection_methods.rs:11:24
|
||||
|
|
||||
11 | use crate::box_trait::{StringBox, IntegerBox, NyashBox, BoolBox};
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: unused imports: `IntegerBox` and `StringBox`
|
||||
--> src/interpreter/methods/data_methods.rs:11:34
|
||||
|
|
||||
11 | use crate::box_trait::{NyashBox, StringBox, IntegerBox};
|
||||
| ^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
warning: unused import: `StringBox`
|
||||
--> src/interpreter/methods/network_methods.rs:10:34
|
||||
|
|
||||
10 | use crate::box_trait::{NyashBox, StringBox};
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: unused import: `basic_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:27:9
|
||||
|
|
||||
27 | pub use basic_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `collection_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:28:9
|
||||
|
|
||||
28 | pub use collection_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `io_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:29:9
|
||||
|
|
||||
29 | pub use io_methods::*;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `data_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:30:9
|
||||
|
|
||||
30 | pub use data_methods::*;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `network_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:31:9
|
||||
|
|
||||
31 | pub use network_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/operator_traits.rs:16:5
|
||||
|
|
||||
16 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0592]: duplicate definitions with name `execute_parent_constructor`
|
||||
--> src/interpreter/expressions.rs:816:5
|
||||
|
|
||||
816 | / fn execute_parent_constructor(&mut self, parent: &str, parent_box_decl: &super::BoxDeclaration,
|
||||
817 | | current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||
818 | | -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
| |__________________________________________________^ duplicate definitions for `execute_parent_constructor`
|
||||
|
|
||||
::: src/interpreter/objects.rs:789:5
|
||||
|
|
||||
789 | / pub(super) fn execute_parent_constructor(&mut self, parent_class: &str, arguments: &[ASTNode])
|
||||
790 | | -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
| |__________________________________________________- other definition for `execute_parent_constructor`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> src/interpreter/expressions.rs:732:77
|
||||
|
|
||||
732 | let is_valid_delegation = current_box_decl.extends.as_ref() == Some(parent) ||
|
||||
| ---- ^^^^^^ expected `&String`, found `&str`
|
||||
| |
|
||||
| arguments to this enum variant are incorrect
|
||||
|
|
||||
= note: expected reference `&std::string::String`
|
||||
found reference `&str`
|
||||
help: the type constructed contains `&str` due to the type of the argument passed
|
||||
--> src/interpreter/expressions.rs:732:72
|
||||
|
|
||||
732 | let is_valid_delegation = current_box_decl.extends.as_ref() == Some(parent) ||
|
||||
| ^^^^^------^
|
||||
| |
|
||||
| this argument influences the type of `Some`
|
||||
note: tuple variant defined here
|
||||
--> /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/core/src/option.rs:597:5
|
||||
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> src/interpreter/expressions.rs:753:25
|
||||
|
|
||||
753 | return self.execute_parent_constructor(parent, &parent_box_decl, current_instance_val.clone_box(), arguments);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ multiple `execute_parent_constructor` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl for the type `core::NyashInterpreter`
|
||||
--> src/interpreter/expressions.rs:816:5
|
||||
|
|
||||
816 | / fn execute_parent_constructor(&mut self, parent: &str, parent_box_decl: &super::BoxDeclaration,
|
||||
817 | | current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||
818 | | -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
| |__________________________________________________^
|
||||
note: candidate #2 is defined in an impl for the type `core::NyashInterpreter`
|
||||
--> src/interpreter/objects.rs:789:5
|
||||
|
|
||||
789 | / pub(super) fn execute_parent_constructor(&mut self, parent_class: &str, arguments: &[ASTNode])
|
||||
790 | | -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
| |__________________________________________________^
|
||||
|
||||
warning: unused import: `Write`
|
||||
--> src/boxes/stream/mod.rs:10:21
|
||||
|
|
||||
10 | use std::io::{Read, Write, Result};
|
||||
| ^^^^^
|
||||
|
||||
warning: unused import: `Read`
|
||||
--> src/boxes/stream/mod.rs:10:15
|
||||
|
|
||||
10 | use std::io::{Read, Write, Result};
|
||||
| ^^^^
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:29:28
|
||||
|
|
||||
29 | pub fn http_get(&self, url: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
|
||||
= note: `#[warn(unused_variables)]` on by default
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:34:24
|
||||
|
|
||||
34 | pub fn post(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `body`
|
||||
--> src/boxes/http/mod.rs:34:48
|
||||
|
|
||||
34 | pub fn post(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_body`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:39:23
|
||||
|
|
||||
39 | pub fn put(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `body`
|
||||
--> src/boxes/http/mod.rs:39:47
|
||||
|
|
||||
39 | pub fn put(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_body`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:44:26
|
||||
|
|
||||
44 | pub fn delete(&self, url: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `method`
|
||||
--> src/boxes/http/mod.rs:49:27
|
||||
|
|
||||
49 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_method`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:49:54
|
||||
|
|
||||
49 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `options`
|
||||
--> src/boxes/http/mod.rs:49:78
|
||||
|
|
||||
49 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_options`
|
||||
|
||||
warning: variable `arg_count` is assigned to, but never used
|
||||
--> src/parser/expressions.rs:246:33
|
||||
|
|
||||
246 | let mut arg_count = 0;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_arg_count` instead
|
||||
|
||||
warning: unused variable: `name`
|
||||
--> src/parser/statements.rs:65:35
|
||||
|
|
||||
65 | TokenType::IDENTIFIER(name) => {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_name`
|
||||
|
||||
warning: variable `statement_count` is assigned to, but never used
|
||||
--> src/parser/mod.rs:132:17
|
||||
|
|
||||
132 | let mut statement_count = 0;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_statement_count` instead
|
||||
|
||||
warning: unused variable: `i`
|
||||
--> src/interpreter/expressions.rs:537:22
|
||||
|
|
||||
537 | for (i, arg) in arguments.iter().enumerate() {
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_i`
|
||||
|
||||
warning: variable `result` is assigned to, but never used
|
||||
--> src/interpreter/expressions.rs:862:21
|
||||
|
|
||||
862 | let mut result: Box<dyn NyashBox> = Box::new(VoidBox::new());
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: consider using `_result` instead
|
||||
|
||||
warning: value assigned to `result` is never read
|
||||
--> src/interpreter/expressions.rs:864:17
|
||||
|
|
||||
864 | result = self.execute_statement(statement)?;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
= note: `#[warn(unused_assignments)]` on by default
|
||||
|
||||
warning: value assigned to `result` is never read
|
||||
--> src/interpreter/expressions.rs:868:21
|
||||
|
|
||||
868 | result = return_val.clone_box();
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
warning: unused variable: `existing_method`
|
||||
--> src/instance.rs:95:21
|
||||
|
|
||||
95 | if let Some(existing_method) = new_methods.get(&method_name) {
|
||||
| ^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_existing_method`
|
||||
|
||||
Some errors have detailed explanations: E0034, E0308, E0592.
|
||||
For more information about an error, try `rustc --explain E0034`.
|
||||
warning: `nyash-rust` (lib) generated 38 warnings
|
||||
error: could not compile `nyash-rust` (lib) due to 3 previous errors; 38 warnings emitted
|
||||
0
docs/archive/build_log.txt
Normal file
0
docs/archive/build_log.txt
Normal file
0
docs/archive/build_output.txt
Normal file
0
docs/archive/build_output.txt
Normal file
56
docs/archive/chatgpt5/インタープリタ評価.txt
Normal file
56
docs/archive/chatgpt5/インタープリタ評価.txt
Normal file
@ -0,0 +1,56 @@
|
||||
Nyash Interpreter Assessment (Current Strengths, Weaknesses, Direction)
|
||||
|
||||
Strengths
|
||||
- Everything is Box: 統一データモデルで生成/代入/比較/解放が一貫。学習・読解が容易。
|
||||
- Explicit lifecycle: init/fini/weak/スコープ解放を構文で規約化。解放点が読み取れる。
|
||||
- Cycles solved pragmatically: init { weak ... } + 自動nil化で双方向参照を安全に扱える。
|
||||
- Delegation-first: from(多重対応)+ override必須で明示合成。暗黙解決を排しテスト容易。
|
||||
- Rust core: Arc<Mutex<...>>/Weak、BoxFinalizer、二重解放防止など堅牢な実装基盤。
|
||||
- Dev UX: 明示変数宣言、単一ループ構文、static box Mainでコード規律が単純。
|
||||
- Repro: WASM Playgroundでゼロインストール再現(docs/chatgpt5/PLAYGROUND_GUIDE.md)。
|
||||
|
||||
Weaknesses
|
||||
- Mixed field models: fields(レガシー)と fields_ng(次世代)が併存し、理解/実装が複雑。
|
||||
- Weak shim leakage: 一部weakを文字列マーカーで代替(set_weak_field_from_legacy)。完全WeakBox化が未完。
|
||||
- Builtin gaps: Math/Float/Intent/P2P周辺に未実装・登録不足が残る。
|
||||
- P2P disabled path: インタープリタ内のP2P呼び出しが一時無効化で連携が途切れがち。
|
||||
- Verbose debug: 実行時eprintlnが多くノイズ。ログレベル切替が未整備。
|
||||
- Multi-delegation policy: 競合解決の仕様/診断が未完成でユーザーが迷う余地。
|
||||
|
||||
Current Limitations
|
||||
- Determinism vs sharing: finiは解放フックだが強参照が残る場合は実体が残存。期待との齟齬可能性あり。
|
||||
- Error surfacing: RuntimeErrorのSpan拡張が全コードパスで統一されていない。
|
||||
- Perf visibility: ベンチ/メトリクス不足。weak upgradeやfini回数の観測が難しい。
|
||||
- WASM behavior: ブラウザでのタイミング/ログ表示がネイティブと異なる場合あり。
|
||||
|
||||
Direction
|
||||
- Product-first clarity: 「迷わない規約」を前面に。実用性と予測可能性を訴求。
|
||||
- Unify field storage: fields_ngへ一本化し、WeakBoxをエンドツーエンドで運用。
|
||||
- Delegation doctrine: 多重デリゲーション競合のポリシー(優先/明示/エラー)を明文化・実装。
|
||||
- Measurable DX: Playgroundでfini回数/weak upgrade成功・失敗を可視化して説得力向上。
|
||||
- Complete builtins: Float/Math/Intent/P2Pの未完箇所を段階的に充足し、テストで裏付け。
|
||||
|
||||
High-Impact Next Steps
|
||||
- WeakBox E2E完了: 文字列マーカー廃止→NyashValue::WeakBoxで統一。テスト追加。
|
||||
- Assignment safety audit: 再代入→fini→weak自動nil化の一連を網羅試験(成功/競合/例外)。
|
||||
- Multi-delegation conflicts: 明示親指定必須・曖昧時はエラー+提案を実装。エラーメッセージ改善。
|
||||
- P2P経路の復活: expressions.rsのP2P呼び出しを段階的に再有効化。Intentアクセサ整備。
|
||||
- Debug levels: ログレベル導入(環境変数/DebugBox)でノイズ削減と計測を両立。
|
||||
- Playground強化: 3シナリオにメトリクス表示(fini総数、weak失敗数、簡易時間)。
|
||||
|
||||
Risks / Trade-offs
|
||||
- Perception risk: finiを「即時破棄」と誤解される恐れ。共有参照残存の挙動を明文化要。
|
||||
- Dual-storage complexity: レガシー/次世代の二重管理期間にバグ混入リスク。
|
||||
- Performance cliffs: 過度なMutexロック/頻繁なupgradeがホットパスで効く可能性。測定・キャッシュ要検討。
|
||||
- WASM differences: ブラウザでのタイミング/ログ/スレッド制約がネイティブと異なる。
|
||||
|
||||
Stretch Ideas
|
||||
- Static analysis: init/weakの静的検証、循環参照ヒント、未宣言代入の修正提案(LSP連携)。
|
||||
- Conflict DSL: 多重デリゲーション競合を宣言で解決できる軽量DSL導入。
|
||||
- Tracing viz: weak生死・finiイベントのタイムライン可視化(Playground連携)。
|
||||
- Packages/templates: 標準Boxとテンプレート(ゲーム/アート/教育)で“動く最小”を量産。
|
||||
|
||||
Summary
|
||||
統一モデルと明示規約で日常のメモリ管理を楽にする点が最大の強み。短期はWeakの完全統一とデモ/数値の可視化に集中し、
|
||||
多重デリゲーションの競合仕様や未完Boxを段階的に整備するのが最も効果的。
|
||||
|
||||
102
docs/archive/chatgpt5/プレイグラウンド_ガイド.md
Normal file
102
docs/archive/chatgpt5/プレイグラウンド_ガイド.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Nyash Playground Guide(ブラウザデモ活用ガイド)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
## リンク
|
||||
- Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
|
||||
## ねらい
|
||||
- 言語の要点(init/fini/weak/スコープ解放)を“動く例”で体感
|
||||
- レビュワーやチームへの共有・再現を容易化(ゼロインストール)
|
||||
|
||||
## 使い方(最短)
|
||||
1) 上記リンクを開く
|
||||
2) 下のサンプルコードをコピー&ペースト
|
||||
3) Run/実行ボタンで結果確認(ログ・出力・エラー挙動)
|
||||
|
||||
---
|
||||
|
||||
## シナリオ1: 循環参照 vs weak(自動nil化)
|
||||
|
||||
```nyash
|
||||
# Parent↔Child の双方向参照。
|
||||
# 子→親は weak 参照にして、リークとダングリングを防ぐ。
|
||||
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me)
|
||||
}
|
||||
getName() { return "P" }
|
||||
fini() { print("Parent.fini") }
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p }
|
||||
show() {
|
||||
if (me.parent != null) { print("parent=" + me.parent.getName()) }
|
||||
else { print("parent is gone") }
|
||||
}
|
||||
fini() { print("Child.fini") }
|
||||
}
|
||||
|
||||
p = new Parent()
|
||||
p.child.show() # => parent=P
|
||||
|
||||
# 親を明示的に破棄(fini 呼出しが発火する環境であればここで解放)
|
||||
p.fini()
|
||||
|
||||
# 親が破棄済みなので、weak 参照は自動的に nil 化される
|
||||
p.child.show() # => parent is gone(想定)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- `init { weak parent }`で弱参照を宣言
|
||||
- 参照先が破棄されるとアクセス時に自動で`null`扱い
|
||||
|
||||
---
|
||||
|
||||
## シナリオ2: 再代入時の fini 発火(予備解放)
|
||||
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # 旧 obj に対して fini() が呼ばれる(ログで確認)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- フィールド再代入の節目で `fini()` が自動呼出し
|
||||
- 二重解放は内部で抑止(安全側)
|
||||
|
||||
---
|
||||
|
||||
## シナリオ3: スコープ抜けでローカル解放
|
||||
|
||||
```nyash
|
||||
function make() {
|
||||
local t
|
||||
t = new Thing()
|
||||
# 関数を抜けるとスコープ追跡により t が解放される
|
||||
}
|
||||
|
||||
box Thing { fini() { print("Thing.fini (scope)") } }
|
||||
|
||||
make() # => Thing.fini (scope)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- `local`で宣言された変数はスコープ終了時に一括解放
|
||||
- 暗黙ではなく構文規約で明示(未宣言代入はエラー)
|
||||
|
||||
---
|
||||
|
||||
## Tips(レビュー/論文向け)
|
||||
- 論文やREADMEから本ガイドへリンクし、コピー&ペーストで再現
|
||||
- 期待ログ(例: `Thing.fini`)を明記して、挙動の確認を容易に
|
||||
- 比較のため「weakなし版」と「weakあり版」を並記
|
||||
|
||||
65
docs/archive/chatgpt5/プレイグラウンド_サンプル.md
Normal file
65
docs/archive/chatgpt5/プレイグラウンド_サンプル.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Playground Samples(コピー&ペースト用サンプル)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
|
||||
---
|
||||
|
||||
## 1) 循環参照 vs weak(自動nil化)
|
||||
|
||||
```nyash
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me)
|
||||
}
|
||||
getName() { return "P" }
|
||||
fini() { print("Parent.fini") }
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p }
|
||||
show() {
|
||||
if (me.parent != null) { print("parent=" + me.parent.getName()) }
|
||||
else { print("parent is gone") }
|
||||
}
|
||||
fini() { print("Child.fini") }
|
||||
}
|
||||
|
||||
p = new Parent()
|
||||
p.child.show() # => parent=P
|
||||
p.fini() # 親を破棄
|
||||
p.child.show() # => parent is gone(想定)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2) 再代入時の fini 発火(予備解放)
|
||||
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # 旧 obj に対して fini() が呼ばれる
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3) スコープ抜けでローカル解放
|
||||
|
||||
```nyash
|
||||
function make() {
|
||||
local t
|
||||
t = new Thing()
|
||||
}
|
||||
|
||||
box Thing { fini() { print("Thing.fini (scope)") } }
|
||||
|
||||
make() # => Thing.fini (scope)
|
||||
```
|
||||
|
||||
31
docs/archive/chatgpt5/実装TODO_解放とガード.txt
Normal file
31
docs/archive/chatgpt5/実装TODO_解放とガード.txt
Normal file
@ -0,0 +1,31 @@
|
||||
Implementation TODOs: Finalization & Guards
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
Scope: src/instance.rs, src/interpreter/{core,expressions,statements}.rs, parser
|
||||
|
||||
1) InstanceBox::fini() の強化(src/instance.rs)
|
||||
- 状態機械: in_finalization(再入防止)→ finalized。
|
||||
- 再帰: init 強参照フィールドを走査し、未処理の子 Instance に対して finalize。weak は対象外。
|
||||
- クリア: 全フィールドクリア、finalized = true。
|
||||
- 無害化: 二重呼び出しは no-op。
|
||||
|
||||
2) 使用禁止ガード(実行時)
|
||||
- expressions.rs: メソッド呼び出し前に instance.is_finalized() をチェック→エラー。
|
||||
- statements.rs: フィールド代入/アクセス時にチェック→エラー。
|
||||
- core.rs: 必要なら共通ヘルパーで一元化。
|
||||
|
||||
3) weak への fini 禁止(静的検出+実行時フォールバック)
|
||||
- parser: AST 上で fini() 呼び出しを検出し、対象が weak フィールドならビルドエラーに。
|
||||
- 実行時: 保険として expressions.rs で weak フィールド経由の fini 呼び出しを拒否。
|
||||
|
||||
4) 例外方針とログ
|
||||
- ユーザー fini() で例外→自動カスケードは続行。最後に集約報告。
|
||||
- ログレベル: デバッグ時のみ詳細(upgrade失敗、already finalized等)。
|
||||
|
||||
5) Playground 可視化(別PR)
|
||||
- fini 回数、Finalizing→Finalized遷移、weak upgrade失敗数をUI表示。
|
||||
|
||||
6) ドキュメント反映(実装後)
|
||||
- LANGUAGE_GUIDE / reference へ最終ルール・エラーメッセージ・サンプルを移植。
|
||||
|
||||
92
docs/archive/chatgpt5/実装計画_fini統合.txt
Normal file
92
docs/archive/chatgpt5/実装計画_fini統合.txt
Normal file
@ -0,0 +1,92 @@
|
||||
Implementation Plan: Finalization Policy Integration (fini)
|
||||
|
||||
Last updated: 2025-08-13
|
||||
|
||||
Goals
|
||||
- Default: Auto-finalize strong fields in init declaration order.
|
||||
- Custom: User-defined fini() can implement any order and additional cleanup.
|
||||
- Remainder: Auto-cascade finalization for strong fields not handled in user fini().
|
||||
- Prohibit: Calling fini() on weak fields (non-owning).
|
||||
- Guard: Forbid any use after finalized (errors), idempotent fini().
|
||||
|
||||
Touched code (planned)
|
||||
- src/instance.rs (core: InstanceBox state + fini strengthen)
|
||||
- src/interpreter/objects.rs (construct InstanceBox with needed metadata)
|
||||
- src/interpreter/expressions.rs (method/field guards, weak-fini runtime check)
|
||||
- src/interpreter/statements.rs (assignment guards)
|
||||
- parser (optional later: static detection of weak-fini inside user fini())
|
||||
|
||||
1) InstanceBox: add metadata and strengthen fini()
|
||||
- Add fields:
|
||||
- init_field_order: Vec<String>
|
||||
Purpose: deterministic auto-cascade order (includes inherited fields).
|
||||
- weak_fields_union: std::collections::HashSet<String>
|
||||
Purpose: fast check to skip weak fields in auto-cascade (includes parents’ weak fields).
|
||||
- in_finalization: bool
|
||||
Purpose: prevent re-entrancy; together with existing finalized flag.
|
||||
- Constructor changes:
|
||||
- InstanceBox::new(class_name: String, all_fields: Vec<String>, methods: HashMap<String, ASTNode>,
|
||||
weak_fields_union: HashSet<String>)
|
||||
Set init_field_order = all_fields; weak_fields_union = provided; in_finalization = false.
|
||||
- Strengthen InstanceBox::fini():
|
||||
- if finalized => return Ok(()) (idempotent)
|
||||
- set in_finalization = true
|
||||
- (User-defined fini() body is executed by interpreter before calling this method; keep that flow)
|
||||
- Auto-cascade: for each field in init_field_order
|
||||
- if field in weak_fields_union => skip
|
||||
- get current field value; if InstanceBox => child.fini() (idempotent)
|
||||
- Clear all fields; set finalized = true; set in_finalization = false; return Ok(())
|
||||
|
||||
2) objects.rs: pass metadata at construction time
|
||||
- Location: src/interpreter/objects.rs, execute_new() / resolve_inheritance()
|
||||
- Already computes `all_fields` via resolve_inheritance(). Use as init_field_order.
|
||||
- Implement helper union_weak_fields(box_decl: &BoxDeclaration) -> HashSet<String>
|
||||
- Traverse current box_decl and recursively parents (extends) to collect weak fields.
|
||||
- Call: InstanceBox::new(actual_class_name, all_fields, all_methods, weak_fields_union)
|
||||
|
||||
3) Runtime guards and weak-fini prohibition (expressions.rs/statements.rs)
|
||||
- Method calls (src/interpreter/expressions.rs::execute_method_call)
|
||||
- If target is InstanceBox and method != "fini":
|
||||
- if instance.is_finalized() => error: "Instance was finalized; further use is prohibited"
|
||||
- If method == "fini":
|
||||
- If object AST is FieldAccess/ThisField/MeField, resolve owner + field name; if field is weak (by box_decl.weak_fields) => error: "Cannot finalize weak field '<name>' (non-owning reference)"
|
||||
- Else proceed with current special fini handling (user body execution) then call instance.fini()
|
||||
- Field access (execute_field_access)
|
||||
- If owner InstanceBox is finalized => error as above
|
||||
- Assignments (src/interpreter/statements.rs)
|
||||
- For FieldAccess/ThisField/MeField targets: if owner InstanceBox is finalized => error
|
||||
|
||||
4) Parser (optional, later)
|
||||
- Static detection inside user-defined fini() body:
|
||||
- Walk AST; detect `me.<weak_field>.fini()` and emit build-time error.
|
||||
- Runtime check remains as fallback for dynamic flows.
|
||||
|
||||
Important decisions
|
||||
- Do not track "handled-by-user-fini" set. Rely on idempotent child.fini(). This keeps implementation simple and safe.
|
||||
- Ensure weak_fields_union includes parents to avoid accidentally finalizing weak fields inherited from parents.
|
||||
|
||||
Tests (to add/verify)
|
||||
- Reassignment: old value’s fini() is called exactly once; Thing.fini counter.
|
||||
- Weak prohibition: `me.weakField.fini()` raises error (runtime; later build-time).
|
||||
- Custom order: User fini closes r3->r2, auto cascade closes remaining r1.
|
||||
- Finalized guard: method call / field access / assignment after fini => error.
|
||||
- Cycles: Parent<->Child (Child weak parent); Parent.fini() => Child’s parent becomes null on access (lazy nilification), no leaks.
|
||||
|
||||
Rollout order
|
||||
1. InstanceBox fields + fini strengthen (core).
|
||||
2. Interpreter guards (method/field/assignment).
|
||||
3. Weak-fini runtime prohibition via AST check.
|
||||
4. Tests and sample updates (docs/chatgpt5/finalization_examples.txt cases).
|
||||
5. Optional: parser build-time detection.
|
||||
|
||||
Risks and mitigations
|
||||
- Re-entrancy: guarded by in_finalization + idempotent finalized flag.
|
||||
- Performance: auto-cascade per field; usually shallow; child.fini idempotent avoids repeated heavy work.
|
||||
- Compatibility: InstanceBox::new signature change; update all call sites (objects.rs, core.rs statics/global creations).
|
||||
- UX: Clear error messages as documented in docs/chatgpt5/finalization_errors.txt.
|
||||
|
||||
Future enhancements (optional)
|
||||
- Attribute `@no_auto_finalize` to exclude fields from auto-cascade when fully managed in user fini().
|
||||
- FinalizationContext injected into user fini() for safe, limited operations.
|
||||
- Debug mode: eager weak invalidation at finalize time for visualization.
|
||||
|
||||
63
docs/archive/chatgpt5/解放ポリシー_fini.txt
Normal file
63
docs/archive/chatgpt5/解放ポリシー_fini.txt
Normal file
@ -0,0 +1,63 @@
|
||||
Nyash Finalization Policy (fini as destructor-style method)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
目的
|
||||
- fini を「フィールド列挙」ではなく「通常のメソッド本体(デストラクタ的)」として運用しつつ、
|
||||
自動カスケード解放(init フィールドの残り処理)と整合する最終ルールを定義する。
|
||||
|
||||
設計方針(合意)
|
||||
- すべての Box は論理的に fini() を持つ(ユーザー未定義でもシステム既定が働く)。
|
||||
- fini() は“論理的解放”のフックであり、以後の使用は禁止(finalized)。
|
||||
- weak フィールドは所有権を持たないため、自動の fini 対象にしない(アクセス時の upgrade 失敗で null)。
|
||||
|
||||
実行順序(最終)
|
||||
1) 既に finalized なら何もしない(idempotent)。
|
||||
2) 再入防止のため in_finalization フラグを立てる(finalized はまだ立てない)。
|
||||
3) ユーザー定義 fini() 本体があれば実行(この間、フィールドアクセス/メソッド呼び出しは許可)。
|
||||
4) 自動カスケード解放:init{ ... } に宣言された強参照フィールドのうち、
|
||||
- ユーザー fini() 本体で明示的に処理されなかった“残り”に対して、宣言順で child.fini() を呼ぶ。
|
||||
- weak 修飾フィールドは対象外。
|
||||
5) 全フィールドをクリアし finalized フラグを立てる(以後の使用は禁止)。
|
||||
6) 再入フラグを下ろして終了。
|
||||
|
||||
使用禁止ガード
|
||||
- finalized 後の操作はエラーとする:
|
||||
- メソッド呼び出し、フィールドアクセス/代入、デリゲーション経由の呼び出し等。
|
||||
- 推奨メッセージ:"Instance was finalized; further use is prohibited"。
|
||||
- idempotent な fini() の再呼び出しのみ許容(無害化)。
|
||||
|
||||
補足
|
||||
- ユーザー定義 fini() 内で解放順序が必要な場合は、自由に child.fini() を呼べる(柔軟性)。
|
||||
- その後に“残り”が自動処理されるため、完全手動にしたい場合は将来的に属性(例:@no_auto_finalize)導入を検討(現段階は自動処理ありを既定)。
|
||||
- 例外発生時はベストエフォートで自動カスケードとクリアを続行(安全側)。
|
||||
|
||||
weak の取り扱い
|
||||
- weak はアクセス時に upgrade/失敗で null となる(lazy nilification)。
|
||||
- デバッグ用途として finalize 時に weak を即時無効化する eager モードを将来オプションで検討可(既定は lazy)。
|
||||
|
||||
禁止事項と診断(weak に対する fini 呼び出し)
|
||||
- ルール: weak 修飾フィールドは所有権を持たないため、`me.<weak_field>.fini()` のような直接の fini 呼び出しを禁止する。
|
||||
- 推奨診断レベル: ビルド(解析)時エラー。
|
||||
- 推奨エラーメッセージ: "Cannot finalize weak field '<name>' (non-owning reference). Use null assignment or let it lazily nilify."
|
||||
- 実装補足: 静的解析で `fini()` 本体内のフィールド呼び出しを走査し、対象が weak に該当すればエラー。検出困難な動的経路は実行時にもエラーを返す。
|
||||
- 推奨代替手段: `me.<weak_field> = null`(参照解除)/アクセス時の自動 nil 化に任せる。
|
||||
|
||||
簡易疑似コード
|
||||
fn finalize(instance):
|
||||
if instance.finalized: return
|
||||
instance.in_finalization = true
|
||||
if has_user_fini(instance):
|
||||
run_user_fini_body(instance)
|
||||
for field in instance.init_fields:
|
||||
if is_strong_ref(field) and not handled_in_user_fini(field):
|
||||
if is_instance(field.value) and not field.value.finalized:
|
||||
finalize(field.value)
|
||||
clear_all_fields(instance)
|
||||
instance.finalized = true
|
||||
instance.in_finalization = false
|
||||
|
||||
期待する効果
|
||||
- 柔軟性:ユーザー fini() 本体で任意順序・任意処理が書ける。
|
||||
- 決定性:残りは init 宣言順で自動解放され、毎回同じ順に実行。
|
||||
- 明確性:finalized 後は使用禁止をガードで強制、誤用を早期検知。
|
||||
39
docs/archive/chatgpt5/解放ポリシー_エラーと診断.txt
Normal file
39
docs/archive/chatgpt5/解放ポリシー_エラーと診断.txt
Normal file
@ -0,0 +1,39 @@
|
||||
Nyash Finalization Errors and Diagnostics
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
1) 使用禁止エラー(finalized 後の操作)
|
||||
---------------------------------------
|
||||
Message: "Instance was finalized; further use is prohibited"
|
||||
When: finalized フラグが立ったインスタンスに対して、
|
||||
- メソッド呼び出し
|
||||
- フィールドアクセス/代入
|
||||
- デリゲーション経由の呼び出し
|
||||
を行った場合。
|
||||
Notes: toString 相当も原則禁止(方針次第)。まずは全面禁止が明快。
|
||||
|
||||
2) weak に対する fini 呼び出し(禁止)
|
||||
---------------------------------------
|
||||
Message (build-time preferred):
|
||||
"Cannot finalize weak field '<name>' (non-owning reference)."
|
||||
Message (runtime fallback):
|
||||
"Finalization of non-owning (weak) reference is not allowed: '<name>'"
|
||||
When: `init { weak <name> }` で宣言されたフィールドに対して `fini()` を直接呼んだ場合。
|
||||
Fix: `me.<name> = null`(参照解除) or 自動 nil 化に任せる。
|
||||
|
||||
3) 二重解放の抑止(無害化)
|
||||
---------------------------------------
|
||||
Behavior: 2回目以降の `fini()` 呼出しは no-op。
|
||||
Notes: ログに "already finalized" を出すかは運用ポリシー次第。
|
||||
|
||||
4) 自動カスケード中の例外
|
||||
---------------------------------------
|
||||
Policy: ベストエフォートで残りの解放を継続、最後にまとめて報告(fail-safe)。
|
||||
Message example:
|
||||
"Finalization encountered errors; see aggregated report (N failures)."
|
||||
|
||||
5) 解析時の注意(推奨)
|
||||
---------------------------------------
|
||||
- fini() 本体内でのフィールド fini 呼び出しは静的解析で走査し、weak を検知したらビルドエラーへ。
|
||||
- 明示属性 `@no_auto_finalize`(将来案)を付与したフィールドは自動カスケード対象から除外。
|
||||
|
||||
73
docs/archive/chatgpt5/解放ポリシー_例.txt
Normal file
73
docs/archive/chatgpt5/解放ポリシー_例.txt
Normal file
@ -0,0 +1,73 @@
|
||||
Nyash Finalization Examples
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
1) 既定: init 宣言順での解放(強参照のみ)
|
||||
--------------------------------------------------
|
||||
box A { fini() { print("A.fini") } }
|
||||
box B { fini() { print("B.fini") } }
|
||||
|
||||
box Holder {
|
||||
init { a, b, weak c }
|
||||
}
|
||||
|
||||
h = new Holder()
|
||||
h.a = new A()
|
||||
h.b = new B()
|
||||
# h.c は weak なので対象外
|
||||
|
||||
# h.fini() を呼ぶと:
|
||||
# 1) ユーザー定義 fini() があれば先に実行
|
||||
# 2) 残りは init の宣言順に a → b の順で child.fini()
|
||||
# 3) フィールドクリア → finalized
|
||||
|
||||
|
||||
2) カスタム順序: ユーザー定義 fini() で順序制御
|
||||
--------------------------------------------------
|
||||
box Resource { init { name } fini() { print("close:" + me.name) } }
|
||||
|
||||
box Pipeline {
|
||||
init { r1, r2, r3 }
|
||||
fini() {
|
||||
# 依存性の都合で r3 → r2 → r1 の順に閉じたい
|
||||
if me.r3 != null { me.r3.fini() }
|
||||
if me.r2 != null { me.r2.fini() }
|
||||
# r1 は明示しない → 自動カスケードで最後に閉じられる
|
||||
}
|
||||
}
|
||||
|
||||
p = new Pipeline()
|
||||
p.r1 = new Resource("r1")
|
||||
p.r2 = new Resource("r2")
|
||||
p.r3 = new Resource("r3")
|
||||
p.fini()
|
||||
# 期待: close:r3 → close:r2 → close:r1 の順
|
||||
|
||||
|
||||
3) 弱参照は対象外(禁止パターン)
|
||||
--------------------------------------------------
|
||||
box Parent { init { weak child } fini() {
|
||||
# NG: 非所有参照のため fini は禁止
|
||||
# me.child.fini() # → ビルド時エラー(推奨):Cannot finalize weak field 'child'
|
||||
# 代替: 参照解除
|
||||
me.child = null
|
||||
} }
|
||||
|
||||
|
||||
4) 再代入での予備解放
|
||||
--------------------------------------------------
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
box Holder { init { obj } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # → 旧 obj に対して自動的に fini()
|
||||
|
||||
|
||||
5) finalized 後の使用禁止
|
||||
--------------------------------------------------
|
||||
box X { }
|
||||
x = new X()
|
||||
x.fini()
|
||||
x.doSomething() # → 実行時エラー: Instance was finalized; further use is prohibited
|
||||
|
||||
94
docs/archive/chatgpt5/設計RFC_多重デリゲーションとfini.txt
Normal file
94
docs/archive/chatgpt5/設計RFC_多重デリゲーションとfini.txt
Normal file
@ -0,0 +1,94 @@
|
||||
Nyash 設計検討メモ(RFC): 多重デリゲーション競合ポリシーと fini の意味づけ
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
目的
|
||||
- 多重デリゲーションにおける競合解決ポリシーを明文化し、実装・診断メッセージと揃える。
|
||||
- fini(論理的解放フック)の意味論と期待管理を定義し、現状課題と解決策を整理する。
|
||||
|
||||
---
|
||||
|
||||
1) 多重デリゲーションの競合ポリシー(提案仕様)
|
||||
|
||||
基本方針
|
||||
- 明示最優先: 解決順は定めない。曖昧さがある場合はエラーとし、明示(修飾/override)を要求する。
|
||||
- 子の定義優先: 子で定義/overrideされたものが最優先される。
|
||||
|
||||
メソッド解決
|
||||
- 子に同名メソッドがあればそれを使用。上書きは必ず `override` を要する。
|
||||
- 子に無く、親のうち「ちょうど1つ」だけがメソッドを提供するなら自動選択。
|
||||
- 親の「複数」が同名メソッドを提供する場合は曖昧エラー。
|
||||
- 対処: 子で `override foo(...) { return from A.foo(...); }` のように一本化、または呼び出しごとに `from A.foo(...)` / `from B.foo(...)` を使う。
|
||||
- 親呼び出しは常に `from Parent.m(...)` で明示修飾できる(推奨パターン)。
|
||||
|
||||
フィールド解決
|
||||
- 子がフィールドを持てばそれを使用。
|
||||
- 子に無く、親のうち「ちょうど1つ」だけが同名フィールドを持つ場合は自動選択。
|
||||
- 複数親が同名フィールドを持つ場合は曖昧エラー。
|
||||
- 対処: 子で別名のラッパー/アクセサを定義して再輸出、または(将来案として)`from Parent.field` の明示アクセスを利用。
|
||||
|
||||
インターフェース整合
|
||||
- インターフェースが要求するメソッドに対し、複数親が候補を提供する場合、子は必ず `override` して一本化(または合成)する。
|
||||
|
||||
ビルトイン/Static Box
|
||||
- 同一ポリシーを適用。曖昧な場合はエラーで明示を要求。
|
||||
|
||||
診断メッセージ例
|
||||
- Method 'foo' is provided by: A, B. Disambiguate via:
|
||||
- override foo(...) { return from A.foo(...); }
|
||||
- or call with qualification: from A.foo(...)
|
||||
- Field 'x' is provided by: A, B. Define an alias in child or qualify access.
|
||||
|
||||
実装の要点(簡易アルゴリズム)
|
||||
- 解決時に候補集合 S を作成。|S|=0 → 未定義エラー。|S|=1 → その定義を使用。|S|>1 → 曖昧エラー。
|
||||
- 子の定義は候補集合より常に優先(S を見る前に確定)。
|
||||
- メソッド/フィールドで同一ロジックを共有できるようヘルパー化。
|
||||
|
||||
補助パターン(任意)
|
||||
- 構文追加は避け、子側に明示ラッパーを定義して再輸出するのを推奨(後方互換/可読)。
|
||||
- 拡張案として alias 機構(例: alias { A.foo -> aFoo })は将来検討。
|
||||
|
||||
---
|
||||
|
||||
2) fini(論理的解放フック)の意味づけと期待管理
|
||||
|
||||
定義(言語仕様)
|
||||
- `fini()` は「論理的解放」を宣言するフック。呼び出しコンテキストで当該インスタンスを以後使用しないことを示し、関連資源の解放を行う。
|
||||
- 共有参照(他所の強参照)が残存していても、言語意味論上は finalized(使用不可)とみなす。実体メモリが残る場合があるのは実装都合。
|
||||
|
||||
使用禁止のガード
|
||||
- `fini()` 後の操作はエラー(idempotent な `fini()` 再呼出しのみOK)。
|
||||
- 対象: メソッド呼出し、フィールドアクセス、代入、デリゲーション経由の呼出し等。
|
||||
- 推奨エラーメッセージ: "Instance was finalized; further use is prohibited"。
|
||||
|
||||
波及とクリーンアップ
|
||||
- `fini()` は所有フィールドにも波及。子Boxであるフィールドに対し `fini()` を呼び、その後フィールドをクリア。
|
||||
- 弱参照はアクセス時 upgrade 失敗で自動的に `null`(lazy nil化)。必要に応じてデバッグモードで eager 無効化(任意機能)。
|
||||
|
||||
現状課題(2025-08 時点)
|
||||
- 内部 `instance.fini()` が、全フィールド再帰 `fini()` → クリア を必ずしも保証していない(実装強化余地)。
|
||||
- `fini()` 後の使用禁止ガードが緩く、明確なエラー化が不十分なコードパスがある可能性。
|
||||
- 共有参照が残るケースの意味論が docs に十分明示されておらず、誤解リスクがある。
|
||||
|
||||
解決策(優先度順)
|
||||
1) 内部解放強化: `instance.fini()` 内で全フィールドを走査し、InstanceBox へは `fini()`、二重防止フラグ→最後にクリア。
|
||||
2) ガード導入: `get_field`/`set_field`/`get_method` など入口で `finalized` チェック→使用禁止エラーを返す。
|
||||
3) ドキュメント明記: fini = 論理的解放。共有参照残存時も以後の使用は禁止。弱参照はアクセス時 `null`。
|
||||
4) 可視化: Playground に `fini` 回数/weak upgrade 失敗数/エラー例の表示を追加し、期待を合わせる。
|
||||
|
||||
禁止事項(weak への fini 呼び出し)
|
||||
- ルール: `init { weak ... }` で宣言されたフィールドに対する `fini()` 直接呼び出しは禁止(非所有参照の解放に相当)。
|
||||
- 診断方針: 可能な限りビルドエラーで検出し、動的経路は実行時エラーで防止。
|
||||
- 推奨メッセージ: "Cannot finalize weak field '<name>' (non-owning reference). Set it to null or rely on lazy nilification."
|
||||
|
||||
備考(質問への回答)
|
||||
- 「共有参照が残っていても解放が正しいか?」→ はい。言語意味論では“以後使用禁止”を宣言するのが `fini()` で、
|
||||
物理メモリが残るかどうかはランタイムの参照カウントに依存するだけ。禁止ガードと文書化で期待を一致させる。
|
||||
|
||||
---
|
||||
|
||||
3) 追補: 実装/ドキュメント TODO
|
||||
- interpreter: 候補集合による曖昧検出と診断の実装(メソッド/フィールド)。
|
||||
- instance: 再帰的 `fini()` + フィールドクリアの保証、finalized ガードの一元化。
|
||||
- docs: LANGUAGE_GUIDE / reference に上記仕様を反映(サンプルと期待エラーメッセージ含む)。
|
||||
- playground: メトリクス・エラーの可視化を追加(検証再現性の強化)。
|
||||
126
docs/archive/chatgpt5/論文_サマリ.md
Normal file
126
docs/archive/chatgpt5/論文_サマリ.md
Normal file
@ -0,0 +1,126 @@
|
||||
# Nyash: Everything is Box — 統一メモリモデルと弱参照による安全なライフサイクル管理
|
||||
|
||||
最終更新: 2025-08-13(ドラフト)
|
||||
|
||||
## 概要(Abstract)
|
||||
本稿は、すべての値を統一的なコンテナ「Box」として扱う“Everything is Box”哲学に基づくプログラミング言語Nyashを提案する。Nyashは、言語構文レベルでメモリ管理を明示化し、予測可能なライフサイクル制御とメモリ安全性を両立する。具体的には、(1) Boxのフィールドは`init { ... }`で宣言し、(2) 再代入・スコープ終了・明示的破棄などの節目で`fini()`による予備解放を行い、(3) ローカル変数はスコープを抜けると自動解放、(4) 循環参照は`init { weak ... }`で弱参照を宣言して回避する。実装はRustで行い、`Arc<Mutex<...>>`と`Weak`を活用、解放済みの二重処理防止や弱参照の自動nil化を含む。設計は明示的デリゲーション(`from`)とオーバーライドの厳密化(`override`必須)と一貫し、ブラウザ/WASMを含む現代環境での直感的・堅牢な開発体験を目指す。
|
||||
|
||||
## 1. 背景と動機
|
||||
- 既存パラダイムの課題: 手動メモリ管理は人為的錯誤に脆弱で、GCは停止時間/タイミング不確定性を招く。双方向参照(Parent↔Child、グラフ構造等)は参照カウント系でリークの温床となる。
|
||||
- 目標: 言語規範でライフサイクル規約を先に定義し、生成・使用・解放の節目を明示することで、安全で予測可能なメモリ管理を提供する。あわせて、表現力(デリゲーション、静的エントリポイント、WASM連携等)を損なわない。
|
||||
|
||||
## 2. 設計の中核(Language Design)
|
||||
### 2.1 Everything is Box
|
||||
あらゆる値(整数・文字列・配列・マップ・ユーザー定義オブジェクト・ユーティリティ等)をBoxで統一する。共通の生成・表示・比較・デバッグ・解放インターフェースを持ち、型ごとの最適化は実装側で行う。
|
||||
|
||||
### 2.2 フィールド宣言と初期化(`init { ... }`)
|
||||
- Boxの状態は`init { field1, field2, ... }`で宣言。循環参照が想定されるフィールドは`weak`修飾で弱参照にする(例: `init { weak parent }`)。
|
||||
- 生成は`new`で行い、必要に応じてコンストラクタ/`pack`等で初期値を設定する(詳細は言語ガイド参照)。
|
||||
|
||||
### 2.3 明示的破棄フック(`fini()`)
|
||||
- `fini()`はBox単位の予備解放フック。リソース解放(子Box解放、外部ハンドルclose、解除処理等)を記述できる。
|
||||
- 言語実装は、(a) フィールド再代入時、(b) スコープ終了時(ローカル環境解体)、(c) 明示呼出し時に`fini()`を安全に実行し、二重実行は抑止する。
|
||||
|
||||
### 2.4 ローカル変数とスコープ解放
|
||||
- `local`で宣言した変数はスコープ終了時に一括解放。未宣言代入はエラーとし、見落としを防止。
|
||||
- Static関数における所有権移転は`outbox`で明示化できる。
|
||||
|
||||
### 2.5 循環参照回避(`weak`)
|
||||
- `init { weak parent }`等で弱参照フィールドを宣言する。代入時に強参照を自動ダウングレードして格納し、アクセス時はupgradeを試みる。失敗時は`null`(自動nil化)を返す。
|
||||
- 双方向参照(Parent↔Child、グラフ)でも参照カウントが残存せず、リークを回避できる。
|
||||
|
||||
### 2.6 デリゲーション(`from`)と明示的オーバーライド
|
||||
- `box Child from Parent { ... }`で機能を委譲。多重デリゲーションにより複数親の機能合成をサポート。
|
||||
- 親メソッド呼出しは`from Parent.method(...)`で明示。暗黙の多段チェーン解決は明示性違反として禁止。上書きは`override`必須。
|
||||
|
||||
### 2.7 Static Boxエントリポイント
|
||||
- `static box Main { main() { ... } }`をアプリの規約化された開始点として用意。初回アクセス時に遅延初期化される。
|
||||
|
||||
## 3. 実装(Rustインタープリタ)
|
||||
本実装はRustにより、安全・明確な所有権モデル上でインタープリタを構築する。
|
||||
|
||||
### 3.1 実行時値(NyashValue)
|
||||
- `NyashValue`は`Integer`, `Float`, `Bool`, `String`, `Array`, `Map`, `Box(Arc<Mutex<dyn NyashBox>>)`に加え、`WeakBox(Weak<Mutex<dyn NyashBox>>)`、`Null`、`Void`等を持つ。
|
||||
- 弱参照は`upgrade_weak()`で強参照化を試み、失敗時は`None`→自動nil化の契機となる(実装詳細は最適化の都合上いくつかの互換層を伴う)。
|
||||
|
||||
### 3.2 インスタンス(InstanceBox)
|
||||
- `InstanceBox`は(互換層の)レガシーフィールド`fields`と次世代フィールド`fields_ng`を併用。弱参照は`fields_ng`で管理し、`set_weak_field`/`get_weak_field`が自動ダウングレード/アップグレードとnil化(失敗時)を司る。
|
||||
- インスタンスの`fini()`は二重呼出し防止フラグを持ち、内部フィールドのクリア等を行う。ユーザー定義`fini()`が存在すれば安全に先行実行される(インタープリタがメソッド本体を一時スタックで実行後、内部解放)。
|
||||
|
||||
### 3.3 予備解放(Finalization)
|
||||
- `finalization`モジュールは、解放済みIDのグローバル管理とスコープ追跡(`BoxFinalizer`)を提供。スコープ終了時/再代入時にBoxを走査し、`fini()`→解放済みマーク→追跡リストクリアの順で安全に解体する。
|
||||
- 代入時のふるまい: フィールドへ新しい値を設定する前に、旧値がインスタンスであれば`fini()`を呼出して二重リソース保持を回避する(ワークフローは`statements.rs`参照)。
|
||||
|
||||
### 3.4 構文サポート
|
||||
- パーサは`init { weak ... }`を解析し、`BoxDeclaration.weak_fields`に収集。フィールドアクセス/代入時に弱参照特有のハンドリング(upgrade/nil化/ダウングレード代入)を適用する。
|
||||
- Static Boxと多重デリゲーションは定義レジストリに登録され、実行時に適切な初期化・解決が行われる。
|
||||
|
||||
## 4. 安全性と正当性(概略)
|
||||
- 予測可能な破棄点: フィールド再代入・スコープ終了・明示的呼出しといった「節目」で`fini()`が必ず実行される。
|
||||
- 二重解放防止: 解放済みIDの記録により、`fini()`の多重呼出しは無害化される。
|
||||
- 循環参照回避: 双方向参照を弱参照にする規約で参照カウントの残留を防止。アクセス時の自動nil化でダングリング参照も防ぐ。
|
||||
- 明示性と可読性: `init`/`weak`/`from`/`override`/`local`等の構文規律により、所有権と到達可能性に関する意図をコードに刻む。
|
||||
|
||||
## 5. パフォーマンス特性(概略)
|
||||
- weakの`upgrade()`は原子的操作+分岐でオーバーヘッドは小さく、Mutexロックより低コストなケースが多い。
|
||||
- stop-the-world GCが存在せず、解放は節目ベースで分散されるため、レイテンシ予測性が高い。
|
||||
- 互換層の段階的移行(legacy→next-gen)は将来的にWeakBoxネイティブ化でさらなる最適化が可能。
|
||||
|
||||
## 6. 使用例
|
||||
### 6.1 親子の相互参照(弱参照)
|
||||
```nyash
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me) # 循環構造だが、子側がweak参照を使用
|
||||
}
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p } # 自動でweakに変換・格納
|
||||
getParentName() {
|
||||
if (me.parent != null) { return me.parent.getName() }
|
||||
else { return "Parent is gone" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 再代入時の予備解放
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
h = new Holder()
|
||||
h.obj = new SomeBox()
|
||||
h.obj = new SomeBox() # 旧objに対してfini()が自動呼出し
|
||||
```
|
||||
|
||||
### 6.3 Static Boxエントリ
|
||||
```nyash
|
||||
static box Main {
|
||||
init { console }
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
me.console.log("Everything is Box!")
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 関連研究
|
||||
- SwiftのARCにおける`weak`/`unowned`参照、Rustの`Arc`/`Weak`、Pythonの`weakref`は弱参照の実務的価値を示している。本研究は、弱参照の規約化と`init`/`fini`/スコープ解放を統合した「言語仕様レベルの一貫したライフサイクル設計」を提示する点で差異化される。
|
||||
- 継承ではなくデリゲーション(多重含む)を明示構文で組込むことで、暗黙の探索鎖を排し、構造的明示性とテスト容易性を高める。
|
||||
|
||||
## 8. 制限と今後の課題
|
||||
- 互換層の完全解消: レガシーフィールドから次世代`WeakBox`主導への移行を完了し、統一的な弱参照動作を保証する。
|
||||
- 競合解決: 多重デリゲーション時のメソッド競合検出と診断の改良。
|
||||
- 静的解析: 循環参照の静的検知・Lintの整備。
|
||||
- エコシステム: P2P系Box、WASM環境APIの充実、`async/await`統合の高速化、数値/配列Boxの最適化。
|
||||
|
||||
## 9. 結論
|
||||
Nyashは“Everything is Box”の統一モデルと、`init`/`fini`/`weak`/スコープ解放による予測可能で安全なメモリ管理を言語仕様として提示した。Rust実装により、所有権・スレッド安全・弱参照の自動nil化・二重解放防止を現実的コストで実現する。デリゲーション中心の設計は明示性を高め、教育・アート・Web・P2Pといった多様な開発領域での再利用性と保守性を支える。今後は互換層の収束と解析・最適化の強化により、研究用言語から実運用環境への移行を促進していく。
|
||||
|
||||
---
|
||||
|
||||
補足: 詳細は`docs/LANGUAGE_GUIDE.md`および`docs/reference/weak-reference-design.md`、実装は`src/`配下(`instance.rs`, `finalization.rs`, `interpreter/`)を参照。
|
||||
|
||||
81
docs/archive/chatgpt5/論文_プロダクト寄りドラフト.md
Normal file
81
docs/archive/chatgpt5/論文_プロダクト寄りドラフト.md
Normal file
@ -0,0 +1,81 @@
|
||||
# Nyash: 実務志向の一貫メモリモデルで日常のプログラミングを簡潔に
|
||||
|
||||
最終更新: 2025-08-13(プロダクト寄りドラフト)
|
||||
|
||||
## 概要(Abstract)
|
||||
Nyashは、すべての値を「Box」に統一し、`init`/`fini`/`weak`/スコープ解放を言語構文に組み込むことで、日常的なメモリ管理をわかりやすくする実務志向の言語です。新奇なアルゴリズムを主張するものではなく、過去数十年のプラクティス(RAII、弱参照、明示的ライフサイクル)を「最初から言語仕様で一貫させる」ことで、予測可能で安全なプログラミング体験を提供します。Rust実装により所有権とスレッド安全を担保しながら、再代入・スコープ終了・循環参照といった“よくある落とし穴”を構文で回避します。
|
||||
|
||||
## 1. 課題設定(なにを楽にするか)
|
||||
- 「いつ解放されるのか」がコードから読み取りづらい(暗黙のGC/規約依存)。
|
||||
- 双方向参照やグラフ構造でリークしやすい(参照カウントの残留)。
|
||||
- フィールド/ローカル/グローバルの寿命や責務が曖昧になりがち。
|
||||
|
||||
## 2. Nyashの要点(どう簡単にするか)
|
||||
- 統一モデル: Everything is Box。生成・代入・比較・解放の扱いが一貫。
|
||||
- 明示宣言: `init { ... }`でフィールド列挙、循環は`weak`で明示。
|
||||
- 予備解放: 再代入・スコープ終了・明示呼出しで`fini()`が走る規約。
|
||||
- ローカル変数: `local`を必須化し、未宣言代入エラーで早期検知。
|
||||
- デリゲーション: `from`で機能合成(多重対応)。`override`は明示必須。
|
||||
|
||||
## 3. なにが“新しい”のではなく“役立つ”のか(ポジショニング)
|
||||
- 研究的な新規性よりも、既知の良い手法の言語レベル統合に価値。
|
||||
- 「60年のメモリ管理の知見を、日常利用に迷わない形へ整理」
|
||||
- 開発者体験(DX)と運用の予測可能性(いつ・どこで解放)が主眼。
|
||||
|
||||
## 4. 開発者にとっての具体的メリット
|
||||
- リーク/二重解放の抑止: `fini()`は二重防止付き、弱参照は自動nil化。
|
||||
- 可読性: フィールド寿命・弱参照・委譲関係がコードから一目で分かる。
|
||||
- テスト容易性: 多重デリゲーションで依存差し替えが明瞭。
|
||||
- ブラウザ対応: WASMで“動かして学ぶ”導線が短い。
|
||||
|
||||
## 5. 最小構文サンプル
|
||||
```nyash
|
||||
box Parent { init { child } }
|
||||
box Child { init { weak parent } }
|
||||
|
||||
p = new Parent()
|
||||
p.child = new Child()
|
||||
p.child.setParent(p) # 子→親はweak。循環でもリークしにくい
|
||||
|
||||
box Holder { init { obj } }
|
||||
h = new Holder()
|
||||
h.obj = new SomeBox()
|
||||
h.obj = new SomeBox() # 旧objに対しfini()が自動呼出し
|
||||
|
||||
static box Main { main() { print("OK") } }
|
||||
```
|
||||
|
||||
## 6. 実装概要(Rust)
|
||||
- 実行時値: `NyashValue`に`Box(Arc<Mutex<_>>)`と`WeakBox(Weak<Mutex<_>>)`を持ち、弱参照はアクセス時upgrade→失敗で`null`。
|
||||
- インスタンス: `InstanceBox`が`set_weak_field`/`get_weak_field`で弱参照の格納・自動nil化を扱う。`fini()`は二重防止付き。
|
||||
- スコープ解放: `finalization`モジュールの`BoxFinalizer`がスコープ終了時に一括予備解放。
|
||||
- 代入時処理: フィールド再代入前に旧値へ`fini()`。安全側に倒す規約。
|
||||
|
||||
## 7. 非ゴール(誤解を避けるために)
|
||||
- 新規GCの提案ではない。停止時間最適化などGC起因の研究課題は対象外。
|
||||
- 低レベル最適化の網羅ではない。まずは実務的に“迷わない統一手引き”。
|
||||
|
||||
## 8. 導入・評価の観点(プロダクト視点)
|
||||
- DX: 未宣言代入の早期検知、解放点の明示、弱参照のシンプル化がバグ件数/修正時間に与える影響。
|
||||
- 安定運用: リーク/ダングリング参照/二重解放の再現テストと回避率。
|
||||
- 性能: 弱参照upgrade/`fini()`呼出しのオーバーヘッド(マイクロ/アプリ)。
|
||||
- 学習曲線: Web/WASMのプレイグラウンドでの到達時間・課題種別。
|
||||
|
||||
## 9. 現状とロードマップ
|
||||
- 現状: インタープリタ、弱参照の自動nil化、再代入時`fini()`、多重デリゲーションの基盤が稼働。
|
||||
- 近接課題: レガシー互換層の整理、競合検出メッセージの改善、P2P/標準Boxの拡充。
|
||||
|
||||
## 10. まとめ
|
||||
Nyashは“新しい理論”よりも“迷わない実装規約”で、日常のメモリ管理を静かに楽にすることを狙う。Boxの統一モデルと、`init`/`fini`/`weak`/スコープ解放の一貫性により、解放のタイミングがコードから読める。弱参照の自動nil化と二重解放防止は、実務の落とし穴を減らす。WASM対応の軽い体験とRust実装の堅牢さを両輪に、まずは「使って心地よい」ことを優先し、順次、解析・最適化・エコシステムを整えていく。
|
||||
|
||||
— 参考: 詳細は `docs/LANGUAGE_GUIDE.md`, `docs/reference/weak-reference-design.md` と `src/` 実装を参照。
|
||||
|
||||
## 付録: ブラウザデモ活用(再現性と導線)
|
||||
- Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
- ガイド: プレイグラウンド_ガイド.md(シナリオと手順)
|
||||
- サンプル集: プレイグラウンド_サンプル.md(コピー&ペースト用)
|
||||
|
||||
活用ポイント:
|
||||
- `init`/`fini`/`weak`/スコープ解放の最小例を即時実行し、期待ログ(例: `Thing.fini`、`parent is gone`)で確認可能。
|
||||
- レビュワー/読者はゼロインストールで再現でき、arXiv原稿への短縮URL/QR掲載と相性が良い。
|
||||
- 比較検証(weakなし/あり、再代入前後、スコープ内/外)を1ページで切替・確認可能。
|
||||
337
docs/archive/design-philosophy/explicit-delegation-revolution.md
Normal file
337
docs/archive/design-philosophy/explicit-delegation-revolution.md
Normal file
@ -0,0 +1,337 @@
|
||||
# 🌟 明示的デリゲーション革命:なぜNyashは世界初の完全明示デリゲーション言語になったのか
|
||||
|
||||
作成日: 2025年8月11日
|
||||
著者: Nyashプロジェクトチーム
|
||||
ステータス: 設計思想決定版
|
||||
|
||||
## 📜 はじめに:革命の始まり
|
||||
|
||||
2025年8月11日、Nyashプログラミング言語の開発において、言語設計史上最大級の発見がありました。それは、**暗黙のオーバーライド問題**の発見と、それを解決する**完全明示デリゲーション構文**の誕生です。
|
||||
|
||||
この文書は、なぜこの革命が必要だったのか、どのような思想の元に設計されたのかを詳しく解説します。
|
||||
|
||||
## 🚨 問題の発見:暗黙の悪魔
|
||||
|
||||
### HashMap::insert による意図しない上書き
|
||||
|
||||
Nyashの実装を詳しく調査した結果、恐ろしい問題が発見されました:
|
||||
|
||||
```rust
|
||||
// instance.rs - add_method関数
|
||||
pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) {
|
||||
let mut new_methods = (*self.methods).clone();
|
||||
new_methods.insert(method_name, method_ast); // ← 暗黙の上書き!
|
||||
self.methods = Arc::new(new_methods);
|
||||
}
|
||||
```
|
||||
|
||||
この実装により、以下のような**暗黙のオーバーライド**が発生していました:
|
||||
|
||||
```nyash
|
||||
box Node {
|
||||
send(msg) { // 最初の定義
|
||||
print("Version 1")
|
||||
}
|
||||
|
||||
send(msg) { // 暗黙に上書きされる
|
||||
print("Version 2") // ← こちらだけが残る
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Nyash哲学との根本的矛盾
|
||||
|
||||
この問題は、Nyashの3つの核心哲学と完全に矛盾していました:
|
||||
|
||||
1. **明示性重視**: 「何が起きているかを隠さない」
|
||||
2. **Everything is Box**: 「統一された世界観」
|
||||
3. **初学者フレンドリー**: 「複雑な概念を分かりやすく表現」
|
||||
|
||||
暗黙のオーバーライドは、これらすべてを破壊する**言語設計上の致命的欠陥**だったのです。
|
||||
|
||||
## 💡 解決への道:3AI大会議
|
||||
|
||||
### AI専門家による徹底分析
|
||||
|
||||
この問題の解決策を求めて、言語設計の専門家であるGeminiとChatGPTに相談を行いました。結果は予想を上回る**圧倒的な支持**でした。
|
||||
|
||||
#### Gemini先生の評価
|
||||
> **「全面的に賛成します」**
|
||||
> **「極めて重要な一歩」**
|
||||
> **「Nyashのアイデンティティを確立する」**
|
||||
|
||||
#### ChatGPT先生の評価
|
||||
> **「強く整合する」**
|
||||
> **「安全性と読みやすさを大幅に向上」**
|
||||
> **「実装工数3-5日程度」**
|
||||
|
||||
### 専門的視点からの裏付け
|
||||
|
||||
両専門家から以下の重要な指摘がありました:
|
||||
|
||||
1. **哲学的整合性**: Nyashの明示性哲学と完全に合致
|
||||
2. **技術的優位性**: 他言語の問題(Python MRO、Java super等)を根本解決
|
||||
3. **学習効果**: 初学者にとってより理解しやすい設計
|
||||
4. **実装可能性**: 技術的に十分実現可能
|
||||
|
||||
## 🌟 革命的解決策:Override + From 統一構文
|
||||
|
||||
### 4つの統一原則
|
||||
|
||||
この問題を解決するため、以下の4つの統一原則を確立しました:
|
||||
|
||||
#### 1. 宣言の統一
|
||||
```nyash
|
||||
box Child from Parent // デリゲーション関係の明示
|
||||
```
|
||||
|
||||
#### 2. 置換の統一
|
||||
```nyash
|
||||
override methodName() // オーバーライドの明示宣言
|
||||
```
|
||||
|
||||
#### 3. 呼び出しの統一
|
||||
```nyash
|
||||
from Parent.methodName() // 親実装の明示呼び出し
|
||||
```
|
||||
|
||||
#### 4. 構築の統一
|
||||
```nyash
|
||||
from Parent.init() // コンストラクタも同じ構文
|
||||
```
|
||||
|
||||
### 完全な例
|
||||
|
||||
```nyash
|
||||
box MeshNode : P2PBox {
|
||||
init routing = RoutingTable()
|
||||
|
||||
constructor(nodeId, world) {
|
||||
from P2PBox.constructor(nodeId, world) // 統一構文
|
||||
me.routing = RoutingTable()
|
||||
}
|
||||
|
||||
override send(intent, data, target) { // 明示的置換
|
||||
me.routing.log(target)
|
||||
from P2PBox.send(intent, data, target) // 明示的呼び出し
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔥 革命的特徴
|
||||
|
||||
### 1. 完全な明示性
|
||||
|
||||
**従来の問題**:
|
||||
- 何がオーバーライドされているかわからない
|
||||
- 親のどのメソッドを呼んでいるかわからない
|
||||
- 実行順序が不明確
|
||||
|
||||
**Nyashの解決**:
|
||||
- `override` で置換を明示宣言
|
||||
- `from Parent.method()` で呼び出し先を完全明示
|
||||
- 上から下への直感的な実行順序
|
||||
|
||||
### 2. 曖昧性の完全排除
|
||||
|
||||
**多重デリゲーション時の曖昧性解消**:
|
||||
```nyash
|
||||
box SmartNode : P2PBox, Logger {
|
||||
override send(intent, data, target) {
|
||||
from Logger.debug("Sending: " + intent) // どのLoggerか明確
|
||||
from P2PBox.send(intent, data, target) // どのP2PBoxか明確
|
||||
}
|
||||
}
|
||||
|
||||
// 競合時は更に明示的に
|
||||
box ConflictNode from ParentA, ParentB {
|
||||
override ParentA.process(data) { // ParentAのprocessを置換
|
||||
from ParentA.process(data)
|
||||
}
|
||||
|
||||
override ParentB.process(data) { // ParentBのprocessを置換
|
||||
from ParentB.process(data)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 学習コストの最小化
|
||||
|
||||
**覚えるべきルール**:
|
||||
1. 親のメソッドを置換したい → `override`
|
||||
2. 親のメソッドを呼びたい → `from Parent.method()`
|
||||
3. 親のコンストラクタを呼びたい → `from Parent.init()`
|
||||
|
||||
たった3つのルールで、すべてのデリゲーション操作が表現できます。
|
||||
|
||||
## 🌍 他言語との比較:なぜNyashが優れているのか
|
||||
|
||||
### Python の問題
|
||||
```python
|
||||
# MRO(Method Resolution Order)地獄
|
||||
class C(A, B):
|
||||
def method(self):
|
||||
super().method() # どっちのmethod?
|
||||
```
|
||||
|
||||
**Nyash の解決**:
|
||||
```nyash
|
||||
box C : A, B {
|
||||
override method() {
|
||||
from A.method() // Aのmethodと明示
|
||||
from B.method() // Bのmethodと明示
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Java/C# の問題
|
||||
```java
|
||||
// どの親のmethodを呼んでいるかコードから不明
|
||||
@Override
|
||||
public void method() {
|
||||
super.method(); // 単一継承でも曖昧
|
||||
}
|
||||
```
|
||||
|
||||
**Nyash の解決**:
|
||||
```nyash
|
||||
override method() {
|
||||
from Parent.method() // どのParentか完全に明確
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript の問題
|
||||
```typescript
|
||||
// 暗黙のオーバーライドによる事故
|
||||
class Child extends Parent {
|
||||
method() { // うっかり同名メソッド → 意図しない上書き
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Nyash の解決**:
|
||||
```nyash
|
||||
// overrideなしで同名メソッド → コンパイルエラー
|
||||
// 意図しない上書きは100%防止
|
||||
```
|
||||
|
||||
## 🎯 設計思想の深層
|
||||
|
||||
### Everything is Box との統合
|
||||
|
||||
この革命は、Nyashの根本思想「Everything is Box」と完全に統合されています:
|
||||
|
||||
- **Box同士のデリゲーション**: 階層ではなく、協力関係
|
||||
- **Boxメソッドの明示的管理**: どのBoxのどのメソッドかが常に明確
|
||||
- **Box構築の明示的制御**: コンストラクタも普通のメソッド
|
||||
|
||||
### 明示性の哲学
|
||||
|
||||
Nyashが目指すのは、**「魔法のない言語」**です:
|
||||
|
||||
- 隠れた処理は一切なし
|
||||
- すべての動作がコードに現れる
|
||||
- 初学者でも上級者でも同じように理解できる
|
||||
|
||||
### 初学者への配慮
|
||||
|
||||
複雑な概念を、シンプルな文法で表現:
|
||||
|
||||
- `override` = 「置き換えます」
|
||||
- `from Parent.method()` = 「親の方法を使います」
|
||||
- コンパイルエラー = 「間違いを素早く教える」
|
||||
|
||||
## 🚀 実装戦略
|
||||
|
||||
### 段階的導入
|
||||
|
||||
ChatGPT先生の提案による実装ロードマップ:
|
||||
|
||||
**Phase 1(0.5-1日)**:
|
||||
- `override` キーワード追加
|
||||
- 基本パーサー拡張
|
||||
|
||||
**Phase 2(1-2日)**:
|
||||
- 暗黙オーバーライド検出
|
||||
- コンストラクタ重複禁止
|
||||
|
||||
**Phase 3(1日)**:
|
||||
- `from Parent.init()` 実装
|
||||
- エラーメッセージ改善
|
||||
|
||||
### 移行支援
|
||||
|
||||
既存コードの安全な移行:
|
||||
- 段階的警告システム
|
||||
- 自動修正支援ツール
|
||||
- 詳細な移行ガイド
|
||||
|
||||
## 🌟 期待される効果
|
||||
|
||||
### 1. 開発者体験の革命的向上
|
||||
|
||||
**Before(暗黙オーバーライド)**:
|
||||
- バグの発見が困難
|
||||
- 意図しない動作
|
||||
- デバッグに多大な時間
|
||||
|
||||
**After(明示的オーバーライド)**:
|
||||
- コンパイル時に間違いを検出
|
||||
- 意図が明確に表現される
|
||||
- デバッグ時間の劇的短縮
|
||||
|
||||
### 2. コードの可読性向上
|
||||
|
||||
**Before**:
|
||||
```nyash
|
||||
// これは何をオーバーライドしている?
|
||||
send(msg) {
|
||||
// 親を呼んでる?呼んでない?
|
||||
processMessage(msg)
|
||||
}
|
||||
```
|
||||
|
||||
**After**:
|
||||
```nyash
|
||||
// P2PBoxのsendを明示的にオーバーライド
|
||||
override send(msg) {
|
||||
processMessage(msg)
|
||||
from P2PBox.send(msg) // P2PBoxの実装も使用
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 保守性の向上
|
||||
|
||||
- 変更の影響範囲が明確
|
||||
- リファクタリングが安全
|
||||
- チーム開発での誤解を防止
|
||||
|
||||
## 🏆 結論:言語設計史に残る革命
|
||||
|
||||
この明示的デリゲーション革命により、Nyashは以下を達成しました:
|
||||
|
||||
### 世界初の完全明示デリゲーション言語
|
||||
|
||||
1. **完全な明示性**: すべての動作を明示
|
||||
2. **曖昧性の完全排除**: どんな複雑なケースも明確
|
||||
3. **統一構文**: デリゲーションとオーバーライドの完全統合
|
||||
4. **初学者フレンドリー**: 学習しやすく、間違いにくい
|
||||
|
||||
### プログラミング言語設計への貢献
|
||||
|
||||
- **暗黙の悪魔**からの完全な解放
|
||||
- **多重デリゲーション**の安全で明確な実現
|
||||
- **コード可読性**の新しい基準の確立
|
||||
|
||||
### 未来への影響
|
||||
|
||||
Nyashのこの革命は、今後のプログラミング言語設計に大きな影響を与えるでしょう。「暗黙より明示」という哲学が、ついに技術的に完全実現されたのです。
|
||||
|
||||
---
|
||||
|
||||
**2025年8月11日は、プログラミング言語史において「明示的デリゲーション革命の日」として記憶されることでしょう。** 🎊
|
||||
|
||||
この革命により、Nyashは単なるプログラミング言語を超えて、**新しいプログラミングパラダイムの先駆者**となりました。
|
||||
|
||||
Everything is Box. Everything is Explicit. Everything is Beautiful. 🌟
|
||||
150
docs/archive/design/DELEGATION_DESIGN_SUMMARY.md
Normal file
150
docs/archive/design/DELEGATION_DESIGN_SUMMARY.md
Normal file
@ -0,0 +1,150 @@
|
||||
# 🎯 Nyash デリゲーション設計サマリー
|
||||
|
||||
作成日: 2025年8月10日
|
||||
状態: 設計完了・実装待ち
|
||||
|
||||
## 🎉 決定事項
|
||||
|
||||
### **基本方針**
|
||||
- ✅ **継承完全廃止** → デリゲーション全面移行
|
||||
- ✅ **Everything is Box哲学維持**
|
||||
- ✅ **明示性重視の文法**
|
||||
|
||||
### **最終採用文法**
|
||||
```nyash
|
||||
// 基本形式(80%のケース)
|
||||
box MeshNode extends P2PBox {
|
||||
init routing = RoutingTable()
|
||||
|
||||
constructor(nodeId, world) {
|
||||
super(nodeId, world) // super解禁!
|
||||
me.routing = RoutingTable()
|
||||
}
|
||||
|
||||
override send(intent, data, target) {
|
||||
me.routing.log(target)
|
||||
super.send(intent, data, target) // 直感的
|
||||
}
|
||||
}
|
||||
|
||||
// 複数デリゲーション(20%のケース)
|
||||
box ComplexNode extends P2PBox {
|
||||
init cache = CacheBox()
|
||||
|
||||
delegates cache // 追加デリゲーション
|
||||
|
||||
override send(intent, data, target) {
|
||||
me.cache.store(intent, data)
|
||||
super.send(intent, data, target)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🌟 3AI大会議結果
|
||||
|
||||
### **参加者**
|
||||
- 🤖 Claude(司会・バランス調整)
|
||||
- 🌟 Gemini(ユーザー体験重視)
|
||||
- 💻 ChatGPT(技術実装重視)
|
||||
|
||||
### **提案比較**
|
||||
| 提案者 | 文法 | 特徴 |
|
||||
|--------|------|------|
|
||||
| Gemini | `delegates to self.pos` | シンプル・直感的 |
|
||||
| ChatGPT | `delegate repo exposes API` | 細かい制御・柔軟性 |
|
||||
| **採用案** | `extends` + `super` | 馴染みやすさ・学習コスト最小 |
|
||||
|
||||
## 🚀 実装すべき機能
|
||||
|
||||
### **Phase 1: 基本デリゲーション(最優先)**
|
||||
```nyash
|
||||
box SimpleWrapper extends SomeBox {
|
||||
constructor(args) {
|
||||
super(args) // 基底初期化
|
||||
}
|
||||
|
||||
override method() {
|
||||
super.method() // 元実装呼び出し
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Phase 2: 複数デリゲーション(中期)**
|
||||
```nyash
|
||||
box ComplexWrapper extends PrimaryBox {
|
||||
init secondary = SecondaryBox()
|
||||
|
||||
delegates secondary
|
||||
delegates tertiary only { save, load } // 選択的
|
||||
}
|
||||
```
|
||||
|
||||
## 🛠️ 実装方針
|
||||
|
||||
### **内部実装**
|
||||
- `extends`は実際にはデリゲーション
|
||||
- `super`は内部フィールドへの参照
|
||||
- 自動メソッド転送生成
|
||||
|
||||
### **ASTノード追加**
|
||||
```rust
|
||||
// ASTに追加すべき要素
|
||||
BoxDeclaration {
|
||||
extends: Option<String>, // extends PrimaryBox
|
||||
delegates: Vec<String>, // delegates field1, field2
|
||||
}
|
||||
|
||||
// superキーワード対応
|
||||
SuperCall {
|
||||
method: String,
|
||||
arguments: Vec<Expression>,
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 期待効果
|
||||
|
||||
### **NyaMeshライブラリでの改善**
|
||||
```nyash
|
||||
// Before: 20行以上の手動ラッピング
|
||||
box MeshNode {
|
||||
// 全メソッド手動転送...
|
||||
send(...) { return me.p2p.send(...) }
|
||||
broadcast(...) { return me.p2p.broadcast(...) }
|
||||
// ...
|
||||
}
|
||||
|
||||
// After: 5行程度
|
||||
box MeshNode extends P2PBox {
|
||||
override send(intent, data, target) {
|
||||
me.routing.log(target)
|
||||
super.send(intent, data, target)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**改善率**: 75%以上のコード削減
|
||||
|
||||
## 🎯 次のステップ
|
||||
|
||||
### **実装優先度**
|
||||
1. 🔥 **`extends`構文追加**(パーサー・AST)
|
||||
2. 🔥 **`super`キーワード解禁**(インタープリター)
|
||||
3. 🔥 **自動メソッド転送**(メソッド解決)
|
||||
4. 🟡 **複数delegates**(将来拡張)
|
||||
|
||||
### **技術的課題**
|
||||
- [ ] ASTにextends/super追加
|
||||
- [ ] superの型チェック・安全性
|
||||
- [ ] メソッド転送の実装
|
||||
- [ ] テストスイート作成
|
||||
|
||||
## 📝 設計哲学
|
||||
|
||||
> 「継承の表現力を、デリゲーションの安全性で実現する」
|
||||
|
||||
- **見た目は継承**:学習コストを最小化
|
||||
- **実装はデリゲーション**:安全性を確保
|
||||
- **Everything is Box**:一貫した設計哲学
|
||||
|
||||
---
|
||||
**次回作業開始時の参照用サマリー完了** 🎉
|
||||
565
docs/archive/design/NYASHFLOW_PROJECT_HANDOVER.md
Normal file
565
docs/archive/design/NYASHFLOW_PROJECT_HANDOVER.md
Normal file
@ -0,0 +1,565 @@
|
||||
# 🎨 NyashFlow プロジェクト引き継ぎドキュメント
|
||||
|
||||
## 📅 作成日: 2025-01-09
|
||||
## 👤 作成者: Claude + ユーザー(にゃ〜)
|
||||
|
||||
---
|
||||
|
||||
# 🌟 プロジェクト概要
|
||||
|
||||
## 🎯 NyashFlowとは
|
||||
**Nyashプログラミング言語のビジュアルプログラミング環境**
|
||||
- 「Everything is Box」の哲学を視覚的に表現
|
||||
- Boxをドラッグ&ドロップでつなげてプログラミング
|
||||
- 教育的価値の高いツールを目指す
|
||||
|
||||
## 🚀 プロジェクトの経緯
|
||||
|
||||
### 1️⃣ **始まり:egui研究**
|
||||
- NyashにGUI機能(EguiBox)を実装
|
||||
- Windows版メモ帳、エクスプローラー風アプリを作成
|
||||
- BMPアイコン表示まで成功
|
||||
|
||||
### 2️⃣ **ビジュアルプログラミングへの発展**
|
||||
- eguiの可能性を探る中で、ノードベースUIの構想が生まれる
|
||||
- 「Everything is Box」を視覚化するアイデア
|
||||
- 教育現場での活用を想定
|
||||
|
||||
### 3️⃣ **CharmFlow v5からの学び**
|
||||
- ユーザーが以前作成した大規模プロジェクト
|
||||
- JavaScript + NyaMesh(P2P)で実装
|
||||
- **失敗から学んだこと**:
|
||||
- カプセル化の欠如 → スパゲティコード化
|
||||
- 役割分担の不明確 → 保守困難
|
||||
- 過剰な機能 → 複雑化
|
||||
|
||||
### 4️⃣ **NyashFlowの方向性決定**
|
||||
- Rust + WebAssemblyで実装
|
||||
- Nyashとは別プロジェクトとして独立
|
||||
- シンプルさを最優先
|
||||
|
||||
---
|
||||
|
||||
# 🏗️ 技術設計
|
||||
|
||||
## 📐 アーキテクチャ
|
||||
|
||||
### **基本構成**
|
||||
```
|
||||
nyashflow/
|
||||
├── Cargo.toml # プロジェクト設定
|
||||
├── src/
|
||||
│ ├── lib.rs # ライブラリエントリ
|
||||
│ ├── main.rs # デスクトップ版エントリ
|
||||
│ ├── visual/ # 🎨 ビジュアル表示層
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── node_renderer.rs # ノード描画
|
||||
│ │ ├── connection_renderer.rs # 接続線描画
|
||||
│ │ └── canvas_manager.rs # キャンバス管理
|
||||
│ ├── execution/ # ⚡ 実行エンジン層
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── interpreter_bridge.rs # Nyashインタープリタ連携
|
||||
│ │ └── data_flow.rs # データフロー管理
|
||||
│ ├── interaction/ # 🖱️ ユーザー操作層
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── drag_drop.rs # ドラッグ&ドロップ
|
||||
│ │ ├── selection.rs # 選択処理
|
||||
│ │ └── context_menu.rs # 右クリックメニュー
|
||||
│ ├── model/ # 📦 データモデル層
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── visual_node.rs # ノード定義
|
||||
│ │ ├── connection.rs # 接続定義
|
||||
│ │ └── project.rs # プロジェクト管理
|
||||
│ └── wasm/ # 🌐 WebAssembly層
|
||||
│ ├── mod.rs
|
||||
│ └── bridge.rs # JS連携
|
||||
├── web/ # 🌐 Web用リソース
|
||||
│ ├── index.html
|
||||
│ ├── style.css
|
||||
│ └── pkg/ # wasm-pack出力
|
||||
└── examples/ # 📚 サンプル
|
||||
└── basic_flow.rs
|
||||
```
|
||||
|
||||
### **設計原則**
|
||||
|
||||
#### 1. **徹底的なカプセル化**
|
||||
```rust
|
||||
pub struct VisualNode {
|
||||
// 🔒 すべてプライベート
|
||||
id: NodeId,
|
||||
node_type: BoxType,
|
||||
position: Pos2,
|
||||
#[serde(skip)]
|
||||
internal_state: NodeState,
|
||||
}
|
||||
|
||||
impl VisualNode {
|
||||
// 🌍 公開APIは最小限
|
||||
pub fn get_id(&self) -> NodeId { self.id }
|
||||
pub fn get_type(&self) -> &BoxType { &self.node_type }
|
||||
pub fn set_position(&mut self, pos: Pos2) {
|
||||
// バリデーション付き
|
||||
if self.validate_position(pos) {
|
||||
self.position = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. **明確な責任分離**
|
||||
```rust
|
||||
// ❌ 悪い例(CharmFlowの失敗)
|
||||
impl EverythingManager {
|
||||
fn handle_everything(&mut self, event: Event) {
|
||||
// 描画もイベントも実行も全部...
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 良い例(単一責任)
|
||||
impl NodeRenderer {
|
||||
pub fn render(&self, node: &VisualNode, ui: &mut Ui) {
|
||||
// 描画だけ!
|
||||
}
|
||||
}
|
||||
|
||||
impl DragDropHandler {
|
||||
pub fn handle_drag(&mut self, event: DragEvent) {
|
||||
// ドラッグ処理だけ!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. **コード品質の維持**
|
||||
- 各ファイル100行以内を目標
|
||||
- 関数は30行以内
|
||||
- ネストは3階層まで
|
||||
- 必ずテストを書く
|
||||
|
||||
---
|
||||
|
||||
# 💻 実装詳細
|
||||
|
||||
## 🎨 ビジュアルノードシステム
|
||||
|
||||
### **ノードの種類(初期実装)**
|
||||
```rust
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum BoxType {
|
||||
// 基本Box
|
||||
StringBox,
|
||||
IntegerBox,
|
||||
BoolBox,
|
||||
|
||||
// 操作Box
|
||||
MathBox,
|
||||
ConsoleBox,
|
||||
|
||||
// コンテナBox
|
||||
ArrayBox,
|
||||
}
|
||||
|
||||
impl BoxType {
|
||||
pub fn color(&self) -> Color32 {
|
||||
match self {
|
||||
BoxType::StringBox => Color32::from_rgb(100, 149, 237),
|
||||
BoxType::IntegerBox => Color32::from_rgb(144, 238, 144),
|
||||
BoxType::MathBox => Color32::from_rgb(255, 182, 193),
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
pub fn icon(&self) -> &str {
|
||||
match self {
|
||||
BoxType::StringBox => "📝",
|
||||
BoxType::IntegerBox => "🔢",
|
||||
BoxType::MathBox => "🧮",
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **接続システム**
|
||||
```rust
|
||||
pub struct Connection {
|
||||
id: ConnectionId,
|
||||
from_node: NodeId,
|
||||
from_port: PortId,
|
||||
to_node: NodeId,
|
||||
to_port: PortId,
|
||||
}
|
||||
|
||||
pub struct Port {
|
||||
id: PortId,
|
||||
name: String,
|
||||
port_type: PortType,
|
||||
data_type: DataType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PortType {
|
||||
Input,
|
||||
Output,
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 実行エンジン
|
||||
|
||||
### **Nyashインタープリタ連携**
|
||||
```rust
|
||||
use nyash::interpreter::{NyashInterpreter, NyashValue};
|
||||
|
||||
pub struct ExecutionEngine {
|
||||
interpreter: NyashInterpreter,
|
||||
node_mapping: HashMap<NodeId, String>, // NodeId → Nyash変数名
|
||||
}
|
||||
|
||||
impl ExecutionEngine {
|
||||
pub fn execute_flow(&mut self, nodes: &[VisualNode], connections: &[Connection]) -> Result<(), ExecutionError> {
|
||||
// 1. トポロジカルソート
|
||||
let sorted_nodes = self.topological_sort(nodes, connections)?;
|
||||
|
||||
// 2. Nyashコード生成
|
||||
let nyash_code = self.generate_nyash_code(&sorted_nodes, connections);
|
||||
|
||||
// 3. 実行
|
||||
self.interpreter.execute(&nyash_code)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🌐 WebAssembly統合
|
||||
|
||||
### **WASM Bridge**
|
||||
```rust
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct NyashFlowApp {
|
||||
#[wasm_bindgen(skip)]
|
||||
nodes: Vec<VisualNode>,
|
||||
#[wasm_bindgen(skip)]
|
||||
connections: Vec<Connection>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl NyashFlowApp {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> Self {
|
||||
console_error_panic_hook::set_once();
|
||||
Self {
|
||||
nodes: vec![],
|
||||
connections: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_node(&mut self, node_type: &str, x: f32, y: f32) -> u32 {
|
||||
// ノード追加処理
|
||||
}
|
||||
|
||||
pub fn connect_nodes(&mut self, from_id: u32, to_id: u32) -> Result<(), JsValue> {
|
||||
// 接続処理
|
||||
}
|
||||
|
||||
pub fn execute(&self) -> Result<String, JsValue> {
|
||||
// 実行処理
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 🚀 開発ロードマップ
|
||||
|
||||
## Phase 1: MVP(1-2週間)
|
||||
- [ ] 基本的なノード表示
|
||||
- [ ] 3種類のBox(String, Integer, Console)
|
||||
- [ ] ドラッグでノード移動
|
||||
- [ ] 接続線の表示
|
||||
- [ ] 簡単な実行(ConsoleBoxでprint)
|
||||
|
||||
## Phase 2: 基本機能(2-3週間)
|
||||
- [ ] 全基本Boxタイプ実装
|
||||
- [ ] 接続の作成/削除
|
||||
- [ ] 右クリックメニュー
|
||||
- [ ] プロジェクト保存/読み込み(JSON)
|
||||
- [ ] 実行結果の表示
|
||||
|
||||
## Phase 3: WebAssembly対応(2週間)
|
||||
- [ ] wasm-pack設定
|
||||
- [ ] Web用UI調整
|
||||
- [ ] ブラウザでの動作確認
|
||||
- [ ] GitHubPages公開
|
||||
|
||||
## Phase 4: 高度な機能(1ヶ月)
|
||||
- [ ] カスタムBox作成
|
||||
- [ ] デバッグ機能(ステップ実行)
|
||||
- [ ] アニメーション(データフロー可視化)
|
||||
- [ ] テンプレート機能
|
||||
|
||||
---
|
||||
|
||||
# 📝 実装上の注意点
|
||||
|
||||
## ⚠️ CharmFlowの失敗を避ける
|
||||
|
||||
### 1. **過剰な機能を避ける**
|
||||
- P2P通信 → 不要
|
||||
- プラグインシステム → Phase 4以降
|
||||
- 複雑なIntent → 直接的なデータフロー
|
||||
|
||||
### 2. **コードレビューポイント**
|
||||
```rust
|
||||
// 毎回チェック
|
||||
- [ ] ファイルが100行を超えていないか?
|
||||
- [ ] 関数が30行を超えていないか?
|
||||
- [ ] Private Fieldsを使っているか?
|
||||
- [ ] 責任が単一か?
|
||||
- [ ] テストを書いたか?
|
||||
```
|
||||
|
||||
### 3. **定期的なリファクタリング**
|
||||
- 週1回はコード全体を見直す
|
||||
- 重複を見つけたら即座に統合
|
||||
- 複雑になったら分割
|
||||
|
||||
## 🧪 テスト戦略
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_node_creation() {
|
||||
let node = VisualNode::new(BoxType::StringBox, Pos2::new(100.0, 100.0));
|
||||
assert_eq!(node.get_type(), &BoxType::StringBox);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_connection_validation() {
|
||||
// StringBox → ConsoleBoxは接続可能
|
||||
assert!(Connection::can_connect(
|
||||
&BoxType::StringBox,
|
||||
&PortType::Output,
|
||||
&BoxType::ConsoleBox,
|
||||
&PortType::Input
|
||||
));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 🎯 成功の指標
|
||||
|
||||
## 定量的指標
|
||||
- コード行数:5,000行以内(CharmFlowの1/10)
|
||||
- ファイル数:50個以内
|
||||
- テストカバレッジ:80%以上
|
||||
- 起動時間:1秒以内
|
||||
|
||||
## 定性的指標
|
||||
- 小学生でも使える直感性
|
||||
- Nyashの哲学が伝わる
|
||||
- メンテナンスが苦にならない
|
||||
- 拡張が容易
|
||||
|
||||
---
|
||||
|
||||
# 🔗 参考資料
|
||||
|
||||
## 技術資料
|
||||
- [egui公式ドキュメント](https://docs.rs/egui)
|
||||
- [wasm-bindgen book](https://rustwasm.github.io/wasm-bindgen/)
|
||||
- [Nyashプロジェクト](../../../README.md)
|
||||
|
||||
## 設計思想
|
||||
- CharmFlow v5の経験(反面教師)
|
||||
- 「Everything is Box」哲学
|
||||
- シンプル・イズ・ベスト
|
||||
|
||||
## 類似プロジェクト
|
||||
- Scratch(教育的UI)
|
||||
- Node-RED(フロープログラミング)
|
||||
- Unreal Engine Blueprint(ゲーム向け)
|
||||
|
||||
---
|
||||
|
||||
# 💬 最後に
|
||||
|
||||
このプロジェクトは「プログラミングを視覚的に理解する」という夢を実現するものです。
|
||||
|
||||
CharmFlowの失敗から学び、Nyashの哲学を活かし、シンプルで美しいツールを作りましょう。
|
||||
|
||||
**「Everything is Box」が「Everything is Visible Box」になる瞬間を楽しみにしています!**
|
||||
|
||||
にゃ〜🎨✨
|
||||
|
||||
---
|
||||
|
||||
# 🔮 P2PBox/intentbox設計の活用(2025-01-09追記)
|
||||
|
||||
## 🎯 NyaMesh設計から学ぶこと
|
||||
|
||||
### **核心概念の抽出**
|
||||
|
||||
NyaMeshの`P2PBox`と`intentbox`から、NyashFlowに活用できる**本質的な設計思想**:
|
||||
|
||||
1. **intentbox = 通信世界の定義**
|
||||
- プロセス内、WebSocket、メモリ共有など
|
||||
- 通信の「場」を抽象化
|
||||
|
||||
2. **P2PBox = その世界に参加するノード**
|
||||
- どのintentboxに所属するかで通信相手が決まる
|
||||
- シンプルなsend/onインターフェース
|
||||
|
||||
### **NyashFlowへの応用(シンプル版)**
|
||||
|
||||
```rust
|
||||
// ⚡ ローカル実行モード(Phase 1-2)
|
||||
pub struct LocalExecutionContext {
|
||||
// ビジュアルノード間のデータフロー管理
|
||||
data_bus: DataFlowBus,
|
||||
}
|
||||
|
||||
// 🌐 将来の拡張(Phase 4以降)
|
||||
pub trait ExecutionContext {
|
||||
fn send_data(&mut self, from: NodeId, to: NodeId, data: NyashValue);
|
||||
fn on_data(&mut self, node: NodeId, callback: DataCallback);
|
||||
}
|
||||
|
||||
// 異なる実行コンテキストの実装例
|
||||
impl ExecutionContext for LocalExecutionContext { ... }
|
||||
impl ExecutionContext for RemoteExecutionContext { ... } // WebSocket経由
|
||||
impl ExecutionContext for SharedMemoryContext { ... } // 高速共有メモリ
|
||||
```
|
||||
|
||||
### **段階的な導入計画**
|
||||
|
||||
#### Phase 1-2: シンプルなデータフロー
|
||||
```rust
|
||||
// 最初はシンプルに
|
||||
pub struct DataFlowEngine {
|
||||
nodes: HashMap<NodeId, VisualNode>,
|
||||
connections: Vec<Connection>,
|
||||
}
|
||||
|
||||
impl DataFlowEngine {
|
||||
pub fn execute(&mut self) {
|
||||
// 単純な同期実行
|
||||
for connection in &self.connections {
|
||||
let data = self.get_output_data(connection.from_node);
|
||||
self.set_input_data(connection.to_node, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Phase 3-4: 抽象化された実行コンテキスト
|
||||
```rust
|
||||
// P2PBox的な抽象化を導入
|
||||
pub struct VisualNodeBox {
|
||||
id: NodeId,
|
||||
context: Box<dyn ExecutionContext>, // どの「世界」で実行するか
|
||||
}
|
||||
|
||||
impl VisualNodeBox {
|
||||
pub fn send(&self, data: NyashValue, to: NodeId) {
|
||||
self.context.send_data(self.id, to, data);
|
||||
}
|
||||
|
||||
pub fn on_receive<F>(&mut self, callback: F)
|
||||
where F: Fn(NyashValue) + 'static {
|
||||
self.context.on_data(self.id, Box::new(callback));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **実用的な応用例**
|
||||
|
||||
#### 1. **マルチスレッド実行(ローカル)**
|
||||
```rust
|
||||
// 重い処理を別スレッドで
|
||||
let math_context = ThreadedExecutionContext::new();
|
||||
let math_node = VisualNodeBox::new(BoxType::MathBox, math_context);
|
||||
```
|
||||
|
||||
#### 2. **リアルタイムコラボレーション(将来)**
|
||||
```rust
|
||||
// WebSocketで他のユーザーと共有
|
||||
let collab_context = WebSocketContext::new("wss://nyashflow.example.com");
|
||||
let shared_node = VisualNodeBox::new(BoxType::SharedBox, collab_context);
|
||||
```
|
||||
|
||||
#### 3. **デバッグモード**
|
||||
```rust
|
||||
// すべてのデータフローを記録
|
||||
let debug_context = RecordingContext::new();
|
||||
// 後でデータフローを再生・分析可能
|
||||
```
|
||||
|
||||
### **設計上の重要な判断**
|
||||
|
||||
1. **最初はローカル実行のみ**
|
||||
- P2P機能は作らない(CharmFlowの教訓)
|
||||
- でも将来の拡張性は確保
|
||||
|
||||
2. **インターフェースの統一**
|
||||
- send/onのシンプルなAPIを維持
|
||||
- 実行コンテキストは隠蔽
|
||||
|
||||
3. **段階的な複雑性**
|
||||
- Phase 1-2: 同期的なローカル実行
|
||||
- Phase 3: 非同期実行対応
|
||||
- Phase 4: リモート実行(必要なら)
|
||||
|
||||
### **実装の指針**
|
||||
|
||||
```rust
|
||||
// ❌ 避けるべき実装(CharmFlow的)
|
||||
struct EverythingNode {
|
||||
p2p_manager: P2PManager,
|
||||
intent_bus: IntentBus,
|
||||
websocket: WebSocket,
|
||||
// ... 100個の機能
|
||||
}
|
||||
|
||||
// ✅ 推奨される実装(NyashFlow的)
|
||||
struct VisualNode {
|
||||
data: NodeData,
|
||||
// 実行コンテキストは外部から注入
|
||||
}
|
||||
|
||||
struct ExecutionEngine {
|
||||
context: Box<dyn ExecutionContext>,
|
||||
// コンテキストを差し替え可能
|
||||
}
|
||||
```
|
||||
|
||||
### **まとめ:「いいとこ取り」の精神**
|
||||
|
||||
- **P2PBox/intentboxの優れた抽象化**を参考に
|
||||
- **最初はシンプルに**実装
|
||||
- **将来の拡張性**を設計に組み込む
|
||||
- **過剰な機能は避ける**
|
||||
|
||||
これにより、NyashFlowは:
|
||||
- 初期は単純なビジュアルプログラミング環境
|
||||
- 必要に応じて高度な実行モデルに拡張可能
|
||||
- CharmFlowの失敗を繰り返さない
|
||||
|
||||
---
|
||||
|
||||
## 📋 チェックリスト(開発開始時)
|
||||
|
||||
- [ ] このドキュメントを読み終えた
|
||||
- [ ] Nyashプロジェクトをビルドできる
|
||||
- [ ] eguiのサンプルを動かした
|
||||
- [ ] プロジェクトフォルダを作成した
|
||||
- [ ] 最初のコミットをした
|
||||
|
||||
頑張ってにゃ〜!🚀
|
||||
148
docs/archive/design/PHILOSOPHY.md
Normal file
148
docs/archive/design/PHILOSOPHY.md
Normal file
@ -0,0 +1,148 @@
|
||||
# 🌟 Nyash - Everything is Box 哲学
|
||||
|
||||
## 核心原則(絶対に忘れてはならない)
|
||||
|
||||
### 1. すべてはBox
|
||||
```nyash
|
||||
// データもBox
|
||||
name = new StringBox("Alice")
|
||||
age = new IntegerBox(30)
|
||||
items = new ArrayBox()
|
||||
|
||||
// 関数もBox(革命的発見!)
|
||||
add = new FunctionBox("add", ["a", "b"], {
|
||||
return a + b
|
||||
})
|
||||
|
||||
// クラスもBox
|
||||
Person = new ClassBox("Person", {
|
||||
fields: ["name", "age"],
|
||||
methods: { greet: ... }
|
||||
})
|
||||
|
||||
// 制御構造もBox(whileは使わない!)
|
||||
myLoop = new LoopBox({
|
||||
condition: i < 10,
|
||||
body: { print(i) }
|
||||
})
|
||||
|
||||
// 条件分岐もBox
|
||||
check = new IfBox({
|
||||
test: score > 80,
|
||||
then: { print("Excellent!") },
|
||||
else: { print("Keep trying!") }
|
||||
})
|
||||
|
||||
// エラーもBox
|
||||
error = new ErrorBox("Something went wrong")
|
||||
|
||||
// コンパイラ自体もBox
|
||||
tokenizer = new TokenizerBox()
|
||||
parser = new ParserBox()
|
||||
interpreter = new InterpreterBox()
|
||||
```
|
||||
|
||||
### 2. すべての操作はBox間通信
|
||||
```nyash
|
||||
// 統一されたインターフェース
|
||||
(caller >> functionBox).execute(args)
|
||||
(executor >> loopBox).run()
|
||||
(evaluator >> ifBox).check()
|
||||
(factory >> classBox).create()
|
||||
|
||||
// P2P通信
|
||||
(alice >> bob).sendMessage("Hello!")
|
||||
(source >> processor >> sink).pipeline()
|
||||
|
||||
// 非同期もBox通信
|
||||
nowait (async >> operation).execute()
|
||||
```
|
||||
|
||||
### 3. 重要な言語設計決定
|
||||
|
||||
#### ❌ 使わない構文
|
||||
- `while` ループ(代わりに `loop` を使う)
|
||||
- 従来の関数定義(代わりに `FunctionBox` を使う)
|
||||
- 生のデータ型(すべてBoxでラップ)
|
||||
|
||||
#### ✅ 使う構文
|
||||
- `loop(condition) { ... }` - LoopBox
|
||||
- `new FunctionBox(...)` - 関数定義
|
||||
- `(sender >> receiver).method()` - P2P通信
|
||||
- `nowait` - 非同期実行
|
||||
|
||||
### 4. 革命的スコープ設計(2025年8月7日 大発見!)
|
||||
|
||||
#### 🌟 すべての変数はBoxのフィールド
|
||||
```nyash
|
||||
// もう関数スコープという概念は存在しない!
|
||||
box GameEngine {
|
||||
init {
|
||||
player, // すべてフィールドとして宣言
|
||||
enemies,
|
||||
currentLevel
|
||||
}
|
||||
|
||||
createPlayer(name) {
|
||||
me.player = new Player(name) // Boxが管理
|
||||
return me.player // 完全に安全!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ✨ localキーワード - 唯一の例外
|
||||
```nyash
|
||||
// 一時変数だけは明示的にlocal
|
||||
box Algorithm {
|
||||
init { result }
|
||||
|
||||
process() {
|
||||
local i, temp // 関数終了で自動解放
|
||||
|
||||
loop(i = 0; i < 100; i++) {
|
||||
temp = calculate(i)
|
||||
me.result = me.result + temp
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**哲学的意味**:
|
||||
- Boxがすべてを管理する究極の統一性
|
||||
- 変数の寿命が明確で予測可能
|
||||
- メモリ管理の完全な透明性
|
||||
|
||||
## 歴史的洞察
|
||||
|
||||
「もしかして 関数も ボックスじゃないか???」
|
||||
|
||||
この一言がNyashを革命的な言語に変えた。関数がBoxであることで:
|
||||
- 統一されたライフサイクル管理(init/fini)
|
||||
- 関数の動的生成と操作
|
||||
- メタプログラミングの自然な実現
|
||||
- セルフホスティングへの道
|
||||
|
||||
## セルフホスティングの証明
|
||||
|
||||
Nyashの究極の証明は、Nyash自身でNyashを実装できること:
|
||||
|
||||
```nyash
|
||||
// NyashでNyashを実装
|
||||
compiler = new CompilerBox({
|
||||
tokenizer: new TokenizerBox(),
|
||||
parser: new ParserBox(),
|
||||
interpreter: new InterpreterBox()
|
||||
})
|
||||
|
||||
// セルフホスティング実行
|
||||
result = (sourceCode >> compiler).compile()
|
||||
```
|
||||
|
||||
## 忘れてはならない真実
|
||||
|
||||
1. **Everything** means EVERYTHING - 例外なし
|
||||
2. Boxは対等 - 階層ではなくP2P
|
||||
3. 統一インターフェース - 学習曲線最小化
|
||||
4. 無限の組み合わせ - BoxとBoxは自由に接続
|
||||
|
||||
> "Where Everything is Box, and Every Box is Everything!"
|
||||
103
docs/archive/design/decisions/ai_conference_overload_decision.md
Normal file
103
docs/archive/design/decisions/ai_conference_overload_decision.md
Normal file
@ -0,0 +1,103 @@
|
||||
# 🎊 AI大会議決定: 関数オーバーロード不採用 + ブロードキャスト除外
|
||||
|
||||
**日時**: 2025-08-12
|
||||
**参加**: Gemini先生・ChatGPT先生
|
||||
**議題**: Nyash P2PBox における関数オーバーロード採用可否
|
||||
|
||||
---
|
||||
|
||||
## 🏆 **最終決定**
|
||||
|
||||
### ❌ **関数オーバーロード不採用**
|
||||
- `send(a)` `send(a,b)` のような引数数による分岐は実装しない
|
||||
- 理由: Nyashの「明示性重視」哲学と矛盾、初学者混乱、実装複雑化
|
||||
|
||||
### ❌ **ブロードキャスト機能除外**
|
||||
- `broadcast(message)` 機能は実装しない
|
||||
- 理由: ネットワーク負荷・セキュリティリスク・初学者誤用防止
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **確定API仕様**
|
||||
|
||||
### ✅ **最終P2PBox API** (ブロードキャスト除外版)
|
||||
```nyash
|
||||
// 基本の個別送信(必須)
|
||||
node.send("bob", message)
|
||||
|
||||
// オプション付き個別送信(将来実装)
|
||||
node.send_with_options("bob", message, opts)
|
||||
```
|
||||
|
||||
### **使用例**
|
||||
```nyash
|
||||
// 基本使用
|
||||
local node_a = new P2PBox("alice", transport: "inprocess")
|
||||
local node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// 受信ハンドラ
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
print("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// 個別送信のみ
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // ✅ 個別送信
|
||||
// node_a.broadcast(msg) // ❌ ブロードキャストは存在しない
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎓 **AI両先生の見解**
|
||||
|
||||
### **Gemini先生**
|
||||
- **結論**: オーバーロード不採用
|
||||
- **理由**: 「明示性は最高の利便性」、初学者混乱防止
|
||||
- **推奨**: 明示的メソッド名分離
|
||||
|
||||
### **ChatGPT先生**
|
||||
- **結論**: オーバーロード不採用
|
||||
- **理由**: 技術実装複雑化、Arc<Mutex>との不整合
|
||||
- **推奨**: Rust単一backend + 明示的API
|
||||
|
||||
### **ブロードキャスト除外理由** (実戦経験に基づく重要判断)
|
||||
|
||||
**🚨 実体験による重要な教訓:**
|
||||
- **C++ nyameshでの悪夢**: AIが無意識にブロードキャストを使用
|
||||
- **無限ループ地獄**: sendデータがばらまかれ、反射して無限ループ発生
|
||||
- **何度も経験**: この問題を繰り返し体験した深刻な実害
|
||||
|
||||
**📋 技術的除外理由:**
|
||||
1. **無限ループリスク**: ブロードキャストデータの反射による暴走
|
||||
2. **P2P本質**: P2P通信は本来1対1が基本、ブロードキャスト不要
|
||||
3. **後付け可能**: 必要になったら最後に安全に追加可能
|
||||
4. **初学者保護**: 危険な機能による事故防止
|
||||
5. **AIセーフティ**: AI使用時の予期しない暴走防止
|
||||
|
||||
---
|
||||
|
||||
## 🌟 **この決定の価値**
|
||||
|
||||
### **Nyashアイデンティティ確立**
|
||||
- **明示性重視**: 何が起こるかが明確
|
||||
- **初学者ファースト**: 混乱のない学習体験
|
||||
- **安全性優先**: 危険な機能は除外
|
||||
- **シンプル美**: 必要十分な機能のみ
|
||||
|
||||
### **技術的優位性**
|
||||
- **実装シンプル**: 保守しやすいコード
|
||||
- **Rust整合性**: 言語実装との自然な統合
|
||||
- **Arc<Mutex>最適化**: 統一アーキテクチャとの親和性
|
||||
- **現代的設計**: Go・Rustと同じ先進路線
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **次のアクション**
|
||||
|
||||
1. **P2P_GUIDE.md確認**: ブロードキャスト言及の除去確認
|
||||
2. **LANGUAGE_GUIDE.md更新**: AI大会議結果反映
|
||||
3. **P2PBox実装開始**: 確定仕様でIntentBox実装開始
|
||||
|
||||
---
|
||||
|
||||
**🎉 「便利な悪魔の誘惑を退け、真の明示性を選択」 - Nyashの哲学勝利!**
|
||||
@ -0,0 +1,51 @@
|
||||
Nyashプログラミング言語のコンストラクタ設計について深い相談です。
|
||||
|
||||
【Nyashの現在の設計哲学】
|
||||
Nyashは既に「コンストラクタの明示的呼び出し」を採用しています。これは以下の理由によるものです:
|
||||
- 明示性重視:プログラマーが何が起きているかを隠さない
|
||||
- 初学者フレンドリー:実行順序が直感的
|
||||
- Everything is Box哲学:隠れた魔法的な動作を避ける
|
||||
|
||||
【他言語の問題例】
|
||||
```cpp
|
||||
// C++:複雑で読みにくい
|
||||
class Cat : public Animal {
|
||||
Toy catToy; // 1. 隠れたメンバー初期化
|
||||
Cat(string name) : Animal(name) { // 2. : Animal(name) が直感的でない
|
||||
// 3. 最後に自分の処理
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
【現在のNyash vs 新提案】
|
||||
```nyash
|
||||
// 現在の書き方
|
||||
box MeshNode : P2PBox {
|
||||
constructor(nodeId, world) {
|
||||
super P2PBox(nodeId, world) // 特別なキーワード
|
||||
me.routing = RoutingTable()
|
||||
}
|
||||
}
|
||||
|
||||
// 新提案:完全統一
|
||||
box MeshNode : P2PBox {
|
||||
constructor(nodeId, world) {
|
||||
from P2PBox.constructor(nodeId, world) // from統一!
|
||||
me.routing = RoutingTable()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
【完全統一のメリット】
|
||||
- from P2PBox.method() と完全に一貫している
|
||||
- 「どの親の何を呼んでいるか」が超明確
|
||||
- 多重デリゲーションでも from Logger.constructor() で区別可能
|
||||
|
||||
【深く考えてほしい点】
|
||||
1. Nyashの明示的コンストラクタ呼び出し設計をどう評価しますか?
|
||||
2. from P2PBox.constructor() の完全統一案をどう思いますか?
|
||||
3. 他言語(Java, Python, C#等)と比較したNyashの優位性は?
|
||||
4. 初学者にとって最も理解しやすい設計は?
|
||||
5. 言語の美しさ・一貫性の観点からの評価は?
|
||||
|
||||
プログラミング言語設計の専門的視点から、深く分析してください。
|
||||
@ -0,0 +1,106 @@
|
||||
Nyashプログラミング言語のオーバーライド設計について深い相談です。
|
||||
|
||||
【現在発見された実装問題】
|
||||
現在のNyashでは HashMap::insert により「暗黙のオーバーライド」が発生している:
|
||||
```rust
|
||||
// instance.rs - add_method関数
|
||||
pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) {
|
||||
let mut new_methods = (*self.methods).clone();
|
||||
new_methods.insert(method_name, method_ast); // ← 同名で上書き!
|
||||
self.methods = Arc::new(new_methods);
|
||||
}
|
||||
```
|
||||
|
||||
これにより以下が可能になってしまっている:
|
||||
```nyash
|
||||
box Node {
|
||||
send(msg) { // 最初の定義
|
||||
print("Version 1")
|
||||
}
|
||||
|
||||
send(msg) { // 暗黙に上書きされる
|
||||
print("Version 2") // ← こちらだけが残る
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
【Nyashの設計哲学との矛盾】
|
||||
- **明示性重視**: 何が起きているかを隠さない
|
||||
- **Everything is Box**: 統一された世界観
|
||||
- **from デリゲーション**: `from Parent.method()` の明示的呼び出し
|
||||
- **初学者フレンドリー**: 複雑な概念を分かりやすく表現
|
||||
|
||||
【提案する修正方針】
|
||||
|
||||
**1. 暗黙のオーバーライドを完全禁止**
|
||||
```nyash
|
||||
box Node {
|
||||
send(msg) {
|
||||
print("Version 1")
|
||||
}
|
||||
|
||||
send(msg) { // ← コンパイルエラーにする
|
||||
print("Version 2")
|
||||
}
|
||||
}
|
||||
// Error: Method 'send' is already defined. Use 'override' keyword if intentional.
|
||||
```
|
||||
|
||||
**2. コンストラクタのオーバーロード禁止**
|
||||
```nyash
|
||||
box Node {
|
||||
constructor(id) {
|
||||
me.id = id
|
||||
}
|
||||
|
||||
constructor(id, name) { // ← エラーにする
|
||||
me.id = id
|
||||
me.name = name
|
||||
}
|
||||
}
|
||||
// Error: Constructor overloading is not allowed. Use explicit initialization.
|
||||
```
|
||||
|
||||
**3. デリゲーションでの明示的override**
|
||||
```nyash
|
||||
box MeshNode : P2PBox {
|
||||
// 明示的にオーバーライドする意図を示す
|
||||
override send(intent, data, target) {
|
||||
me.routing.log(target)
|
||||
from P2PBox.send(intent, data, target) // 親の実装も呼べる
|
||||
}
|
||||
|
||||
// 新しいメソッド(overrideなし)
|
||||
sendWithRetry(intent, data, target) {
|
||||
// 新機能
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**4. エラーメッセージの改善**
|
||||
- 重複定義時: "Method 'send' already exists. Use 'override' if you want to replace parent method."
|
||||
- override不正使用時: "Method 'newMethod' does not exist in parent. Remove 'override' keyword."
|
||||
|
||||
【深く考えてほしい点】
|
||||
|
||||
**1. 哲学的整合性**
|
||||
- この方針はNyashの「明示性重視」「Everything is Box」哲学と整合しますか?
|
||||
- `from Parent.method()` デリゲーション設計との相性は?
|
||||
|
||||
**2. 学習コスト vs 安全性**
|
||||
- `override` キーワード追加による学習コストは妥当ですか?
|
||||
- 暗黙のオーバーライド禁止により、どの程度安全性が向上しますか?
|
||||
|
||||
**3. デリゲーションとの関係**
|
||||
- デリゲーション先メソッドを `override` するのは自然ですか?
|
||||
- 多重デリゲーション時の `override` はどう扱うべきですか?
|
||||
|
||||
**4. 実装上の課題**
|
||||
- コンパイル時の重複チェック実装の複雑度は?
|
||||
- 既存コードへの影響と移行戦略は?
|
||||
|
||||
**5. 他言語との比較優位性**
|
||||
- Java/C#の `@Override` や TypeScript の `override` との違いは?
|
||||
- Nyashならではの独自価値は何ですか?
|
||||
|
||||
プログラミング言語設計の専門的視点から、この方針がNyashの目指す「明示的で安全、かつ初学者フレンドリーな言語」に最適かどうか深く分析してください。
|
||||
77
docs/archive/design/decisions/architecture_consultation.txt
Normal file
77
docs/archive/design/decisions/architecture_consultation.txt
Normal file
@ -0,0 +1,77 @@
|
||||
Nyashプログラミング言語のBox型アーキテクチャ設計について深い技術相談です。
|
||||
|
||||
【現在の状況】
|
||||
- Rust実装のプログラミング言語Nyash開発中
|
||||
- "Everything is Box"哲学:全データがBoxオブジェクト
|
||||
- 現在16種類のBox型実装済み(StringBox, IntegerBox, P2PBox等)
|
||||
- Arc<Mutex>統一パターンでスレッドセーフ性確保
|
||||
|
||||
【現在のアーキテクチャ問題】
|
||||
現在、全Box型をtype aliasで統一しているが、実装で型エラー地獄が発生:
|
||||
|
||||
```rust
|
||||
// 現在の問題のある設計
|
||||
type StringBox = Arc<Mutex<StringBoxData>>;
|
||||
type IntegerBox = Arc<Mutex<IntegerBoxData>>;
|
||||
type P2PBox = Arc<Mutex<P2PBoxData>>;
|
||||
|
||||
// 問題:型エイリアス複雑化、trait object Debug実装困難
|
||||
// 結果:Copilot実装で型エラー多発、開発効率低下
|
||||
```
|
||||
|
||||
【検討中のシンプル設計】
|
||||
newtype patternによるシンプル化:
|
||||
|
||||
```rust
|
||||
// 案1: newtype pattern
|
||||
struct StringBox(Arc<Mutex<StringBoxData>>);
|
||||
struct IntegerBox(Arc<Mutex<IntegerBoxData>>);
|
||||
struct P2PBox(Arc<Mutex<P2PBoxData>>);
|
||||
|
||||
// 案2: 生構造体(必要時のみArc化)
|
||||
struct StringBox { data: String }
|
||||
struct IntegerBox { value: i64 }
|
||||
// 共有が必要な時だけArc::new()で包む
|
||||
```
|
||||
|
||||
【技術的検討ポイント】
|
||||
|
||||
1. **型安全性とシンプルさのバランス**
|
||||
- type alias vs newtype vs 生構造体
|
||||
- コンパイル時エラー検出 vs 実装しやすさ
|
||||
|
||||
2. **スレッドセーフ性の要件**
|
||||
- 全Box型で並行処理が必要か?
|
||||
- StringBox等の基本型にもMutex必要?
|
||||
- 必要な時だけArc<Mutex>化する方が良い?
|
||||
|
||||
3. **拡張性・保守性**
|
||||
- 新Box型追加時の実装コスト
|
||||
- エラーメッセージの分かりやすさ
|
||||
- 他開発者(AI含む)の理解しやすさ
|
||||
|
||||
4. **パフォーマンス**
|
||||
- Arc<Mutex>のオーバーヘッド
|
||||
- ゼロコスト抽象化の実現可能性
|
||||
- メモリ使用量の最適化
|
||||
|
||||
5. **現実的な実装戦略**
|
||||
- 段階的移行 vs 一括変更
|
||||
- 既存コードとの互換性
|
||||
- 開発スピード重視 vs 理想設計重視
|
||||
|
||||
【具体的相談事項】
|
||||
1. type alias vs newtype vs 生構造体、どの設計が最適?
|
||||
2. 全Box型に一律Arc<Mutex>は過剰?必要な箇所のみの方が良い?
|
||||
3. Rust専門家から見て推奨されるBox型統一アーキテクチャは?
|
||||
4. プログラミング言語実装において、型システムのベストプラクティスは?
|
||||
5. 実装効率と設計美学のバランスをどう取るべき?
|
||||
|
||||
【制約条件】
|
||||
- Rust実装必須
|
||||
- Everything is Box哲学維持
|
||||
- スレッドセーフ性確保
|
||||
- 16種類+今後追加予定のBox型すべてで統一
|
||||
- 実装・保守の現実性重視
|
||||
|
||||
プログラミング言語設計・Rust専門家の視点から、実装可能で美しく、長期保守に適したアーキテクチャ設計を提案してください。
|
||||
@ -0,0 +1,100 @@
|
||||
Nyash Programming Language - Weak Reference Architecture Critical Decision
|
||||
|
||||
I need expert advice on a fundamental architectural decision for weak reference implementation. This is a foundational component that will impact native compilation plans.
|
||||
|
||||
【Current Situation】
|
||||
Copilot has completed 99% of weak reference implementation with excellent quality. Only the final invalidation mechanism remains.
|
||||
|
||||
【Two Competing Approaches】
|
||||
|
||||
## Approach A: Copilot's "Proper" Global Tracking
|
||||
```rust
|
||||
pub struct SharedState {
|
||||
// Existing fields...
|
||||
pub instance_registry: Arc<Mutex<Vec<Weak<Mutex<InstanceBox>>>>>,
|
||||
}
|
||||
|
||||
fn invalidate_weak_references(&mut self, target_info: &str) {
|
||||
// Linear search through ALL instances in the system
|
||||
for weak_instance in &self.instance_registry {
|
||||
if let Some(instance) = weak_instance.upgrade() {
|
||||
instance.lock().unwrap().invalidate_weak_references_to(target_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Architecturally correct, immediate invalidation, theoretically perfect
|
||||
**Cons**: O(n) linear search, complex state management, heavyweight
|
||||
|
||||
## Approach B: Gemini's "On-Access" Lazy Invalidation
|
||||
```rust
|
||||
pub struct Interpreter {
|
||||
pub invalidated_ids: Arc<Mutex<HashSet<u64>>>, // Simple ID set
|
||||
}
|
||||
|
||||
fn trigger_weak_reference_invalidation(&mut self, target_info: &str) {
|
||||
if let Ok(id) = target_info.parse::<u64>() {
|
||||
self.invalidated_ids.lock().unwrap().insert(id); // O(1) operation
|
||||
}
|
||||
}
|
||||
|
||||
fn get_weak_field(&self, name: &str) -> Option<...> {
|
||||
if invalidated_ids.contains(&id) { // O(1) lookup
|
||||
return None; // Auto-nil on access
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: O(1) operations, minimal changes, leverages 99% existing implementation
|
||||
**Cons**: Delayed invalidation (only on access), not "immediate"
|
||||
|
||||
【Critical Considerations】
|
||||
|
||||
## 1. Native Compilation Impact
|
||||
This weak reference system will be compiled to native code. Performance characteristics matter significantly:
|
||||
- Approach A: O(n) linear search in native code = potential bottleneck
|
||||
- Approach B: O(1) HashSet operations = predictable performance
|
||||
|
||||
## 2. Foundation Quality vs Pragmatism
|
||||
- This is foundational memory safety infrastructure
|
||||
- Must balance correctness with performance
|
||||
- Real-world usage patterns matter more than theoretical perfection
|
||||
|
||||
## 3. Scaling Characteristics
|
||||
In applications with 1000+ objects:
|
||||
- Approach A: 1000+ instance traversal on each drop
|
||||
- Approach B: Single hash table insertion/lookup
|
||||
|
||||
## 4. Maintenance Complexity
|
||||
- Approach A: Complex global state, threading issues, lifecycle management
|
||||
- Approach B: Simple addition to existing interpreter state
|
||||
|
||||
【Specific Technical Questions】
|
||||
|
||||
1. **Performance Reality Check**: In a native-compiled language, is O(n) weak reference invalidation acceptable for real applications?
|
||||
|
||||
2. **Lazy vs Eager Trade-off**: Is "on-access invalidation" a viable pattern for systems programming? What are the hidden costs?
|
||||
|
||||
3. **Native Compilation Compatibility**: Which approach translates better to efficient native code generation?
|
||||
|
||||
4. **Memory Safety Guarantee**: Do both approaches provide equivalent memory safety guarantees?
|
||||
|
||||
5. **Industry Best Practices**: How do modern systems languages (Rust, Swift, etc.) handle this problem?
|
||||
|
||||
【Nyash Context】
|
||||
- Everything is Box philosophy (unified object model)
|
||||
- Target: P2P networking applications (performance-sensitive)
|
||||
- Native compilation planned (MIR → LLVM/Cranelift)
|
||||
- Developer experience priority (simplicity over theoretical perfection)
|
||||
|
||||
【Request】
|
||||
Please provide expert analysis focusing on:
|
||||
1. Real-world performance implications for native compilation
|
||||
2. Hidden complexity costs of each approach
|
||||
3. Recommendation for foundational language infrastructure
|
||||
4. Risk assessment for future scaling
|
||||
|
||||
This decision affects the entire language's memory management foundation. I need the most technically sound recommendation that balances correctness, performance, and maintainability.
|
||||
|
||||
Thank you for your expertise!
|
||||
@ -0,0 +1,64 @@
|
||||
Nyashプログラミング言語の関数オーバーロード設計について深い技術的相談です。
|
||||
|
||||
【Nyashの技術的特徴】
|
||||
- Everything is Box哲学: 全データがBoxオブジェクト
|
||||
- Arc<Mutex>統一アーキテクチャ: 完全スレッドセーフ設計
|
||||
- 明示性重視: 変数宣言先の即座特定可能
|
||||
- Rust実装: メモリ安全性+高性能
|
||||
- 目的: 初学者フレンドリー + 実用性
|
||||
|
||||
【検討する技術的課題】
|
||||
現在P2PBox実装において、関数オーバーロード(引数数による分岐)採用の是非を検討中。
|
||||
|
||||
具体例:
|
||||
```rust
|
||||
// Option A: オーバーロードあり
|
||||
impl P2PBox {
|
||||
pub fn send(&self, message: IntentBox) -> Result<(), SendError> // ブロードキャスト
|
||||
pub fn send(&self, to: &str, message: IntentBox) -> Result<(), SendError> // 個別送信
|
||||
pub fn send(&self, to: &str, message: IntentBox, opts: SendOpts) -> Result<(), SendError> // オプション付き
|
||||
}
|
||||
|
||||
// Option B: オーバーロードなし(現在)
|
||||
impl P2PBox {
|
||||
pub fn broadcast(&self, message: IntentBox) -> Result<(), SendError>
|
||||
pub fn send(&self, to: &str, message: IntentBox) -> Result<(), SendError>
|
||||
pub fn send_with_options(&self, to: &str, message: IntentBox, opts: SendOpts) -> Result<(), SendError>
|
||||
}
|
||||
```
|
||||
|
||||
【技術的検討ポイント】
|
||||
|
||||
1. **Rust実装との整合性**
|
||||
- Rustにはメソッドオーバーロードがない
|
||||
- 引数数による分岐をインタープリターで実装する必要
|
||||
- パフォーマンスへの影響
|
||||
|
||||
2. **Arc<Mutex>アーキテクチャとの親和性**
|
||||
- 動的ディスパッチの複雑さ
|
||||
- エラーハンドリングの一貫性
|
||||
- スレッドセーフティの保持
|
||||
|
||||
3. **インタープリター実装の複雑度**
|
||||
- パーサーでの引数数判定
|
||||
- 実行時メソッド選択アルゴリズム
|
||||
- デバッグ情報の提供
|
||||
|
||||
4. **型安全性とパフォーマンス**
|
||||
- 実行時型チェックのオーバーヘッド
|
||||
- エラーメッセージの品質
|
||||
- 開発時デバッグ体験
|
||||
|
||||
5. **エコシステム設計との整合性**
|
||||
- 他のBox型との一貫性
|
||||
- 拡張性(新しいオーバーロード追加)
|
||||
- メンテナンス性
|
||||
|
||||
【深く検討してほしい点】
|
||||
1. 技術的実装の複雑さ vs ユーザー体験の向上
|
||||
2. Nyashの「明示性重視」哲学との技術的整合性
|
||||
3. 初学者がエラーに遭遇した時のデバッグ体験
|
||||
4. P2P通信という特定ドメインでの最適解
|
||||
5. 言語の長期進化における影響
|
||||
|
||||
プログラミング言語実装の専門的視点から、技術的に最良で保守しやすい設計を分析してください。
|
||||
@ -0,0 +1,46 @@
|
||||
Nyashプログラミング言語の関数オーバーロード採用可否について言語設計の専門的観点から相談です。
|
||||
|
||||
【背景】
|
||||
Nyashは「Everything is Box」哲学で、明示性重視・初学者フレンドリー・メモリ安全性を重視する言語です。現在Phase 2でP2PBox実装中で、関数オーバーロード(引数数による分岐)を採用するか重要な決断が必要です。
|
||||
|
||||
【具体的争点】
|
||||
send(a) と send(a, b) のような関数オーバーロードを許すか?
|
||||
|
||||
例:
|
||||
```nyash
|
||||
// オーバーロードありの場合
|
||||
node.send("hello") // ブロードキャスト
|
||||
node.send("bob", "hello") // 個別送信
|
||||
node.send("bob", msg, options) // オプション付き
|
||||
|
||||
// オーバーロードなしの場合(現在)
|
||||
node.broadcast("hello") // 明示的メソッド名
|
||||
node.send("bob", "hello") // 必ず2引数
|
||||
node.sendWithOptions("bob", msg, options) // 明示的メソッド名
|
||||
```
|
||||
|
||||
【メリット】
|
||||
1. API使いやすさ向上
|
||||
2. 他言語からの移行しやすさ
|
||||
3. 直感的な呼び出し
|
||||
|
||||
【デメリット】
|
||||
1. 間違った関数を呼ぶリスク
|
||||
2. デバッグ困難
|
||||
3. Nyashの明示性哲学と矛盾
|
||||
4. 初学者混乱
|
||||
5. 型推論複雑化
|
||||
|
||||
【Nyashの設計思想との照合】
|
||||
- 明示性重視: プログラマーが変数の宣言先を即座に特定可能
|
||||
- 初学者フレンドリー: 学習コストが低い
|
||||
- Everything is Box: 統一されたオブジェクトモデル
|
||||
|
||||
【質問】
|
||||
1. Nyashの設計思想から見て、関数オーバーロードは採用すべきか?
|
||||
2. 明示性 vs 利便性のトレードオフをどう判断すべきか?
|
||||
3. 初学者向け言語として適切な選択は?
|
||||
4. P2P通信APIにおける最良の設計は?
|
||||
5. 他の現代的言語設計トレンドとの整合性は?
|
||||
|
||||
プログラミング言語設計の専門的視点から、Nyashの将来を決めるアドバイスをお願いします。
|
||||
@ -0,0 +1,73 @@
|
||||
Nyash言語のweak参照システム最終実装について技術的相談をお願いします。
|
||||
|
||||
【現在の状況】
|
||||
copilot様がweak参照システムを99%完成させました。驚くべき実装品質です。
|
||||
|
||||
【✅ 完成済みの素晴らしい実装】
|
||||
1. ハイブリッド構造: fields + fields_ng 併用システム
|
||||
2. weak参照専用メソッド: set_weak_field(), get_weak_field()
|
||||
3. 文字列ベース追跡: "WEAK_REF_TO:..." → "WEAK_REFERENCE_DROPPED"
|
||||
4. インタープリター統合: weak参照の検出・代入・アクセス完璧
|
||||
5. 5つの包括的テストケース
|
||||
|
||||
【⚠️ 残り1%の課題】
|
||||
単一関数 trigger_weak_reference_invalidation() が未実装:
|
||||
|
||||
```rust
|
||||
pub(super) fn trigger_weak_reference_invalidation(&mut self, target_info: &str) {
|
||||
eprintln!("🔗 DEBUG: Triggering global weak reference invalidation for: {}", target_info);
|
||||
|
||||
// TODO: Real implementation would require tracking all instances
|
||||
// and their weak references
|
||||
}
|
||||
```
|
||||
|
||||
【現在の動作】
|
||||
```
|
||||
✅ weak参照検出: 完璧 (🔗 DEBUG: Assigning to weak field 'parent')
|
||||
✅ ドロップ検出: 動作中 (🔗 DEBUG: Variable 'parent' set to 0)
|
||||
✅ 無効化呼び出し: 実行中 (🔗 DEBUG: Triggering global weak reference invalidation)
|
||||
❌ 実際のnil化: 未接続 (🔗 DEBUG: Weak field 'parent' still has valid reference)
|
||||
```
|
||||
|
||||
【copilot提案の実装アプローチ】
|
||||
グローバルインスタンス追跡システム:
|
||||
|
||||
```rust
|
||||
pub struct SharedState {
|
||||
// 既存フィールド...
|
||||
pub instance_registry: Arc<Mutex<Vec<Weak<Mutex<InstanceBox>>>>>,
|
||||
}
|
||||
|
||||
impl SharedState {
|
||||
fn register_instance(&mut self, instance: Weak<Mutex<InstanceBox>>) { ... }
|
||||
fn invalidate_weak_references(&mut self, target_info: &str) {
|
||||
// 全インスタンスを走査してweak参照を無効化
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
【技術的課題】
|
||||
1. 全InstanceBox作成時のグローバル登録必要
|
||||
2. 複雑なスレッドセーフティ管理
|
||||
3. デッドweak参照のガベージコレクション
|
||||
4. 5+ファイルにわたる変更
|
||||
|
||||
【代替案検討の観点】
|
||||
1. **より簡単な実装**: グローバル追跡なしで実現可能?
|
||||
2. **性能重視**: シンプルな文字列マッチングで十分?
|
||||
3. **段階的実装**: デモレベルで動作する最小実装?
|
||||
|
||||
【具体的質問】
|
||||
1. グローバルインスタンス追跡は本当に必要ですか?
|
||||
2. copilotの文字列ベース追跡をより簡単に完成できますか?
|
||||
3. 「target_info」による簡単なマッチング実装は可能ですか?
|
||||
4. デモ目的なら手動的な実装で十分ではないですか?
|
||||
|
||||
【Nyashの設計哲学】
|
||||
- Everything is Box: すべてがBoxオブジェクト
|
||||
- 明示性重視: 隠れた動作を避ける
|
||||
- シンプル重視: 初学者フレンドリー
|
||||
- 実用性優先: 完璧より動くもの
|
||||
|
||||
プログラミング言語実装の専門的観点から、最もシンプルで実装しやすいアプローチを提案してください。copilot様の99%完成した実装を活かしつつ、最後の1%を効率的に完成させる方法をお願いします。
|
||||
@ -0,0 +1,40 @@
|
||||
Nyash言語のweak参照実装で根本的な設計問題が発覚しました。専門的分析をお願いします。
|
||||
|
||||
【現在の問題】
|
||||
InstanceBox構造が原因でweak参照が実装できません:
|
||||
|
||||
```rust
|
||||
pub struct InstanceBox {
|
||||
pub fields: Arc<Mutex<HashMap<String, Box<dyn NyashBox>>>>, // 問題の核心
|
||||
}
|
||||
```
|
||||
|
||||
NyashValue::WeakBoxを作っても、Box<dyn NyashBox>にしか格納できず、弱参照情報が失われます。
|
||||
|
||||
【解決策の選択肢】
|
||||
|
||||
1. **根本解決**(理想だが影響大)
|
||||
```rust
|
||||
pub fields: Arc<Mutex<HashMap<String, NyashValue>>>, // 全面アーキテクチャ変更
|
||||
```
|
||||
|
||||
2. **暫定解決**(copilot提案)
|
||||
```rust
|
||||
pub struct InstanceBox {
|
||||
pub fields: Arc<Mutex<HashMap<String, Box<dyn NyashBox>>>>, // 既存維持
|
||||
pub weak_fields: Arc<Mutex<HashMap<String, Weak<Mutex<dyn NyashBox>>>>>, // 追加
|
||||
}
|
||||
```
|
||||
|
||||
【コンテキスト】
|
||||
- NyashValue革命は完了済み(Arc<Mutex>過剰症候群解決)
|
||||
- Everything is Box哲学必須
|
||||
- 実用性重視(完璧より動くもの優先)
|
||||
|
||||
【質問】
|
||||
1. 暫定解決策の技術的妥当性は?
|
||||
2. パフォーマンス・保守性への影響は?
|
||||
3. 根本解決は本当に必要か?
|
||||
4. 段階的移行戦略の是非は?
|
||||
|
||||
実装可能性と設計の美しさのバランスを重視した分析をお願いします。
|
||||
56
docs/archive/design/decisions/インタープリタ評価.txt
Normal file
56
docs/archive/design/decisions/インタープリタ評価.txt
Normal file
@ -0,0 +1,56 @@
|
||||
Nyash Interpreter Assessment (Current Strengths, Weaknesses, Direction)
|
||||
|
||||
Strengths
|
||||
- Everything is Box: 統一データモデルで生成/代入/比較/解放が一貫。学習・読解が容易。
|
||||
- Explicit lifecycle: init/fini/weak/スコープ解放を構文で規約化。解放点が読み取れる。
|
||||
- Cycles solved pragmatically: init { weak ... } + 自動nil化で双方向参照を安全に扱える。
|
||||
- Delegation-first: from(多重対応)+ override必須で明示合成。暗黙解決を排しテスト容易。
|
||||
- Rust core: Arc<Mutex<...>>/Weak、BoxFinalizer、二重解放防止など堅牢な実装基盤。
|
||||
- Dev UX: 明示変数宣言、単一ループ構文、static box Mainでコード規律が単純。
|
||||
- Repro: WASM Playgroundでゼロインストール再現(docs/chatgpt5/PLAYGROUND_GUIDE.md)。
|
||||
|
||||
Weaknesses
|
||||
- Mixed field models: fields(レガシー)と fields_ng(次世代)が併存し、理解/実装が複雑。
|
||||
- Weak shim leakage: 一部weakを文字列マーカーで代替(set_weak_field_from_legacy)。完全WeakBox化が未完。
|
||||
- Builtin gaps: Math/Float/Intent/P2P周辺に未実装・登録不足が残る。
|
||||
- P2P disabled path: インタープリタ内のP2P呼び出しが一時無効化で連携が途切れがち。
|
||||
- Verbose debug: 実行時eprintlnが多くノイズ。ログレベル切替が未整備。
|
||||
- Multi-delegation policy: 競合解決の仕様/診断が未完成でユーザーが迷う余地。
|
||||
|
||||
Current Limitations
|
||||
- Determinism vs sharing: finiは解放フックだが強参照が残る場合は実体が残存。期待との齟齬可能性あり。
|
||||
- Error surfacing: RuntimeErrorのSpan拡張が全コードパスで統一されていない。
|
||||
- Perf visibility: ベンチ/メトリクス不足。weak upgradeやfini回数の観測が難しい。
|
||||
- WASM behavior: ブラウザでのタイミング/ログ表示がネイティブと異なる場合あり。
|
||||
|
||||
Direction
|
||||
- Product-first clarity: 「迷わない規約」を前面に。実用性と予測可能性を訴求。
|
||||
- Unify field storage: fields_ngへ一本化し、WeakBoxをエンドツーエンドで運用。
|
||||
- Delegation doctrine: 多重デリゲーション競合のポリシー(優先/明示/エラー)を明文化・実装。
|
||||
- Measurable DX: Playgroundでfini回数/weak upgrade成功・失敗を可視化して説得力向上。
|
||||
- Complete builtins: Float/Math/Intent/P2Pの未完箇所を段階的に充足し、テストで裏付け。
|
||||
|
||||
High-Impact Next Steps
|
||||
- WeakBox E2E完了: 文字列マーカー廃止→NyashValue::WeakBoxで統一。テスト追加。
|
||||
- Assignment safety audit: 再代入→fini→weak自動nil化の一連を網羅試験(成功/競合/例外)。
|
||||
- Multi-delegation conflicts: 明示親指定必須・曖昧時はエラー+提案を実装。エラーメッセージ改善。
|
||||
- P2P経路の復活: expressions.rsのP2P呼び出しを段階的に再有効化。Intentアクセサ整備。
|
||||
- Debug levels: ログレベル導入(環境変数/DebugBox)でノイズ削減と計測を両立。
|
||||
- Playground強化: 3シナリオにメトリクス表示(fini総数、weak失敗数、簡易時間)。
|
||||
|
||||
Risks / Trade-offs
|
||||
- Perception risk: finiを「即時破棄」と誤解される恐れ。共有参照残存の挙動を明文化要。
|
||||
- Dual-storage complexity: レガシー/次世代の二重管理期間にバグ混入リスク。
|
||||
- Performance cliffs: 過度なMutexロック/頻繁なupgradeがホットパスで効く可能性。測定・キャッシュ要検討。
|
||||
- WASM differences: ブラウザでのタイミング/ログ/スレッド制約がネイティブと異なる。
|
||||
|
||||
Stretch Ideas
|
||||
- Static analysis: init/weakの静的検証、循環参照ヒント、未宣言代入の修正提案(LSP連携)。
|
||||
- Conflict DSL: 多重デリゲーション競合を宣言で解決できる軽量DSL導入。
|
||||
- Tracing viz: weak生死・finiイベントのタイムライン可視化(Playground連携)。
|
||||
- Packages/templates: 標準Boxとテンプレート(ゲーム/アート/教育)で“動く最小”を量産。
|
||||
|
||||
Summary
|
||||
統一モデルと明示規約で日常のメモリ管理を楽にする点が最大の強み。短期はWeakの完全統一とデモ/数値の可視化に集中し、
|
||||
多重デリゲーションの競合仕様や未完Boxを段階的に整備するのが最も効果的。
|
||||
|
||||
65
docs/archive/design/decisions/プレイグラウンド_サンプル.md
Normal file
65
docs/archive/design/decisions/プレイグラウンド_サンプル.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Playground Samples(コピー&ペースト用サンプル)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
|
||||
---
|
||||
|
||||
## 1) 循環参照 vs weak(自動nil化)
|
||||
|
||||
```nyash
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me)
|
||||
}
|
||||
getName() { return "P" }
|
||||
fini() { print("Parent.fini") }
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p }
|
||||
show() {
|
||||
if (me.parent != null) { print("parent=" + me.parent.getName()) }
|
||||
else { print("parent is gone") }
|
||||
}
|
||||
fini() { print("Child.fini") }
|
||||
}
|
||||
|
||||
p = new Parent()
|
||||
p.child.show() # => parent=P
|
||||
p.fini() # 親を破棄
|
||||
p.child.show() # => parent is gone(想定)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2) 再代入時の fini 発火(予備解放)
|
||||
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # 旧 obj に対して fini() が呼ばれる
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3) スコープ抜けでローカル解放
|
||||
|
||||
```nyash
|
||||
function make() {
|
||||
local t
|
||||
t = new Thing()
|
||||
}
|
||||
|
||||
box Thing { fini() { print("Thing.fini (scope)") } }
|
||||
|
||||
make() # => Thing.fini (scope)
|
||||
```
|
||||
|
||||
31
docs/archive/design/decisions/実装TODO_解放とガード.txt
Normal file
31
docs/archive/design/decisions/実装TODO_解放とガード.txt
Normal file
@ -0,0 +1,31 @@
|
||||
Implementation TODOs: Finalization & Guards
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
Scope: src/instance.rs, src/interpreter/{core,expressions,statements}.rs, parser
|
||||
|
||||
1) InstanceBox::fini() の強化(src/instance.rs)
|
||||
- 状態機械: in_finalization(再入防止)→ finalized。
|
||||
- 再帰: init 強参照フィールドを走査し、未処理の子 Instance に対して finalize。weak は対象外。
|
||||
- クリア: 全フィールドクリア、finalized = true。
|
||||
- 無害化: 二重呼び出しは no-op。
|
||||
|
||||
2) 使用禁止ガード(実行時)
|
||||
- expressions.rs: メソッド呼び出し前に instance.is_finalized() をチェック→エラー。
|
||||
- statements.rs: フィールド代入/アクセス時にチェック→エラー。
|
||||
- core.rs: 必要なら共通ヘルパーで一元化。
|
||||
|
||||
3) weak への fini 禁止(静的検出+実行時フォールバック)
|
||||
- parser: AST 上で fini() 呼び出しを検出し、対象が weak フィールドならビルドエラーに。
|
||||
- 実行時: 保険として expressions.rs で weak フィールド経由の fini 呼び出しを拒否。
|
||||
|
||||
4) 例外方針とログ
|
||||
- ユーザー fini() で例外→自動カスケードは続行。最後に集約報告。
|
||||
- ログレベル: デバッグ時のみ詳細(upgrade失敗、already finalized等)。
|
||||
|
||||
5) Playground 可視化(別PR)
|
||||
- fini 回数、Finalizing→Finalized遷移、weak upgrade失敗数をUI表示。
|
||||
|
||||
6) ドキュメント反映(実装後)
|
||||
- LANGUAGE_GUIDE / reference へ最終ルール・エラーメッセージ・サンプルを移植。
|
||||
|
||||
92
docs/archive/design/decisions/実装計画_fini統合.txt
Normal file
92
docs/archive/design/decisions/実装計画_fini統合.txt
Normal file
@ -0,0 +1,92 @@
|
||||
Implementation Plan: Finalization Policy Integration (fini)
|
||||
|
||||
Last updated: 2025-08-13
|
||||
|
||||
Goals
|
||||
- Default: Auto-finalize strong fields in init declaration order.
|
||||
- Custom: User-defined fini() can implement any order and additional cleanup.
|
||||
- Remainder: Auto-cascade finalization for strong fields not handled in user fini().
|
||||
- Prohibit: Calling fini() on weak fields (non-owning).
|
||||
- Guard: Forbid any use after finalized (errors), idempotent fini().
|
||||
|
||||
Touched code (planned)
|
||||
- src/instance.rs (core: InstanceBox state + fini strengthen)
|
||||
- src/interpreter/objects.rs (construct InstanceBox with needed metadata)
|
||||
- src/interpreter/expressions.rs (method/field guards, weak-fini runtime check)
|
||||
- src/interpreter/statements.rs (assignment guards)
|
||||
- parser (optional later: static detection of weak-fini inside user fini())
|
||||
|
||||
1) InstanceBox: add metadata and strengthen fini()
|
||||
- Add fields:
|
||||
- init_field_order: Vec<String>
|
||||
Purpose: deterministic auto-cascade order (includes inherited fields).
|
||||
- weak_fields_union: std::collections::HashSet<String>
|
||||
Purpose: fast check to skip weak fields in auto-cascade (includes parents’ weak fields).
|
||||
- in_finalization: bool
|
||||
Purpose: prevent re-entrancy; together with existing finalized flag.
|
||||
- Constructor changes:
|
||||
- InstanceBox::new(class_name: String, all_fields: Vec<String>, methods: HashMap<String, ASTNode>,
|
||||
weak_fields_union: HashSet<String>)
|
||||
Set init_field_order = all_fields; weak_fields_union = provided; in_finalization = false.
|
||||
- Strengthen InstanceBox::fini():
|
||||
- if finalized => return Ok(()) (idempotent)
|
||||
- set in_finalization = true
|
||||
- (User-defined fini() body is executed by interpreter before calling this method; keep that flow)
|
||||
- Auto-cascade: for each field in init_field_order
|
||||
- if field in weak_fields_union => skip
|
||||
- get current field value; if InstanceBox => child.fini() (idempotent)
|
||||
- Clear all fields; set finalized = true; set in_finalization = false; return Ok(())
|
||||
|
||||
2) objects.rs: pass metadata at construction time
|
||||
- Location: src/interpreter/objects.rs, execute_new() / resolve_inheritance()
|
||||
- Already computes `all_fields` via resolve_inheritance(). Use as init_field_order.
|
||||
- Implement helper union_weak_fields(box_decl: &BoxDeclaration) -> HashSet<String>
|
||||
- Traverse current box_decl and recursively parents (extends) to collect weak fields.
|
||||
- Call: InstanceBox::new(actual_class_name, all_fields, all_methods, weak_fields_union)
|
||||
|
||||
3) Runtime guards and weak-fini prohibition (expressions.rs/statements.rs)
|
||||
- Method calls (src/interpreter/expressions.rs::execute_method_call)
|
||||
- If target is InstanceBox and method != "fini":
|
||||
- if instance.is_finalized() => error: "Instance was finalized; further use is prohibited"
|
||||
- If method == "fini":
|
||||
- If object AST is FieldAccess/ThisField/MeField, resolve owner + field name; if field is weak (by box_decl.weak_fields) => error: "Cannot finalize weak field '<name>' (non-owning reference)"
|
||||
- Else proceed with current special fini handling (user body execution) then call instance.fini()
|
||||
- Field access (execute_field_access)
|
||||
- If owner InstanceBox is finalized => error as above
|
||||
- Assignments (src/interpreter/statements.rs)
|
||||
- For FieldAccess/ThisField/MeField targets: if owner InstanceBox is finalized => error
|
||||
|
||||
4) Parser (optional, later)
|
||||
- Static detection inside user-defined fini() body:
|
||||
- Walk AST; detect `me.<weak_field>.fini()` and emit build-time error.
|
||||
- Runtime check remains as fallback for dynamic flows.
|
||||
|
||||
Important decisions
|
||||
- Do not track "handled-by-user-fini" set. Rely on idempotent child.fini(). This keeps implementation simple and safe.
|
||||
- Ensure weak_fields_union includes parents to avoid accidentally finalizing weak fields inherited from parents.
|
||||
|
||||
Tests (to add/verify)
|
||||
- Reassignment: old value’s fini() is called exactly once; Thing.fini counter.
|
||||
- Weak prohibition: `me.weakField.fini()` raises error (runtime; later build-time).
|
||||
- Custom order: User fini closes r3->r2, auto cascade closes remaining r1.
|
||||
- Finalized guard: method call / field access / assignment after fini => error.
|
||||
- Cycles: Parent<->Child (Child weak parent); Parent.fini() => Child’s parent becomes null on access (lazy nilification), no leaks.
|
||||
|
||||
Rollout order
|
||||
1. InstanceBox fields + fini strengthen (core).
|
||||
2. Interpreter guards (method/field/assignment).
|
||||
3. Weak-fini runtime prohibition via AST check.
|
||||
4. Tests and sample updates (docs/chatgpt5/finalization_examples.txt cases).
|
||||
5. Optional: parser build-time detection.
|
||||
|
||||
Risks and mitigations
|
||||
- Re-entrancy: guarded by in_finalization + idempotent finalized flag.
|
||||
- Performance: auto-cascade per field; usually shallow; child.fini idempotent avoids repeated heavy work.
|
||||
- Compatibility: InstanceBox::new signature change; update all call sites (objects.rs, core.rs statics/global creations).
|
||||
- UX: Clear error messages as documented in docs/chatgpt5/finalization_errors.txt.
|
||||
|
||||
Future enhancements (optional)
|
||||
- Attribute `@no_auto_finalize` to exclude fields from auto-cascade when fully managed in user fini().
|
||||
- FinalizationContext injected into user fini() for safe, limited operations.
|
||||
- Debug mode: eager weak invalidation at finalize time for visualization.
|
||||
|
||||
63
docs/archive/design/decisions/解放ポリシー_fini.txt
Normal file
63
docs/archive/design/decisions/解放ポリシー_fini.txt
Normal file
@ -0,0 +1,63 @@
|
||||
Nyash Finalization Policy (fini as destructor-style method)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
目的
|
||||
- fini を「フィールド列挙」ではなく「通常のメソッド本体(デストラクタ的)」として運用しつつ、
|
||||
自動カスケード解放(init フィールドの残り処理)と整合する最終ルールを定義する。
|
||||
|
||||
設計方針(合意)
|
||||
- すべての Box は論理的に fini() を持つ(ユーザー未定義でもシステム既定が働く)。
|
||||
- fini() は“論理的解放”のフックであり、以後の使用は禁止(finalized)。
|
||||
- weak フィールドは所有権を持たないため、自動の fini 対象にしない(アクセス時の upgrade 失敗で null)。
|
||||
|
||||
実行順序(最終)
|
||||
1) 既に finalized なら何もしない(idempotent)。
|
||||
2) 再入防止のため in_finalization フラグを立てる(finalized はまだ立てない)。
|
||||
3) ユーザー定義 fini() 本体があれば実行(この間、フィールドアクセス/メソッド呼び出しは許可)。
|
||||
4) 自動カスケード解放:init{ ... } に宣言された強参照フィールドのうち、
|
||||
- ユーザー fini() 本体で明示的に処理されなかった“残り”に対して、宣言順で child.fini() を呼ぶ。
|
||||
- weak 修飾フィールドは対象外。
|
||||
5) 全フィールドをクリアし finalized フラグを立てる(以後の使用は禁止)。
|
||||
6) 再入フラグを下ろして終了。
|
||||
|
||||
使用禁止ガード
|
||||
- finalized 後の操作はエラーとする:
|
||||
- メソッド呼び出し、フィールドアクセス/代入、デリゲーション経由の呼び出し等。
|
||||
- 推奨メッセージ:"Instance was finalized; further use is prohibited"。
|
||||
- idempotent な fini() の再呼び出しのみ許容(無害化)。
|
||||
|
||||
補足
|
||||
- ユーザー定義 fini() 内で解放順序が必要な場合は、自由に child.fini() を呼べる(柔軟性)。
|
||||
- その後に“残り”が自動処理されるため、完全手動にしたい場合は将来的に属性(例:@no_auto_finalize)導入を検討(現段階は自動処理ありを既定)。
|
||||
- 例外発生時はベストエフォートで自動カスケードとクリアを続行(安全側)。
|
||||
|
||||
weak の取り扱い
|
||||
- weak はアクセス時に upgrade/失敗で null となる(lazy nilification)。
|
||||
- デバッグ用途として finalize 時に weak を即時無効化する eager モードを将来オプションで検討可(既定は lazy)。
|
||||
|
||||
禁止事項と診断(weak に対する fini 呼び出し)
|
||||
- ルール: weak 修飾フィールドは所有権を持たないため、`me.<weak_field>.fini()` のような直接の fini 呼び出しを禁止する。
|
||||
- 推奨診断レベル: ビルド(解析)時エラー。
|
||||
- 推奨エラーメッセージ: "Cannot finalize weak field '<name>' (non-owning reference). Use null assignment or let it lazily nilify."
|
||||
- 実装補足: 静的解析で `fini()` 本体内のフィールド呼び出しを走査し、対象が weak に該当すればエラー。検出困難な動的経路は実行時にもエラーを返す。
|
||||
- 推奨代替手段: `me.<weak_field> = null`(参照解除)/アクセス時の自動 nil 化に任せる。
|
||||
|
||||
簡易疑似コード
|
||||
fn finalize(instance):
|
||||
if instance.finalized: return
|
||||
instance.in_finalization = true
|
||||
if has_user_fini(instance):
|
||||
run_user_fini_body(instance)
|
||||
for field in instance.init_fields:
|
||||
if is_strong_ref(field) and not handled_in_user_fini(field):
|
||||
if is_instance(field.value) and not field.value.finalized:
|
||||
finalize(field.value)
|
||||
clear_all_fields(instance)
|
||||
instance.finalized = true
|
||||
instance.in_finalization = false
|
||||
|
||||
期待する効果
|
||||
- 柔軟性:ユーザー fini() 本体で任意順序・任意処理が書ける。
|
||||
- 決定性:残りは init 宣言順で自動解放され、毎回同じ順に実行。
|
||||
- 明確性:finalized 後は使用禁止をガードで強制、誤用を早期検知。
|
||||
39
docs/archive/design/decisions/解放ポリシー_エラーと診断.txt
Normal file
39
docs/archive/design/decisions/解放ポリシー_エラーと診断.txt
Normal file
@ -0,0 +1,39 @@
|
||||
Nyash Finalization Errors and Diagnostics
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
1) 使用禁止エラー(finalized 後の操作)
|
||||
---------------------------------------
|
||||
Message: "Instance was finalized; further use is prohibited"
|
||||
When: finalized フラグが立ったインスタンスに対して、
|
||||
- メソッド呼び出し
|
||||
- フィールドアクセス/代入
|
||||
- デリゲーション経由の呼び出し
|
||||
を行った場合。
|
||||
Notes: toString 相当も原則禁止(方針次第)。まずは全面禁止が明快。
|
||||
|
||||
2) weak に対する fini 呼び出し(禁止)
|
||||
---------------------------------------
|
||||
Message (build-time preferred):
|
||||
"Cannot finalize weak field '<name>' (non-owning reference)."
|
||||
Message (runtime fallback):
|
||||
"Finalization of non-owning (weak) reference is not allowed: '<name>'"
|
||||
When: `init { weak <name> }` で宣言されたフィールドに対して `fini()` を直接呼んだ場合。
|
||||
Fix: `me.<name> = null`(参照解除) or 自動 nil 化に任せる。
|
||||
|
||||
3) 二重解放の抑止(無害化)
|
||||
---------------------------------------
|
||||
Behavior: 2回目以降の `fini()` 呼出しは no-op。
|
||||
Notes: ログに "already finalized" を出すかは運用ポリシー次第。
|
||||
|
||||
4) 自動カスケード中の例外
|
||||
---------------------------------------
|
||||
Policy: ベストエフォートで残りの解放を継続、最後にまとめて報告(fail-safe)。
|
||||
Message example:
|
||||
"Finalization encountered errors; see aggregated report (N failures)."
|
||||
|
||||
5) 解析時の注意(推奨)
|
||||
---------------------------------------
|
||||
- fini() 本体内でのフィールド fini 呼び出しは静的解析で走査し、weak を検知したらビルドエラーへ。
|
||||
- 明示属性 `@no_auto_finalize`(将来案)を付与したフィールドは自動カスケード対象から除外。
|
||||
|
||||
73
docs/archive/design/decisions/解放ポリシー_例.txt
Normal file
73
docs/archive/design/decisions/解放ポリシー_例.txt
Normal file
@ -0,0 +1,73 @@
|
||||
Nyash Finalization Examples
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
1) 既定: init 宣言順での解放(強参照のみ)
|
||||
--------------------------------------------------
|
||||
box A { fini() { print("A.fini") } }
|
||||
box B { fini() { print("B.fini") } }
|
||||
|
||||
box Holder {
|
||||
init { a, b, weak c }
|
||||
}
|
||||
|
||||
h = new Holder()
|
||||
h.a = new A()
|
||||
h.b = new B()
|
||||
# h.c は weak なので対象外
|
||||
|
||||
# h.fini() を呼ぶと:
|
||||
# 1) ユーザー定義 fini() があれば先に実行
|
||||
# 2) 残りは init の宣言順に a → b の順で child.fini()
|
||||
# 3) フィールドクリア → finalized
|
||||
|
||||
|
||||
2) カスタム順序: ユーザー定義 fini() で順序制御
|
||||
--------------------------------------------------
|
||||
box Resource { init { name } fini() { print("close:" + me.name) } }
|
||||
|
||||
box Pipeline {
|
||||
init { r1, r2, r3 }
|
||||
fini() {
|
||||
# 依存性の都合で r3 → r2 → r1 の順に閉じたい
|
||||
if me.r3 != null { me.r3.fini() }
|
||||
if me.r2 != null { me.r2.fini() }
|
||||
# r1 は明示しない → 自動カスケードで最後に閉じられる
|
||||
}
|
||||
}
|
||||
|
||||
p = new Pipeline()
|
||||
p.r1 = new Resource("r1")
|
||||
p.r2 = new Resource("r2")
|
||||
p.r3 = new Resource("r3")
|
||||
p.fini()
|
||||
# 期待: close:r3 → close:r2 → close:r1 の順
|
||||
|
||||
|
||||
3) 弱参照は対象外(禁止パターン)
|
||||
--------------------------------------------------
|
||||
box Parent { init { weak child } fini() {
|
||||
# NG: 非所有参照のため fini は禁止
|
||||
# me.child.fini() # → ビルド時エラー(推奨):Cannot finalize weak field 'child'
|
||||
# 代替: 参照解除
|
||||
me.child = null
|
||||
} }
|
||||
|
||||
|
||||
4) 再代入での予備解放
|
||||
--------------------------------------------------
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
box Holder { init { obj } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # → 旧 obj に対して自動的に fini()
|
||||
|
||||
|
||||
5) finalized 後の使用禁止
|
||||
--------------------------------------------------
|
||||
box X { }
|
||||
x = new X()
|
||||
x.fini()
|
||||
x.doSomething() # → 実行時エラー: Instance was finalized; further use is prohibited
|
||||
|
||||
94
docs/archive/design/decisions/設計RFC_多重デリゲーションとfini.txt
Normal file
94
docs/archive/design/decisions/設計RFC_多重デリゲーションとfini.txt
Normal file
@ -0,0 +1,94 @@
|
||||
Nyash 設計検討メモ(RFC): 多重デリゲーション競合ポリシーと fini の意味づけ
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
目的
|
||||
- 多重デリゲーションにおける競合解決ポリシーを明文化し、実装・診断メッセージと揃える。
|
||||
- fini(論理的解放フック)の意味論と期待管理を定義し、現状課題と解決策を整理する。
|
||||
|
||||
---
|
||||
|
||||
1) 多重デリゲーションの競合ポリシー(提案仕様)
|
||||
|
||||
基本方針
|
||||
- 明示最優先: 解決順は定めない。曖昧さがある場合はエラーとし、明示(修飾/override)を要求する。
|
||||
- 子の定義優先: 子で定義/overrideされたものが最優先される。
|
||||
|
||||
メソッド解決
|
||||
- 子に同名メソッドがあればそれを使用。上書きは必ず `override` を要する。
|
||||
- 子に無く、親のうち「ちょうど1つ」だけがメソッドを提供するなら自動選択。
|
||||
- 親の「複数」が同名メソッドを提供する場合は曖昧エラー。
|
||||
- 対処: 子で `override foo(...) { return from A.foo(...); }` のように一本化、または呼び出しごとに `from A.foo(...)` / `from B.foo(...)` を使う。
|
||||
- 親呼び出しは常に `from Parent.m(...)` で明示修飾できる(推奨パターン)。
|
||||
|
||||
フィールド解決
|
||||
- 子がフィールドを持てばそれを使用。
|
||||
- 子に無く、親のうち「ちょうど1つ」だけが同名フィールドを持つ場合は自動選択。
|
||||
- 複数親が同名フィールドを持つ場合は曖昧エラー。
|
||||
- 対処: 子で別名のラッパー/アクセサを定義して再輸出、または(将来案として)`from Parent.field` の明示アクセスを利用。
|
||||
|
||||
インターフェース整合
|
||||
- インターフェースが要求するメソッドに対し、複数親が候補を提供する場合、子は必ず `override` して一本化(または合成)する。
|
||||
|
||||
ビルトイン/Static Box
|
||||
- 同一ポリシーを適用。曖昧な場合はエラーで明示を要求。
|
||||
|
||||
診断メッセージ例
|
||||
- Method 'foo' is provided by: A, B. Disambiguate via:
|
||||
- override foo(...) { return from A.foo(...); }
|
||||
- or call with qualification: from A.foo(...)
|
||||
- Field 'x' is provided by: A, B. Define an alias in child or qualify access.
|
||||
|
||||
実装の要点(簡易アルゴリズム)
|
||||
- 解決時に候補集合 S を作成。|S|=0 → 未定義エラー。|S|=1 → その定義を使用。|S|>1 → 曖昧エラー。
|
||||
- 子の定義は候補集合より常に優先(S を見る前に確定)。
|
||||
- メソッド/フィールドで同一ロジックを共有できるようヘルパー化。
|
||||
|
||||
補助パターン(任意)
|
||||
- 構文追加は避け、子側に明示ラッパーを定義して再輸出するのを推奨(後方互換/可読)。
|
||||
- 拡張案として alias 機構(例: alias { A.foo -> aFoo })は将来検討。
|
||||
|
||||
---
|
||||
|
||||
2) fini(論理的解放フック)の意味づけと期待管理
|
||||
|
||||
定義(言語仕様)
|
||||
- `fini()` は「論理的解放」を宣言するフック。呼び出しコンテキストで当該インスタンスを以後使用しないことを示し、関連資源の解放を行う。
|
||||
- 共有参照(他所の強参照)が残存していても、言語意味論上は finalized(使用不可)とみなす。実体メモリが残る場合があるのは実装都合。
|
||||
|
||||
使用禁止のガード
|
||||
- `fini()` 後の操作はエラー(idempotent な `fini()` 再呼出しのみOK)。
|
||||
- 対象: メソッド呼出し、フィールドアクセス、代入、デリゲーション経由の呼出し等。
|
||||
- 推奨エラーメッセージ: "Instance was finalized; further use is prohibited"。
|
||||
|
||||
波及とクリーンアップ
|
||||
- `fini()` は所有フィールドにも波及。子Boxであるフィールドに対し `fini()` を呼び、その後フィールドをクリア。
|
||||
- 弱参照はアクセス時 upgrade 失敗で自動的に `null`(lazy nil化)。必要に応じてデバッグモードで eager 無効化(任意機能)。
|
||||
|
||||
現状課題(2025-08 時点)
|
||||
- 内部 `instance.fini()` が、全フィールド再帰 `fini()` → クリア を必ずしも保証していない(実装強化余地)。
|
||||
- `fini()` 後の使用禁止ガードが緩く、明確なエラー化が不十分なコードパスがある可能性。
|
||||
- 共有参照が残るケースの意味論が docs に十分明示されておらず、誤解リスクがある。
|
||||
|
||||
解決策(優先度順)
|
||||
1) 内部解放強化: `instance.fini()` 内で全フィールドを走査し、InstanceBox へは `fini()`、二重防止フラグ→最後にクリア。
|
||||
2) ガード導入: `get_field`/`set_field`/`get_method` など入口で `finalized` チェック→使用禁止エラーを返す。
|
||||
3) ドキュメント明記: fini = 論理的解放。共有参照残存時も以後の使用は禁止。弱参照はアクセス時 `null`。
|
||||
4) 可視化: Playground に `fini` 回数/weak upgrade 失敗数/エラー例の表示を追加し、期待を合わせる。
|
||||
|
||||
禁止事項(weak への fini 呼び出し)
|
||||
- ルール: `init { weak ... }` で宣言されたフィールドに対する `fini()` 直接呼び出しは禁止(非所有参照の解放に相当)。
|
||||
- 診断方針: 可能な限りビルドエラーで検出し、動的経路は実行時エラーで防止。
|
||||
- 推奨メッセージ: "Cannot finalize weak field '<name>' (non-owning reference). Set it to null or rely on lazy nilification."
|
||||
|
||||
備考(質問への回答)
|
||||
- 「共有参照が残っていても解放が正しいか?」→ はい。言語意味論では“以後使用禁止”を宣言するのが `fini()` で、
|
||||
物理メモリが残るかどうかはランタイムの参照カウントに依存するだけ。禁止ガードと文書化で期待を一致させる。
|
||||
|
||||
---
|
||||
|
||||
3) 追補: 実装/ドキュメント TODO
|
||||
- interpreter: 候補集合による曖昧検出と診断の実装(メソッド/フィールド)。
|
||||
- instance: 再帰的 `fini()` + フィールドクリアの保証、finalized ガードの一元化。
|
||||
- docs: LANGUAGE_GUIDE / reference に上記仕様を反映(サンプルと期待エラーメッセージ含む)。
|
||||
- playground: メトリクス・エラーの可視化を追加(検証再現性の強化)。
|
||||
126
docs/archive/design/decisions/論文_サマリ.md
Normal file
126
docs/archive/design/decisions/論文_サマリ.md
Normal file
@ -0,0 +1,126 @@
|
||||
# Nyash: Everything is Box — 統一メモリモデルと弱参照による安全なライフサイクル管理
|
||||
|
||||
最終更新: 2025-08-13(ドラフト)
|
||||
|
||||
## 概要(Abstract)
|
||||
本稿は、すべての値を統一的なコンテナ「Box」として扱う“Everything is Box”哲学に基づくプログラミング言語Nyashを提案する。Nyashは、言語構文レベルでメモリ管理を明示化し、予測可能なライフサイクル制御とメモリ安全性を両立する。具体的には、(1) Boxのフィールドは`init { ... }`で宣言し、(2) 再代入・スコープ終了・明示的破棄などの節目で`fini()`による予備解放を行い、(3) ローカル変数はスコープを抜けると自動解放、(4) 循環参照は`init { weak ... }`で弱参照を宣言して回避する。実装はRustで行い、`Arc<Mutex<...>>`と`Weak`を活用、解放済みの二重処理防止や弱参照の自動nil化を含む。設計は明示的デリゲーション(`from`)とオーバーライドの厳密化(`override`必須)と一貫し、ブラウザ/WASMを含む現代環境での直感的・堅牢な開発体験を目指す。
|
||||
|
||||
## 1. 背景と動機
|
||||
- 既存パラダイムの課題: 手動メモリ管理は人為的錯誤に脆弱で、GCは停止時間/タイミング不確定性を招く。双方向参照(Parent↔Child、グラフ構造等)は参照カウント系でリークの温床となる。
|
||||
- 目標: 言語規範でライフサイクル規約を先に定義し、生成・使用・解放の節目を明示することで、安全で予測可能なメモリ管理を提供する。あわせて、表現力(デリゲーション、静的エントリポイント、WASM連携等)を損なわない。
|
||||
|
||||
## 2. 設計の中核(Language Design)
|
||||
### 2.1 Everything is Box
|
||||
あらゆる値(整数・文字列・配列・マップ・ユーザー定義オブジェクト・ユーティリティ等)をBoxで統一する。共通の生成・表示・比較・デバッグ・解放インターフェースを持ち、型ごとの最適化は実装側で行う。
|
||||
|
||||
### 2.2 フィールド宣言と初期化(`init { ... }`)
|
||||
- Boxの状態は`init { field1, field2, ... }`で宣言。循環参照が想定されるフィールドは`weak`修飾で弱参照にする(例: `init { weak parent }`)。
|
||||
- 生成は`new`で行い、必要に応じてコンストラクタ/`pack`等で初期値を設定する(詳細は言語ガイド参照)。
|
||||
|
||||
### 2.3 明示的破棄フック(`fini()`)
|
||||
- `fini()`はBox単位の予備解放フック。リソース解放(子Box解放、外部ハンドルclose、解除処理等)を記述できる。
|
||||
- 言語実装は、(a) フィールド再代入時、(b) スコープ終了時(ローカル環境解体)、(c) 明示呼出し時に`fini()`を安全に実行し、二重実行は抑止する。
|
||||
|
||||
### 2.4 ローカル変数とスコープ解放
|
||||
- `local`で宣言した変数はスコープ終了時に一括解放。未宣言代入はエラーとし、見落としを防止。
|
||||
- Static関数における所有権移転は`outbox`で明示化できる。
|
||||
|
||||
### 2.5 循環参照回避(`weak`)
|
||||
- `init { weak parent }`等で弱参照フィールドを宣言する。代入時に強参照を自動ダウングレードして格納し、アクセス時はupgradeを試みる。失敗時は`null`(自動nil化)を返す。
|
||||
- 双方向参照(Parent↔Child、グラフ)でも参照カウントが残存せず、リークを回避できる。
|
||||
|
||||
### 2.6 デリゲーション(`from`)と明示的オーバーライド
|
||||
- `box Child from Parent { ... }`で機能を委譲。多重デリゲーションにより複数親の機能合成をサポート。
|
||||
- 親メソッド呼出しは`from Parent.method(...)`で明示。暗黙の多段チェーン解決は明示性違反として禁止。上書きは`override`必須。
|
||||
|
||||
### 2.7 Static Boxエントリポイント
|
||||
- `static box Main { main() { ... } }`をアプリの規約化された開始点として用意。初回アクセス時に遅延初期化される。
|
||||
|
||||
## 3. 実装(Rustインタープリタ)
|
||||
本実装はRustにより、安全・明確な所有権モデル上でインタープリタを構築する。
|
||||
|
||||
### 3.1 実行時値(NyashValue)
|
||||
- `NyashValue`は`Integer`, `Float`, `Bool`, `String`, `Array`, `Map`, `Box(Arc<Mutex<dyn NyashBox>>)`に加え、`WeakBox(Weak<Mutex<dyn NyashBox>>)`、`Null`、`Void`等を持つ。
|
||||
- 弱参照は`upgrade_weak()`で強参照化を試み、失敗時は`None`→自動nil化の契機となる(実装詳細は最適化の都合上いくつかの互換層を伴う)。
|
||||
|
||||
### 3.2 インスタンス(InstanceBox)
|
||||
- `InstanceBox`は(互換層の)レガシーフィールド`fields`と次世代フィールド`fields_ng`を併用。弱参照は`fields_ng`で管理し、`set_weak_field`/`get_weak_field`が自動ダウングレード/アップグレードとnil化(失敗時)を司る。
|
||||
- インスタンスの`fini()`は二重呼出し防止フラグを持ち、内部フィールドのクリア等を行う。ユーザー定義`fini()`が存在すれば安全に先行実行される(インタープリタがメソッド本体を一時スタックで実行後、内部解放)。
|
||||
|
||||
### 3.3 予備解放(Finalization)
|
||||
- `finalization`モジュールは、解放済みIDのグローバル管理とスコープ追跡(`BoxFinalizer`)を提供。スコープ終了時/再代入時にBoxを走査し、`fini()`→解放済みマーク→追跡リストクリアの順で安全に解体する。
|
||||
- 代入時のふるまい: フィールドへ新しい値を設定する前に、旧値がインスタンスであれば`fini()`を呼出して二重リソース保持を回避する(ワークフローは`statements.rs`参照)。
|
||||
|
||||
### 3.4 構文サポート
|
||||
- パーサは`init { weak ... }`を解析し、`BoxDeclaration.weak_fields`に収集。フィールドアクセス/代入時に弱参照特有のハンドリング(upgrade/nil化/ダウングレード代入)を適用する。
|
||||
- Static Boxと多重デリゲーションは定義レジストリに登録され、実行時に適切な初期化・解決が行われる。
|
||||
|
||||
## 4. 安全性と正当性(概略)
|
||||
- 予測可能な破棄点: フィールド再代入・スコープ終了・明示的呼出しといった「節目」で`fini()`が必ず実行される。
|
||||
- 二重解放防止: 解放済みIDの記録により、`fini()`の多重呼出しは無害化される。
|
||||
- 循環参照回避: 双方向参照を弱参照にする規約で参照カウントの残留を防止。アクセス時の自動nil化でダングリング参照も防ぐ。
|
||||
- 明示性と可読性: `init`/`weak`/`from`/`override`/`local`等の構文規律により、所有権と到達可能性に関する意図をコードに刻む。
|
||||
|
||||
## 5. パフォーマンス特性(概略)
|
||||
- weakの`upgrade()`は原子的操作+分岐でオーバーヘッドは小さく、Mutexロックより低コストなケースが多い。
|
||||
- stop-the-world GCが存在せず、解放は節目ベースで分散されるため、レイテンシ予測性が高い。
|
||||
- 互換層の段階的移行(legacy→next-gen)は将来的にWeakBoxネイティブ化でさらなる最適化が可能。
|
||||
|
||||
## 6. 使用例
|
||||
### 6.1 親子の相互参照(弱参照)
|
||||
```nyash
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me) # 循環構造だが、子側がweak参照を使用
|
||||
}
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p } # 自動でweakに変換・格納
|
||||
getParentName() {
|
||||
if (me.parent != null) { return me.parent.getName() }
|
||||
else { return "Parent is gone" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 再代入時の予備解放
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
h = new Holder()
|
||||
h.obj = new SomeBox()
|
||||
h.obj = new SomeBox() # 旧objに対してfini()が自動呼出し
|
||||
```
|
||||
|
||||
### 6.3 Static Boxエントリ
|
||||
```nyash
|
||||
static box Main {
|
||||
init { console }
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
me.console.log("Everything is Box!")
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 関連研究
|
||||
- SwiftのARCにおける`weak`/`unowned`参照、Rustの`Arc`/`Weak`、Pythonの`weakref`は弱参照の実務的価値を示している。本研究は、弱参照の規約化と`init`/`fini`/スコープ解放を統合した「言語仕様レベルの一貫したライフサイクル設計」を提示する点で差異化される。
|
||||
- 継承ではなくデリゲーション(多重含む)を明示構文で組込むことで、暗黙の探索鎖を排し、構造的明示性とテスト容易性を高める。
|
||||
|
||||
## 8. 制限と今後の課題
|
||||
- 互換層の完全解消: レガシーフィールドから次世代`WeakBox`主導への移行を完了し、統一的な弱参照動作を保証する。
|
||||
- 競合解決: 多重デリゲーション時のメソッド競合検出と診断の改良。
|
||||
- 静的解析: 循環参照の静的検知・Lintの整備。
|
||||
- エコシステム: P2P系Box、WASM環境APIの充実、`async/await`統合の高速化、数値/配列Boxの最適化。
|
||||
|
||||
## 9. 結論
|
||||
Nyashは“Everything is Box”の統一モデルと、`init`/`fini`/`weak`/スコープ解放による予測可能で安全なメモリ管理を言語仕様として提示した。Rust実装により、所有権・スレッド安全・弱参照の自動nil化・二重解放防止を現実的コストで実現する。デリゲーション中心の設計は明示性を高め、教育・アート・Web・P2Pといった多様な開発領域での再利用性と保守性を支える。今後は互換層の収束と解析・最適化の強化により、研究用言語から実運用環境への移行を促進していく。
|
||||
|
||||
---
|
||||
|
||||
補足: 詳細は`docs/LANGUAGE_GUIDE.md`および`docs/reference/weak-reference-design.md`、実装は`src/`配下(`instance.rs`, `finalization.rs`, `interpreter/`)を参照。
|
||||
|
||||
81
docs/archive/design/decisions/論文_プロダクト寄りドラフト.md
Normal file
81
docs/archive/design/decisions/論文_プロダクト寄りドラフト.md
Normal file
@ -0,0 +1,81 @@
|
||||
# Nyash: 実務志向の一貫メモリモデルで日常のプログラミングを簡潔に
|
||||
|
||||
最終更新: 2025-08-13(プロダクト寄りドラフト)
|
||||
|
||||
## 概要(Abstract)
|
||||
Nyashは、すべての値を「Box」に統一し、`init`/`fini`/`weak`/スコープ解放を言語構文に組み込むことで、日常的なメモリ管理をわかりやすくする実務志向の言語です。新奇なアルゴリズムを主張するものではなく、過去数十年のプラクティス(RAII、弱参照、明示的ライフサイクル)を「最初から言語仕様で一貫させる」ことで、予測可能で安全なプログラミング体験を提供します。Rust実装により所有権とスレッド安全を担保しながら、再代入・スコープ終了・循環参照といった“よくある落とし穴”を構文で回避します。
|
||||
|
||||
## 1. 課題設定(なにを楽にするか)
|
||||
- 「いつ解放されるのか」がコードから読み取りづらい(暗黙のGC/規約依存)。
|
||||
- 双方向参照やグラフ構造でリークしやすい(参照カウントの残留)。
|
||||
- フィールド/ローカル/グローバルの寿命や責務が曖昧になりがち。
|
||||
|
||||
## 2. Nyashの要点(どう簡単にするか)
|
||||
- 統一モデル: Everything is Box。生成・代入・比較・解放の扱いが一貫。
|
||||
- 明示宣言: `init { ... }`でフィールド列挙、循環は`weak`で明示。
|
||||
- 予備解放: 再代入・スコープ終了・明示呼出しで`fini()`が走る規約。
|
||||
- ローカル変数: `local`を必須化し、未宣言代入エラーで早期検知。
|
||||
- デリゲーション: `from`で機能合成(多重対応)。`override`は明示必須。
|
||||
|
||||
## 3. なにが“新しい”のではなく“役立つ”のか(ポジショニング)
|
||||
- 研究的な新規性よりも、既知の良い手法の言語レベル統合に価値。
|
||||
- 「60年のメモリ管理の知見を、日常利用に迷わない形へ整理」
|
||||
- 開発者体験(DX)と運用の予測可能性(いつ・どこで解放)が主眼。
|
||||
|
||||
## 4. 開発者にとっての具体的メリット
|
||||
- リーク/二重解放の抑止: `fini()`は二重防止付き、弱参照は自動nil化。
|
||||
- 可読性: フィールド寿命・弱参照・委譲関係がコードから一目で分かる。
|
||||
- テスト容易性: 多重デリゲーションで依存差し替えが明瞭。
|
||||
- ブラウザ対応: WASMで“動かして学ぶ”導線が短い。
|
||||
|
||||
## 5. 最小構文サンプル
|
||||
```nyash
|
||||
box Parent { init { child } }
|
||||
box Child { init { weak parent } }
|
||||
|
||||
p = new Parent()
|
||||
p.child = new Child()
|
||||
p.child.setParent(p) # 子→親はweak。循環でもリークしにくい
|
||||
|
||||
box Holder { init { obj } }
|
||||
h = new Holder()
|
||||
h.obj = new SomeBox()
|
||||
h.obj = new SomeBox() # 旧objに対しfini()が自動呼出し
|
||||
|
||||
static box Main { main() { print("OK") } }
|
||||
```
|
||||
|
||||
## 6. 実装概要(Rust)
|
||||
- 実行時値: `NyashValue`に`Box(Arc<Mutex<_>>)`と`WeakBox(Weak<Mutex<_>>)`を持ち、弱参照はアクセス時upgrade→失敗で`null`。
|
||||
- インスタンス: `InstanceBox`が`set_weak_field`/`get_weak_field`で弱参照の格納・自動nil化を扱う。`fini()`は二重防止付き。
|
||||
- スコープ解放: `finalization`モジュールの`BoxFinalizer`がスコープ終了時に一括予備解放。
|
||||
- 代入時処理: フィールド再代入前に旧値へ`fini()`。安全側に倒す規約。
|
||||
|
||||
## 7. 非ゴール(誤解を避けるために)
|
||||
- 新規GCの提案ではない。停止時間最適化などGC起因の研究課題は対象外。
|
||||
- 低レベル最適化の網羅ではない。まずは実務的に“迷わない統一手引き”。
|
||||
|
||||
## 8. 導入・評価の観点(プロダクト視点)
|
||||
- DX: 未宣言代入の早期検知、解放点の明示、弱参照のシンプル化がバグ件数/修正時間に与える影響。
|
||||
- 安定運用: リーク/ダングリング参照/二重解放の再現テストと回避率。
|
||||
- 性能: 弱参照upgrade/`fini()`呼出しのオーバーヘッド(マイクロ/アプリ)。
|
||||
- 学習曲線: Web/WASMのプレイグラウンドでの到達時間・課題種別。
|
||||
|
||||
## 9. 現状とロードマップ
|
||||
- 現状: インタープリタ、弱参照の自動nil化、再代入時`fini()`、多重デリゲーションの基盤が稼働。
|
||||
- 近接課題: レガシー互換層の整理、競合検出メッセージの改善、P2P/標準Boxの拡充。
|
||||
|
||||
## 10. まとめ
|
||||
Nyashは“新しい理論”よりも“迷わない実装規約”で、日常のメモリ管理を静かに楽にすることを狙う。Boxの統一モデルと、`init`/`fini`/`weak`/スコープ解放の一貫性により、解放のタイミングがコードから読める。弱参照の自動nil化と二重解放防止は、実務の落とし穴を減らす。WASM対応の軽い体験とRust実装の堅牢さを両輪に、まずは「使って心地よい」ことを優先し、順次、解析・最適化・エコシステムを整えていく。
|
||||
|
||||
— 参考: 詳細は `docs/LANGUAGE_GUIDE.md`, `docs/reference/weak-reference-design.md` と `src/` 実装を参照。
|
||||
|
||||
## 付録: ブラウザデモ活用(再現性と導線)
|
||||
- Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
- ガイド: プレイグラウンド_ガイド.md(シナリオと手順)
|
||||
- サンプル集: プレイグラウンド_サンプル.md(コピー&ペースト用)
|
||||
|
||||
活用ポイント:
|
||||
- `init`/`fini`/`weak`/スコープ解放の最小例を即時実行し、期待ログ(例: `Thing.fini`、`parent is gone`)で確認可能。
|
||||
- レビュワー/読者はゼロインストールで再現でき、arXiv原稿への短縮URL/QR掲載と相性が良い。
|
||||
- 比較検証(weakなし/あり、再代入前後、スコープ内/外)を1ページで切替・確認可能。
|
||||
337
docs/archive/design/explicit-delegation-revolution.md
Normal file
337
docs/archive/design/explicit-delegation-revolution.md
Normal file
@ -0,0 +1,337 @@
|
||||
# 🌟 明示的デリゲーション革命:なぜNyashは世界初の完全明示デリゲーション言語になったのか
|
||||
|
||||
作成日: 2025年8月11日
|
||||
著者: Nyashプロジェクトチーム
|
||||
ステータス: 設計思想決定版
|
||||
|
||||
## 📜 はじめに:革命の始まり
|
||||
|
||||
2025年8月11日、Nyashプログラミング言語の開発において、言語設計史上最大級の発見がありました。それは、**暗黙のオーバーライド問題**の発見と、それを解決する**完全明示デリゲーション構文**の誕生です。
|
||||
|
||||
この文書は、なぜこの革命が必要だったのか、どのような思想の元に設計されたのかを詳しく解説します。
|
||||
|
||||
## 🚨 問題の発見:暗黙の悪魔
|
||||
|
||||
### HashMap::insert による意図しない上書き
|
||||
|
||||
Nyashの実装を詳しく調査した結果、恐ろしい問題が発見されました:
|
||||
|
||||
```rust
|
||||
// instance.rs - add_method関数
|
||||
pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) {
|
||||
let mut new_methods = (*self.methods).clone();
|
||||
new_methods.insert(method_name, method_ast); // ← 暗黙の上書き!
|
||||
self.methods = Arc::new(new_methods);
|
||||
}
|
||||
```
|
||||
|
||||
この実装により、以下のような**暗黙のオーバーライド**が発生していました:
|
||||
|
||||
```nyash
|
||||
box Node {
|
||||
send(msg) { // 最初の定義
|
||||
print("Version 1")
|
||||
}
|
||||
|
||||
send(msg) { // 暗黙に上書きされる
|
||||
print("Version 2") // ← こちらだけが残る
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Nyash哲学との根本的矛盾
|
||||
|
||||
この問題は、Nyashの3つの核心哲学と完全に矛盾していました:
|
||||
|
||||
1. **明示性重視**: 「何が起きているかを隠さない」
|
||||
2. **Everything is Box**: 「統一された世界観」
|
||||
3. **初学者フレンドリー**: 「複雑な概念を分かりやすく表現」
|
||||
|
||||
暗黙のオーバーライドは、これらすべてを破壊する**言語設計上の致命的欠陥**だったのです。
|
||||
|
||||
## 💡 解決への道:3AI大会議
|
||||
|
||||
### AI専門家による徹底分析
|
||||
|
||||
この問題の解決策を求めて、言語設計の専門家であるGeminiとChatGPTに相談を行いました。結果は予想を上回る**圧倒的な支持**でした。
|
||||
|
||||
#### Gemini先生の評価
|
||||
> **「全面的に賛成します」**
|
||||
> **「極めて重要な一歩」**
|
||||
> **「Nyashのアイデンティティを確立する」**
|
||||
|
||||
#### ChatGPT先生の評価
|
||||
> **「強く整合する」**
|
||||
> **「安全性と読みやすさを大幅に向上」**
|
||||
> **「実装工数3-5日程度」**
|
||||
|
||||
### 専門的視点からの裏付け
|
||||
|
||||
両専門家から以下の重要な指摘がありました:
|
||||
|
||||
1. **哲学的整合性**: Nyashの明示性哲学と完全に合致
|
||||
2. **技術的優位性**: 他言語の問題(Python MRO、Java super等)を根本解決
|
||||
3. **学習効果**: 初学者にとってより理解しやすい設計
|
||||
4. **実装可能性**: 技術的に十分実現可能
|
||||
|
||||
## 🌟 革命的解決策:Override + From 統一構文
|
||||
|
||||
### 4つの統一原則
|
||||
|
||||
この問題を解決するため、以下の4つの統一原則を確立しました:
|
||||
|
||||
#### 1. 宣言の統一
|
||||
```nyash
|
||||
box Child from Parent // デリゲーション関係の明示
|
||||
```
|
||||
|
||||
#### 2. 置換の統一
|
||||
```nyash
|
||||
override methodName() // オーバーライドの明示宣言
|
||||
```
|
||||
|
||||
#### 3. 呼び出しの統一
|
||||
```nyash
|
||||
from Parent.methodName() // 親実装の明示呼び出し
|
||||
```
|
||||
|
||||
#### 4. 構築の統一
|
||||
```nyash
|
||||
from Parent.init() // コンストラクタも同じ構文
|
||||
```
|
||||
|
||||
### 完全な例
|
||||
|
||||
```nyash
|
||||
box MeshNode : P2PBox {
|
||||
init routing = RoutingTable()
|
||||
|
||||
constructor(nodeId, world) {
|
||||
from P2PBox.constructor(nodeId, world) // 統一構文
|
||||
me.routing = RoutingTable()
|
||||
}
|
||||
|
||||
override send(intent, data, target) { // 明示的置換
|
||||
me.routing.log(target)
|
||||
from P2PBox.send(intent, data, target) // 明示的呼び出し
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔥 革命的特徴
|
||||
|
||||
### 1. 完全な明示性
|
||||
|
||||
**従来の問題**:
|
||||
- 何がオーバーライドされているかわからない
|
||||
- 親のどのメソッドを呼んでいるかわからない
|
||||
- 実行順序が不明確
|
||||
|
||||
**Nyashの解決**:
|
||||
- `override` で置換を明示宣言
|
||||
- `from Parent.method()` で呼び出し先を完全明示
|
||||
- 上から下への直感的な実行順序
|
||||
|
||||
### 2. 曖昧性の完全排除
|
||||
|
||||
**多重デリゲーション時の曖昧性解消**:
|
||||
```nyash
|
||||
box SmartNode : P2PBox, Logger {
|
||||
override send(intent, data, target) {
|
||||
from Logger.debug("Sending: " + intent) // どのLoggerか明確
|
||||
from P2PBox.send(intent, data, target) // どのP2PBoxか明確
|
||||
}
|
||||
}
|
||||
|
||||
// 競合時は更に明示的に
|
||||
box ConflictNode from ParentA, ParentB {
|
||||
override ParentA.process(data) { // ParentAのprocessを置換
|
||||
from ParentA.process(data)
|
||||
}
|
||||
|
||||
override ParentB.process(data) { // ParentBのprocessを置換
|
||||
from ParentB.process(data)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 学習コストの最小化
|
||||
|
||||
**覚えるべきルール**:
|
||||
1. 親のメソッドを置換したい → `override`
|
||||
2. 親のメソッドを呼びたい → `from Parent.method()`
|
||||
3. 親のコンストラクタを呼びたい → `from Parent.init()`
|
||||
|
||||
たった3つのルールで、すべてのデリゲーション操作が表現できます。
|
||||
|
||||
## 🌍 他言語との比較:なぜNyashが優れているのか
|
||||
|
||||
### Python の問題
|
||||
```python
|
||||
# MRO(Method Resolution Order)地獄
|
||||
class C(A, B):
|
||||
def method(self):
|
||||
super().method() # どっちのmethod?
|
||||
```
|
||||
|
||||
**Nyash の解決**:
|
||||
```nyash
|
||||
box C : A, B {
|
||||
override method() {
|
||||
from A.method() // Aのmethodと明示
|
||||
from B.method() // Bのmethodと明示
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Java/C# の問題
|
||||
```java
|
||||
// どの親のmethodを呼んでいるかコードから不明
|
||||
@Override
|
||||
public void method() {
|
||||
super.method(); // 単一継承でも曖昧
|
||||
}
|
||||
```
|
||||
|
||||
**Nyash の解決**:
|
||||
```nyash
|
||||
override method() {
|
||||
from Parent.method() // どのParentか完全に明確
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript の問題
|
||||
```typescript
|
||||
// 暗黙のオーバーライドによる事故
|
||||
class Child extends Parent {
|
||||
method() { // うっかり同名メソッド → 意図しない上書き
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Nyash の解決**:
|
||||
```nyash
|
||||
// overrideなしで同名メソッド → コンパイルエラー
|
||||
// 意図しない上書きは100%防止
|
||||
```
|
||||
|
||||
## 🎯 設計思想の深層
|
||||
|
||||
### Everything is Box との統合
|
||||
|
||||
この革命は、Nyashの根本思想「Everything is Box」と完全に統合されています:
|
||||
|
||||
- **Box同士のデリゲーション**: 階層ではなく、協力関係
|
||||
- **Boxメソッドの明示的管理**: どのBoxのどのメソッドかが常に明確
|
||||
- **Box構築の明示的制御**: コンストラクタも普通のメソッド
|
||||
|
||||
### 明示性の哲学
|
||||
|
||||
Nyashが目指すのは、**「魔法のない言語」**です:
|
||||
|
||||
- 隠れた処理は一切なし
|
||||
- すべての動作がコードに現れる
|
||||
- 初学者でも上級者でも同じように理解できる
|
||||
|
||||
### 初学者への配慮
|
||||
|
||||
複雑な概念を、シンプルな文法で表現:
|
||||
|
||||
- `override` = 「置き換えます」
|
||||
- `from Parent.method()` = 「親の方法を使います」
|
||||
- コンパイルエラー = 「間違いを素早く教える」
|
||||
|
||||
## 🚀 実装戦略
|
||||
|
||||
### 段階的導入
|
||||
|
||||
ChatGPT先生の提案による実装ロードマップ:
|
||||
|
||||
**Phase 1(0.5-1日)**:
|
||||
- `override` キーワード追加
|
||||
- 基本パーサー拡張
|
||||
|
||||
**Phase 2(1-2日)**:
|
||||
- 暗黙オーバーライド検出
|
||||
- コンストラクタ重複禁止
|
||||
|
||||
**Phase 3(1日)**:
|
||||
- `from Parent.init()` 実装
|
||||
- エラーメッセージ改善
|
||||
|
||||
### 移行支援
|
||||
|
||||
既存コードの安全な移行:
|
||||
- 段階的警告システム
|
||||
- 自動修正支援ツール
|
||||
- 詳細な移行ガイド
|
||||
|
||||
## 🌟 期待される効果
|
||||
|
||||
### 1. 開発者体験の革命的向上
|
||||
|
||||
**Before(暗黙オーバーライド)**:
|
||||
- バグの発見が困難
|
||||
- 意図しない動作
|
||||
- デバッグに多大な時間
|
||||
|
||||
**After(明示的オーバーライド)**:
|
||||
- コンパイル時に間違いを検出
|
||||
- 意図が明確に表現される
|
||||
- デバッグ時間の劇的短縮
|
||||
|
||||
### 2. コードの可読性向上
|
||||
|
||||
**Before**:
|
||||
```nyash
|
||||
// これは何をオーバーライドしている?
|
||||
send(msg) {
|
||||
// 親を呼んでる?呼んでない?
|
||||
processMessage(msg)
|
||||
}
|
||||
```
|
||||
|
||||
**After**:
|
||||
```nyash
|
||||
// P2PBoxのsendを明示的にオーバーライド
|
||||
override send(msg) {
|
||||
processMessage(msg)
|
||||
from P2PBox.send(msg) // P2PBoxの実装も使用
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 保守性の向上
|
||||
|
||||
- 変更の影響範囲が明確
|
||||
- リファクタリングが安全
|
||||
- チーム開発での誤解を防止
|
||||
|
||||
## 🏆 結論:言語設計史に残る革命
|
||||
|
||||
この明示的デリゲーション革命により、Nyashは以下を達成しました:
|
||||
|
||||
### 世界初の完全明示デリゲーション言語
|
||||
|
||||
1. **完全な明示性**: すべての動作を明示
|
||||
2. **曖昧性の完全排除**: どんな複雑なケースも明確
|
||||
3. **統一構文**: デリゲーションとオーバーライドの完全統合
|
||||
4. **初学者フレンドリー**: 学習しやすく、間違いにくい
|
||||
|
||||
### プログラミング言語設計への貢献
|
||||
|
||||
- **暗黙の悪魔**からの完全な解放
|
||||
- **多重デリゲーション**の安全で明確な実現
|
||||
- **コード可読性**の新しい基準の確立
|
||||
|
||||
### 未来への影響
|
||||
|
||||
Nyashのこの革命は、今後のプログラミング言語設計に大きな影響を与えるでしょう。「暗黙より明示」という哲学が、ついに技術的に完全実現されたのです。
|
||||
|
||||
---
|
||||
|
||||
**2025年8月11日は、プログラミング言語史において「明示的デリゲーション革命の日」として記憶されることでしょう。** 🎊
|
||||
|
||||
この革命により、Nyashは単なるプログラミング言語を超えて、**新しいプログラミングパラダイムの先駆者**となりました。
|
||||
|
||||
Everything is Box. Everything is Explicit. Everything is Beautiful. 🌟
|
||||
300
docs/archive/design/lisp_interpreter_design.md
Normal file
300
docs/archive/design/lisp_interpreter_design.md
Normal file
@ -0,0 +1,300 @@
|
||||
# 🎯 Nyash LISP インタープリタ設計書
|
||||
|
||||
## 概要
|
||||
Nyash上で動作するLISPインタープリタを実装する。「Everything is Box」哲学に基づき、LISPのS式をNyashのBoxで表現する。
|
||||
|
||||
## 🏗️ アーキテクチャ
|
||||
|
||||
### 1. コアBox実装
|
||||
|
||||
#### ConsBox - cons cell(ペア)
|
||||
```nyash
|
||||
box ConsBox {
|
||||
car // 最初の要素
|
||||
cdr // 残りの要素(通常は別のConsBoxかNullBox)
|
||||
|
||||
init { car, cdr }
|
||||
|
||||
func getCar() { return me.car }
|
||||
func getCdr() { return me.cdr }
|
||||
func setCar(value) { me.car = value }
|
||||
func setCdr(value) { me.cdr = value }
|
||||
|
||||
func toString() {
|
||||
if (NullBox.isNull(me.cdr)) {
|
||||
return "(" + me.car.toString() + ")"
|
||||
}
|
||||
// TODO: 適切なリスト表示
|
||||
return "(" + me.car.toString() + " . " + me.cdr.toString() + ")"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### SymbolBox - シンボル
|
||||
```nyash
|
||||
box SymbolBox {
|
||||
name
|
||||
|
||||
init { name }
|
||||
|
||||
func getName() { return me.name }
|
||||
func toString() { return me.name }
|
||||
}
|
||||
```
|
||||
|
||||
#### LispEnvironment - 変数環境
|
||||
```nyash
|
||||
box LispEnvironment {
|
||||
bindings // MapBox: symbol name -> value
|
||||
parent // 親環境(スコープチェーン用)
|
||||
|
||||
init { parent }
|
||||
|
||||
func define(symbol, value) {
|
||||
me.bindings.set(symbol.getName(), value)
|
||||
}
|
||||
|
||||
func lookup(symbol) {
|
||||
name = symbol.getName()
|
||||
if (me.bindings.has(name)) {
|
||||
return me.bindings.get(name)
|
||||
}
|
||||
if (not NullBox.isNull(me.parent)) {
|
||||
return me.parent.lookup(symbol)
|
||||
}
|
||||
return new ErrorBox("Unbound variable: " + name)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. S式パーサー
|
||||
|
||||
```nyash
|
||||
box SExpressionParser {
|
||||
tokens
|
||||
position
|
||||
|
||||
init { input }
|
||||
|
||||
func parse() {
|
||||
me.tokens = me.tokenize(input)
|
||||
me.position = 0
|
||||
return me.parseExpression()
|
||||
}
|
||||
|
||||
func parseExpression() {
|
||||
token = me.currentToken()
|
||||
|
||||
if (token == "(") {
|
||||
return me.parseList()
|
||||
}
|
||||
if (token.isNumber()) {
|
||||
return new IntegerBox(token.toNumber())
|
||||
}
|
||||
if (token.isString()) {
|
||||
return new StringBox(token.getValue())
|
||||
}
|
||||
// シンボル
|
||||
return new SymbolBox(token)
|
||||
}
|
||||
|
||||
func parseList() {
|
||||
me.consume("(")
|
||||
elements = new ArrayBox()
|
||||
|
||||
loop(me.currentToken() != ")") {
|
||||
elements.push(me.parseExpression())
|
||||
}
|
||||
|
||||
me.consume(")")
|
||||
return me.arrayToConsList(elements)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. eval関数
|
||||
|
||||
```nyash
|
||||
box LispEvaluator {
|
||||
globalEnv
|
||||
|
||||
init {}
|
||||
|
||||
func eval(expr, env) {
|
||||
// 自己評価的な値
|
||||
if (expr.isNumber() or expr.isString()) {
|
||||
return expr
|
||||
}
|
||||
|
||||
// シンボル
|
||||
if (expr.isSymbol()) {
|
||||
return env.lookup(expr)
|
||||
}
|
||||
|
||||
// リスト(関数適用か特殊形式)
|
||||
if (expr.isCons()) {
|
||||
car = expr.getCar()
|
||||
|
||||
// 特殊形式のチェック
|
||||
if (car.isSymbol()) {
|
||||
name = car.getName()
|
||||
|
||||
if (name == "quote") {
|
||||
return me.evalQuote(expr, env)
|
||||
}
|
||||
if (name == "if") {
|
||||
return me.evalIf(expr, env)
|
||||
}
|
||||
if (name == "define") {
|
||||
return me.evalDefine(expr, env)
|
||||
}
|
||||
if (name == "lambda") {
|
||||
return me.evalLambda(expr, env)
|
||||
}
|
||||
// ... 他の特殊形式
|
||||
}
|
||||
|
||||
// 通常の関数適用
|
||||
func = me.eval(car, env)
|
||||
args = me.evalList(expr.getCdr(), env)
|
||||
return me.apply(func, args)
|
||||
}
|
||||
|
||||
return expr
|
||||
}
|
||||
|
||||
func apply(func, args) {
|
||||
// プリミティブ関数
|
||||
if (func.isPrimitive()) {
|
||||
return func.applyPrimitive(args)
|
||||
}
|
||||
|
||||
// ラムダ式
|
||||
if (func.isLambda()) {
|
||||
newEnv = new LispEnvironment(func.getEnv())
|
||||
params = func.getParams()
|
||||
|
||||
// パラメータをバインド
|
||||
// ... 実装
|
||||
|
||||
return me.eval(func.getBody(), newEnv)
|
||||
}
|
||||
|
||||
return new ErrorBox("Not a function: " + func.toString())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 基本関数の実装
|
||||
|
||||
```nyash
|
||||
box LispPrimitives {
|
||||
func setupGlobalEnv(env) {
|
||||
// 算術演算
|
||||
env.define(new SymbolBox("+"), new PrimitiveBox(me.add))
|
||||
env.define(new SymbolBox("-"), new PrimitiveBox(me.subtract))
|
||||
env.define(new SymbolBox("*"), new PrimitiveBox(me.multiply))
|
||||
env.define(new SymbolBox("/"), new PrimitiveBox(me.divide))
|
||||
|
||||
// リスト操作
|
||||
env.define(new SymbolBox("cons"), new PrimitiveBox(me.cons))
|
||||
env.define(new SymbolBox("car"), new PrimitiveBox(me.car))
|
||||
env.define(new SymbolBox("cdr"), new PrimitiveBox(me.cdr))
|
||||
env.define(new SymbolBox("list"), new PrimitiveBox(me.list))
|
||||
|
||||
// 述語
|
||||
env.define(new SymbolBox("null?"), new PrimitiveBox(me.isNull))
|
||||
env.define(new SymbolBox("pair?"), new PrimitiveBox(me.isPair))
|
||||
env.define(new SymbolBox("number?"), new PrimitiveBox(me.isNumber))
|
||||
|
||||
// 比較
|
||||
env.define(new SymbolBox("="), new PrimitiveBox(me.equal))
|
||||
env.define(new SymbolBox("<"), new PrimitiveBox(me.lessThan))
|
||||
env.define(new SymbolBox(">"), new PrimitiveBox(me.greaterThan))
|
||||
}
|
||||
|
||||
func add(args) {
|
||||
sum = 0
|
||||
current = args
|
||||
loop(not NullBox.isNull(current)) {
|
||||
sum = sum + current.getCar().getValue()
|
||||
current = current.getCdr()
|
||||
}
|
||||
return new IntegerBox(sum)
|
||||
}
|
||||
|
||||
// ... 他のプリミティブ関数
|
||||
}
|
||||
```
|
||||
|
||||
## 🎮 使用例
|
||||
|
||||
```lisp
|
||||
; Nyash LISPでの階乗計算
|
||||
(define factorial
|
||||
(lambda (n)
|
||||
(if (= n 0)
|
||||
1
|
||||
(* n (factorial (- n 1))))))
|
||||
|
||||
(factorial 5) ; => 120
|
||||
|
||||
; リスト操作
|
||||
(define map
|
||||
(lambda (f lst)
|
||||
(if (null? lst)
|
||||
'()
|
||||
(cons (f (car lst))
|
||||
(map f (cdr lst))))))
|
||||
|
||||
(map (lambda (x) (* x x)) '(1 2 3 4 5)) ; => (1 4 9 16 25)
|
||||
```
|
||||
|
||||
## 📋 実装ステップ
|
||||
|
||||
1. **Phase 1: 基本データ構造**
|
||||
- ConsBox実装
|
||||
- SymbolBox実装
|
||||
- 基本的なリスト操作
|
||||
|
||||
2. **Phase 2: パーサー**
|
||||
- トークナイザー
|
||||
- S式パーサー
|
||||
- 文字列→Box変換
|
||||
|
||||
3. **Phase 3: 評価器**
|
||||
- eval関数の基本実装
|
||||
- 環境(Environment)管理
|
||||
- 特殊形式の処理
|
||||
|
||||
4. **Phase 4: 基本関数**
|
||||
- 四則演算
|
||||
- リスト操作(cons, car, cdr)
|
||||
- 述語関数
|
||||
|
||||
5. **Phase 5: 高度な機能**
|
||||
- lambda式
|
||||
- クロージャ
|
||||
- 再帰関数のサポート
|
||||
|
||||
6. **Phase 6: 最適化とデバッグ**
|
||||
- DebugBoxとの統合
|
||||
- エラーハンドリングの改善
|
||||
- パフォーマンス最適化
|
||||
|
||||
## 🎯 成功基準
|
||||
|
||||
- 基本的なLISPプログラムが動作する
|
||||
- 再帰関数が正しく実行される
|
||||
- リスト操作が適切に機能する
|
||||
- Nyashの他のBox機能と統合できる
|
||||
|
||||
## 💡 技術的課題
|
||||
|
||||
1. **末尾再帰最適化**: NyashはTCOをサポートしていないため、深い再帰でスタックオーバーフローの可能性
|
||||
2. **ガベージコレクション**: Nyashのfini()との統合方法
|
||||
3. **マクロシステム**: 将来的な実装検討事項
|
||||
|
||||
---
|
||||
|
||||
「Everything is Box」の究極の実証 - LISPインタープリタ on Nyash!
|
||||
393
docs/archive/design/technical_architecture.md
Normal file
393
docs/archive/design/technical_architecture.md
Normal file
@ -0,0 +1,393 @@
|
||||
# 🔧 Nyash Technical Architecture & Implementation Guide
|
||||
|
||||
**最終更新: 2025年8月8日**
|
||||
|
||||
## 📐 アーキテクチャ概要
|
||||
|
||||
Nyashインタープリターは以下の主要コンポーネントから構成されています:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Nyash Runtime │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Parser │ AST │ Interpreter │
|
||||
│ ├─Tokenizer │ ├─ASTNode │ ├─SharedState │
|
||||
│ ├─ParseError │ ├─Span │ ├─NyashBox │
|
||||
│ └─NyashParser │ └─BoxDecl │ └─RuntimeError │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Box System │
|
||||
│ ├─StringBox ├─IntegerBox ├─BoolBox ├─ArrayBox │
|
||||
│ ├─MapBox ├─DebugBox ├─MathBox ├─TimeBox │
|
||||
│ ├─RandomBox ├─SoundBox ├─MethodBox└─TypeBox │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Memory Management │
|
||||
│ ├─InstanceBox ├─GlobalBox ├─finalization │
|
||||
│ └─reference counting + explicit destructors │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎯 核心設計原則
|
||||
|
||||
### 1. **Everything is Box**
|
||||
すべてのデータがNyashBoxトレイトを実装:
|
||||
```rust
|
||||
pub trait NyashBox: Any + Send + Sync {
|
||||
fn to_string_box(&self) -> Box<StringBox>;
|
||||
fn clone_box(&self) -> Box<dyn NyashBox>;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn box_id(&self) -> usize;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. **Unified Memory Model**
|
||||
- **GlobalBox**: 全グローバル変数・関数の統一管理
|
||||
- **Local Variables**: 一時的なローカルスコープ
|
||||
- **SharedState**: 並行処理でのスレッド間共有
|
||||
|
||||
### 3. **Zero-Copy Philosophy**
|
||||
- Arc/Rc による効率的な参照共有
|
||||
- Clone-on-Write パターンの活用
|
||||
- 最小限のメモリコピー
|
||||
|
||||
## 🏗️ 主要コンポーネント
|
||||
|
||||
### **Tokenizer (src/tokenizer.rs)**
|
||||
```rust
|
||||
pub enum TokenType {
|
||||
// 基本トークン
|
||||
IDENTIFIER(String), STRING(String), INTEGER(i64), FLOAT(f64),
|
||||
|
||||
// 演算子
|
||||
PLUS, MINUS, MULTIPLY, DIVIDE,
|
||||
EQ, NE, LT, GT, LE, GE,
|
||||
NOT, AND, OR,
|
||||
|
||||
// キーワード
|
||||
LOCAL, OUTBOX, STATIC, FUNCTION, BOX,
|
||||
IF, ELSE, LOOP, BREAK, RETURN,
|
||||
NOWAIT, AWAIT,
|
||||
|
||||
// 区切り文字
|
||||
LPAREN, RPAREN, LBRACE, RBRACE,
|
||||
COMMA, DOT, ASSIGN,
|
||||
}
|
||||
```
|
||||
|
||||
### **AST構造 (src/ast.rs)**
|
||||
```rust
|
||||
pub enum ASTNode {
|
||||
// 変数宣言(初期化対応)
|
||||
Local {
|
||||
variables: Vec<String>,
|
||||
initial_values: Vec<Option<Box<ASTNode>>>, // 🚀 2025-08-08実装
|
||||
span: Span,
|
||||
},
|
||||
|
||||
// Box宣言(static対応)
|
||||
BoxDeclaration {
|
||||
name: String,
|
||||
fields: Vec<String>,
|
||||
methods: HashMap<String, ASTNode>,
|
||||
constructors: HashMap<String, ASTNode>,
|
||||
init_fields: Vec<String>,
|
||||
is_interface: bool,
|
||||
extends: Option<String>,
|
||||
implements: Vec<String>,
|
||||
type_parameters: Vec<String>, // ジェネリクス
|
||||
is_static: bool, // 🚀 Static Box
|
||||
static_init: Option<Vec<ASTNode>>,
|
||||
},
|
||||
|
||||
// 非同期
|
||||
Nowait { variable: String, expression: Box<ASTNode> },
|
||||
|
||||
// その他の全ASTノード...
|
||||
}
|
||||
```
|
||||
|
||||
### **Interpreter Core (src/interpreter/mod.rs)**
|
||||
|
||||
#### SharedState - 並行処理アーキテクチャ
|
||||
```rust
|
||||
#[derive(Clone)]
|
||||
pub struct SharedState {
|
||||
/// 🌍 グローバルBox:すべてのグローバル変数・関数を管理
|
||||
pub global_box: Arc<Mutex<InstanceBox>>,
|
||||
|
||||
/// 📦 Box宣言:クラス定義情報を管理
|
||||
pub box_declarations: Arc<RwLock<HashMap<String, BoxDeclaration>>>,
|
||||
|
||||
/// ⚡ Static関数:static box関数を管理
|
||||
pub static_functions: Arc<RwLock<HashMap<String, HashMap<String, ASTNode>>>>,
|
||||
|
||||
/// 📁 インクルード済みファイル:重複読み込み防止
|
||||
pub included_files: Arc<Mutex<HashSet<String>>>,
|
||||
}
|
||||
```
|
||||
|
||||
#### NyashInterpreter - 実行エンジン
|
||||
```rust
|
||||
pub struct NyashInterpreter {
|
||||
/// 🤝 共有状態:マルチスレッド対応
|
||||
pub shared: SharedState,
|
||||
|
||||
/// 📍 ローカル変数:スレッドローカル
|
||||
pub local_vars: HashMap<String, Box<dyn NyashBox>>,
|
||||
|
||||
/// 📤 outbox変数:所有権移転用
|
||||
pub outbox_vars: HashMap<String, Box<dyn NyashBox>>,
|
||||
|
||||
/// 🔄 制御フロー:return/break/throw管理
|
||||
pub control_flow: ControlFlow,
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 革新的実装詳細
|
||||
|
||||
### 1. **GlobalBox革命**
|
||||
従来のEnvironmentスコープチェーンを廃止:
|
||||
|
||||
```rust
|
||||
// ❌ 従来のスコープチェーン(複雑・低効率)
|
||||
Environment -> ParentEnvironment -> GlobalEnvironment
|
||||
|
||||
// ✅ GlobalBox統一管理(シンプル・高効率)
|
||||
local_vars -> GlobalBox (直接2段階解決)
|
||||
```
|
||||
|
||||
**効果:**
|
||||
- メモリ使用量30%削減
|
||||
- 変数解決速度向上
|
||||
- コード複雑性大幅削減
|
||||
|
||||
### 2. **Static Box Lazy Initialization**
|
||||
```rust
|
||||
impl NyashInterpreter {
|
||||
pub fn ensure_static_box_initialized(&mut self, name: &str) -> Result<(), RuntimeError> {
|
||||
// 1. 初期化済みチェック
|
||||
if self.is_static_box_initialized(name) { return Ok(()); }
|
||||
|
||||
// 2. 循環参照検出
|
||||
if self.is_static_box_initializing(name) {
|
||||
return Err(RuntimeError::CircularDependency(name.to_string()));
|
||||
}
|
||||
|
||||
// 3. 初期化実行
|
||||
self.initialize_static_box(name)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**遅延初期化の利点:**
|
||||
- 効率的なリソース利用
|
||||
- 循環参照の安全な検出
|
||||
- JavaScript ES Modules準拠の実績あるパターン
|
||||
|
||||
### 3. **並行処理アーキテクチャ**
|
||||
```rust
|
||||
pub fn execute_nowait(&mut self, variable: &str, expression: &ASTNode) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||
let shared_state = self.shared.clone(); // SharedState複製
|
||||
let expr = expression.clone(); // AST複製
|
||||
|
||||
// 🚀 別スレッドで非同期実行
|
||||
let handle = std::thread::spawn(move || {
|
||||
let mut interpreter = NyashInterpreter::new_with_shared(shared_state);
|
||||
interpreter.execute_expression(&expr)
|
||||
});
|
||||
|
||||
// FutureBoxとして結果を返す
|
||||
let future_box = FutureBox::new(handle);
|
||||
self.set_variable(variable, Box::new(future_box))?;
|
||||
Ok(Box::new(VoidBox::new()))
|
||||
}
|
||||
```
|
||||
|
||||
### 4. **初期化付きlocal宣言実装**
|
||||
```rust
|
||||
// AST: 各変数の初期化状態を個別管理
|
||||
Local {
|
||||
variables: vec!["a", "b", "c"],
|
||||
initial_values: vec![
|
||||
Some(Box::new(/* 10 + 20 */)), // a = 30
|
||||
None, // b(初期化なし)
|
||||
Some(Box::new(/* "hello" */)), // c = "hello"
|
||||
],
|
||||
}
|
||||
|
||||
// Interpreter: 効率的な初期化処理
|
||||
for (i, var_name) in variables.iter().enumerate() {
|
||||
if let Some(Some(init_expr)) = initial_values.get(i) {
|
||||
let init_value = self.execute_expression(init_expr)?;
|
||||
self.declare_local_variable(var_name, init_value);
|
||||
} else {
|
||||
self.declare_local_variable(var_name, Box::new(VoidBox::new()));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 Box System詳細
|
||||
|
||||
### **Core Boxes**
|
||||
```rust
|
||||
// StringBox: 文字列データ
|
||||
pub struct StringBox { pub value: String }
|
||||
|
||||
// IntegerBox: 整数データ
|
||||
pub struct IntegerBox { pub value: i64 }
|
||||
|
||||
// BoolBox: 論理値データ
|
||||
pub struct BoolBox { pub value: bool }
|
||||
|
||||
// ArrayBox: 動的配列
|
||||
pub struct ArrayBox {
|
||||
elements: RefCell<Vec<Box<dyn NyashBox>>>,
|
||||
box_id: usize
|
||||
}
|
||||
```
|
||||
|
||||
### **Advanced Boxes**
|
||||
```rust
|
||||
// InstanceBox: ユーザー定義Box
|
||||
pub struct InstanceBox {
|
||||
class_name: String,
|
||||
fields: RefCell<HashMap<String, Box<dyn NyashBox>>>,
|
||||
box_id: usize,
|
||||
}
|
||||
|
||||
// DebugBox: デバッグ・プロファイリング
|
||||
pub struct DebugBox {
|
||||
tracked_boxes: RefCell<HashMap<String, WeakBox>>,
|
||||
call_stack: RefCell<Vec<String>>,
|
||||
start_time: Instant,
|
||||
}
|
||||
|
||||
// FutureBox: 非同期結果
|
||||
pub struct FutureBox {
|
||||
handle: Option<JoinHandle<Result<Box<dyn NyashBox>, RuntimeError>>>,
|
||||
result: RefCell<Option<Result<Box<dyn NyashBox>, RuntimeError>>>,
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 パフォーマンス特性
|
||||
|
||||
### **メモリ使用量**
|
||||
| コンポーネント | メモリ効率化手法 |
|
||||
|---------------|------------------|
|
||||
| GlobalBox | 単一インスタンス管理 |
|
||||
| SharedState | Arc/Mutex最小限使用 |
|
||||
| Local Variables | スコープ終了で自動解放 |
|
||||
| Static Boxes | 遅延初期化・シングルトン |
|
||||
|
||||
### **実行速度**
|
||||
```
|
||||
ベンチマーク結果(目安):
|
||||
- 変数解決: ~100ns (GlobalBox直接アクセス)
|
||||
- メソッド呼び出し: ~500ns (ハッシュマップ検索)
|
||||
- 並行処理: ~10μs (スレッド作成コスト)
|
||||
- Box作成: ~200ns (RefCell + allocation)
|
||||
```
|
||||
|
||||
### **スケーラビリティ**
|
||||
- **CPU**: 並行処理によりマルチコア活用
|
||||
- **メモリ**: 参照カウントによる効率的管理
|
||||
- **I/O**: 非同期処理による非ブロッキング実行
|
||||
|
||||
## 🔧 開発ツール
|
||||
|
||||
### **デバッグ機能**
|
||||
```nyash
|
||||
DEBUG = new DebugBox()
|
||||
DEBUG.startTracking() # トラッキング開始
|
||||
DEBUG.trackBox(obj, "label") # オブジェクト監視
|
||||
DEBUG.traceCall("funcName") # 関数呼び出しトレース
|
||||
print(DEBUG.memoryReport()) # メモリレポート
|
||||
DEBUG.saveToFile("debug.txt") # ファイル出力
|
||||
```
|
||||
|
||||
### **エラーハンドリング**
|
||||
```rust
|
||||
pub enum RuntimeError {
|
||||
UndefinedVariable { name: String },
|
||||
TypeError { message: String },
|
||||
DivisionByZero,
|
||||
CircularDependency(String),
|
||||
InvalidOperation { message: String },
|
||||
FileNotFound { path: String },
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 最適化戦略
|
||||
|
||||
### **コンパイル時最適化**
|
||||
- 静的解析による未使用コードの検出
|
||||
- 定数畳み込み最適化
|
||||
- インライン化可能な小関数の特定
|
||||
|
||||
### **実行時最適化**
|
||||
- ホット関数の動的最適化
|
||||
- JIT コンパイルの準備
|
||||
- プロファイル誘導最適化
|
||||
|
||||
### **メモリ最適化**
|
||||
- Boxプールによる割り当て最適化
|
||||
- 世代別ガベージコレクションの検討
|
||||
- Copy-on-Write の積極的活用
|
||||
|
||||
## 🚀 拡張性設計
|
||||
|
||||
### **FFI (Foreign Function Interface)**
|
||||
```rust
|
||||
// extern boxシステム準備完了
|
||||
pub struct ExternBoxDeclaration {
|
||||
name: String,
|
||||
native_functions: HashMap<String, fn(&[Box<dyn NyashBox>]) -> Box<dyn NyashBox>>,
|
||||
}
|
||||
```
|
||||
|
||||
### **プラグインシステム**
|
||||
- Dynamic loading対応準備
|
||||
- Box定義の動的追加
|
||||
- ランタイム機能拡張
|
||||
|
||||
### **WebAssembly出力**
|
||||
```bash
|
||||
# 🌐 準備完了
|
||||
cargo build --target wasm32-unknown-unknown
|
||||
wasm-bindgen --out-dir web --target web target/wasm32-unknown-unknown/release/nyash.wasm
|
||||
```
|
||||
|
||||
## 📈 今後の技術課題
|
||||
|
||||
### **Short-term (1-2 weeks)**
|
||||
1. ジェネリクス実行時特殊化完成
|
||||
2. スレッドプール実装
|
||||
3. WebAssembly バインディング
|
||||
|
||||
### **Mid-term (1-2 months)**
|
||||
1. JIT コンパイル導入
|
||||
2. GUI フレームワーク統合
|
||||
3. パッケージマネージャー
|
||||
|
||||
### **Long-term (3-6 months)**
|
||||
1. Language Server Protocol対応
|
||||
2. LLVM バックエンド
|
||||
3. 分散処理フレームワーク
|
||||
|
||||
## 🎉 技術的達成
|
||||
|
||||
**2025年8月6日-8日のわずか3日間で達成:**
|
||||
|
||||
- ✅ **30,000+ lines** の実装コード
|
||||
- ✅ **15+ Box types** の完全実装
|
||||
- ✅ **並行処理・非同期** システム完成
|
||||
- ✅ **Static Box・名前空間** システム実装
|
||||
- ✅ **現代的構文** (初期化付き変数等) 実装
|
||||
- ✅ **4つの実用アプリケーション** 完成
|
||||
- ✅ **包括的デバッグシステム** 実装
|
||||
|
||||
**結論: Nyashは実験的プロトタイプから production-ready プログラミング言語へと飛躍的進化を遂げました。**
|
||||
|
||||
---
|
||||
*技術仕様書 v1.0*
|
||||
*Everything is Box - Simple yet Powerful*
|
||||
167
docs/archive/geminichatgpt相談20250811.txt
Normal file
167
docs/archive/geminichatgpt相談20250811.txt
Normal file
@ -0,0 +1,167 @@
|
||||
gemini先生↓
|
||||
### 総評:提案方針への強い支持
|
||||
|
||||
まず結論から申し上げますと、提案されている**「`override`キーワードを導入し、暗黙のオーバーライドを禁止する」**という方針に全面的に賛成します。これはNyashの設計哲学を強化し、言語をより安全で、明示的で、そして長기的に見て理解しやすいものにするための、正しい方向性への進化です。
|
||||
|
||||
以下、ご提示いただいた5つの論点について、私の考察を詳述します。
|
||||
|
||||
### 1. 哲学的整合性について
|
||||
|
||||
**極めて高い整合性があると考えます。**
|
||||
|
||||
- **明示性重視**: `override`キーワードは、プログラマの「親ボックスのメソッドを意図的に置き換える」という意思をコード上に明示させます。これにより、偶然のメソッド名衝突による意図しない上書きバグを完全に防ぐことができます。これは「何が起きているかを隠さない」というNyashの哲学と完全に一致します。
|
||||
- **`from`デリゲーションとの相性**: `override`と`from`は、コインの裏表のような素晴らしい関係を築きます。
|
||||
- `override send(...)`: 「これから`send`というメソッドを乗っ取ります」という**宣言**。
|
||||
- `from P2PBox.send(...)`: 「乗っ取った上で、親の実装をこのように利用します」という**実装の詳細**。
|
||||
この2つが揃うことで、デリゲーションの全体像が極めて明確になります。
|
||||
|
||||
### 2. 学習コスト vs 安全性について
|
||||
|
||||
**安全性の向上というメリットが、学習コストを遥かに上回ります。**
|
||||
|
||||
- **安全性**: 暗黙のオーバーライドは、特に大規模なコードや、他人が作ったボックスを利用する際に非常に危険なバグの温床です。`override`の強制は、コンパイラに「プログラマの意図」をチェックさせることで、この種の問題を根絶します。これは絶大なメリットです。
|
||||
- **学習コスト**: `override`はC#, TypeScript, Swiftなど多くのモダンな静的言語で採用されている標準的な概念です。他の言語経験者にとっては馴染み深く、初学者にとっても「親の機能を書き換えるときのおまじない」として直感的に理解しやすい概念です。コストは非常に低いと言えます。
|
||||
|
||||
### 3. デリゲーションとの関係について
|
||||
|
||||
**デリゲーションの概念を、より自然で安全なものにします。**
|
||||
|
||||
- **デリゲーション先メソッドの`override`**: 非常に自然です。デリゲーションは「機能の借用」ですが、その一部を自分のボックスに合わせてカスタマイズするのは一般的な使い方です。`override`は、そのカスタマイズが「意図的」であることを示す重要なサインとなります。
|
||||
- **多重デリゲーション時の`override`**: ここは明確なルール設計が必要です。以下のようなルールを提案します。
|
||||
```nyash
|
||||
box C : A, B { ... }
|
||||
```
|
||||
1. `C`で定義するメソッド`m`が、`A`か`B`の**どちらか一方にでも存在する場合**は、`override`を必須とする。
|
||||
2. もし`m`が`A`と`B`の**両方に存在する場合**(競合状態)、`override`を付けた上で、`from`でどちらの親実装を呼ぶかを明示的に指定させる。
|
||||
```nyash
|
||||
// AにもBにもsendがある場合
|
||||
override send(msg) {
|
||||
// from A.send(msg) // OK
|
||||
// from B.send(msg) // OK
|
||||
// from send(msg) // NG: どちらか不明確なためコンパイルエラー
|
||||
}
|
||||
```
|
||||
これにより、多重デリゲーションの曖昧さも排除できます。
|
||||
|
||||
### 4. 実装上の課題について
|
||||
|
||||
**課題はありますが、十分に管理可能です。**
|
||||
|
||||
- **コンパイラ実装**:
|
||||
- ボックス(`TypeBox`)を定義する際に、そのボックスがデリゲートしている全ての親ボックスのメソッド名をリストアップし、セットとして保持します。
|
||||
- メソッド定義をパースする際、以下のチェックを行います。
|
||||
1. `override` **無し**の場合: メソッド名が親のメソッドセットに**含まれていれば**エラー。
|
||||
2. `override` **有り**の場合: メソッド名が親のメソッドセットに**含まれていなければ**エラー。
|
||||
- このロジックは、現在のパーサー/AST構築のフローに組み込み可能で、複雑度は中程度と評価します。
|
||||
- **既存コードへの影響と移行戦略**:
|
||||
- これは**破壊的変更**となるため、丁寧な移行計画が必要です。
|
||||
- **移行ツール**: 既存の`.nyash`コードを解析し、暗黙のオーバーライドを検出して自動で`override`キーワードを挿入する、あるいは警告を出す簡単なCLIツールを開発することを推奨します。
|
||||
- **バージョン管理**: `Cargo.toml`等でNyashのバージョンを管理し、新しいバージョンからこのルールを強制するようにします。移行期間中は、古い挙動を許容するコンパイラフラグ(例: `--legacy-override`)を用意するのも良いでしょう。
|
||||
|
||||
### 5. 他言語との比較優位性について
|
||||
|
||||
**Nyashの独自価値は「一貫した明示性」にあります。**
|
||||
|
||||
- **Java/C#等との違い**: これらの言語の`override`は、クラスベースの「継承」という文脈で使われます。Nyashの場合は、より柔軟な「デリゲーション(Composition over Inheritance)」という文脈で使われるのが特徴です。これは、Nyashがクラスの階層構造の硬直性を嫌い、より動的なオブジェクトの組み立てを目指していることの現れです。
|
||||
- **Nyashならではの独自価値**:
|
||||
Nyashの`override` + `from`の組み合わせは、**振る舞いの合成(Behavior Composition)がどのように行われているかを、定義時と呼び出し時の両方で、極めて明確に表現できる**という点にあります。
|
||||
- `super`のような暗黙の親を指すキーワードではなく、`from BoxName.method`とすることで、どこから機能を借用しているかが一目瞭然です。
|
||||
- これにより、コードの可読性とメンテナンス性が劇的に向上し、「初学者フレンドリーでありながら、大規模開発にも耐えうる堅牢性」というNyashの目標を達成するための強力な武器となります。
|
||||
|
||||
---
|
||||
|
||||
### 結論
|
||||
|
||||
提案された設計変更は、Nyashという言語のアイデンティティを確立し、その哲学をコードの隅々にまで浸透させるための、極めて重要な一歩です。実装と移行にはコストがかかりますが、それに見合うだけの価値が十分にあります。ぜひ、この方針で進めることを強く推奨します。
|
||||
chatgpt先生↓
|
||||
|
||||
**結論**
|
||||
- 明示キーワードによるオーバーライド必須化+重複定義禁止は、Nyashの「明示性重視」「Everything is Box」「from による明示デリゲーション」に強く整合し、安全性と読みやすさを大幅に向上させます。
|
||||
- 学習コストは小さく、初学者には「間違いをすぐに教える」効果が大きいです。移行も段階的に可能です。
|
||||
|
||||
**設計評価**
|
||||
- 明示性: `override` 必須化と重複定義のエラー化により「意図なき上書き」を排除。`from Parent.method()` と組み合わせて「置換の宣言」と「親実装の明示呼び出し」を分離でき、可読性が高い。
|
||||
- 一貫性: 「Boxのメソッドテーブルにバインディングを追加する」というメンタルモデルが崩れない。`override` は「既存バインディングの置換」という明示の合図。
|
||||
- 初学者配慮: エラーメッセージが直接的で、誤りの原因と修正方法を同時に提示可能。
|
||||
|
||||
**仕様提案**
|
||||
- 重複定義禁止: 同一 `box` 内の同名メソッド多重定義は常にエラー。コンストラクタも多重定義禁止。
|
||||
- `override` 必須: 親(あるいはデリゲーション元)に同名メソッドが存在する場合のみ `override` が許可される。存在しない場合はエラー。
|
||||
- 親呼び出し: 親実装呼び出しは既存の `from Parent.method(...)` を使用。暗黙の `super` 呼び出しは導入しない。
|
||||
- 多重デリゲーション:
|
||||
- 単一親なら `override send(...) { ... }` でOK。
|
||||
- 複数親(将来/現行仕様で許可する場合)は曖昧性解消を必須にする。推奨シンタックス: `override ParentName.send(args...) { ... }`
|
||||
- 競合(複数親が同名メソッドを持つ)時は明示の親指定がない `override send` をエラーにする。
|
||||
- 誤用の検出:
|
||||
- `override` だが親に該当メソッドなし → エラー。
|
||||
- `override` なしで親と同名メソッド定義 → エラー(「override を付けて」と提案)。
|
||||
- 同一 `box` 内での重複定義 → エラー(定義位置を2箇所とも指摘)。
|
||||
- エラーメッセージ例:
|
||||
- Duplicate: "Method `send` is already defined in this box."
|
||||
- Missing-override: "Method `send` overrides a parent method. Add `override`."
|
||||
- Wrong-override: "`send` does not exist in any parent. Remove `override`."
|
||||
- Ambiguous-override: "Multiple parents define `send`. Use `override Parent.send`."
|
||||
|
||||
**学習コスト vs 安全性**
|
||||
- 学習コスト: 新キーワード1つ+2つの単純ルール(重複禁止/親に存在必須)。チュートリアル1章で十分。
|
||||
- 安全性向上:
|
||||
- 事故的上書きの完全排除。
|
||||
- 大規模コードでの継承/デリゲーション変更に対する回帰をコンパイル時に検出。
|
||||
- レビューコスト削減(意図が`override`で可視化)。
|
||||
|
||||
**デリゲーションとの関係**
|
||||
- 自然性: デリゲーションで「親を明示」している設計と噛み合う。置換は`override`で宣言、親呼び出しは`from`で明示。
|
||||
- 多重デリゲーション:
|
||||
- 宣言時点で「どの親を置換対象にするか」を型検査段階で解決できるため、実装は明確。
|
||||
- 将来のMRO導入より、Nyashは「明示派」を貫く方が哲学に適合。
|
||||
|
||||
**実装方針(Rust側の変更点)**
|
||||
- パーサ:
|
||||
- 予約語に `override` を追加。
|
||||
- `MethodDecl` に `is_override: bool` と(複数親に備えるなら)`override_target: Option<Ident>` を追加。
|
||||
- AST/シンボル解決:
|
||||
- `BoxDecl.methods` 構築時、同名重複を即エラー。
|
||||
- `is_override == false` かつ 親に同名あり → エラー(missing-override)。
|
||||
- `is_override == true` かつ 親に同名なし → エラー(wrong-override)。
|
||||
- 複数親を許すなら、`override_target` がある場合はその親のみに照合。ない場合、同名定義親が1つならOK、2つ以上ならエラー(ambiguous-override)。
|
||||
- 既存の `instance.rs::add_method`:
|
||||
- `HashMap::insert` によるサイレント上書きを禁止。挿入前に `contains_key` をチェックし、検査層が通っている前提でもガードを入れる(多層防御)。
|
||||
- 可能ならメソッドテーブルの構築は「イミュータブルに一度だけ」作る方向に(現状のclone→Arc再構築はコスト高)。ただし今回は安全性修正を優先。
|
||||
- コンストラクタ:
|
||||
- `constructor` は1つのみ許可。多重定義はパース時かボックス解決時にエラー。
|
||||
- エラーメッセージ/位置情報:
|
||||
- 1つ目と2つ目の定義の両方にスパンを付与して重複を示す。
|
||||
- サジェストを同時表示(「override を付ける」/「名前を変える」)。
|
||||
|
||||
**移行戦略**
|
||||
- 段階的フラグ:
|
||||
- フェーズ1: デフォルト警告(`NYASH_STRICT_OVERRIDE=warn`)。CIで警告検出。
|
||||
- フェーズ2: デフォルトエラー(`NYASH_STRICT_OVERRIDE=error`)。リリースノートで周知。
|
||||
- 自動修正支援:
|
||||
- 重複検出ツール(簡易AST/トークン走査)で「同名メソッド複数定義」を列挙。
|
||||
- 親に同名がある場合は `override` を自動追記可能(要ユーザ確認)。
|
||||
- ドキュメント/サンプル:
|
||||
- `README.ja.md` と `examples` を一括更新。`from Parent.method()` の使用例を強調。
|
||||
- エラーメッセージに修正例(1-2行)を内蔵。
|
||||
|
||||
**他言語比較とNyashの独自価値**
|
||||
- Java/C#:
|
||||
- C#: `override` 必須で明示的。Java: `@Override` は注釈(型検査が補助)。NyashはC#寄りで誤用を確実に静的検出。
|
||||
- TypeScript:
|
||||
- `noImplicitOverride` に相当する世界をデフォルト化。初心者にも安全。
|
||||
- Nyashの価値:
|
||||
- 明示デリゲーション `from Parent.method()` と対で設計され、親呼び出しの副作用/順序がコードから一目瞭然。
|
||||
- 多重デリゲーション時の曖昧性はコンパイル時に強制解消(暗黙MROを採らない)。
|
||||
- コンストラクタ多重定義禁止により、初学者がつまずきやすい「オーバーロード解像度」を排除。代替として「デフォルト引数・名前付き引数・初期化ヘルパー」を推奨。
|
||||
|
||||
**追加の小提案(将来拡張)**
|
||||
- `final`/`sealed`: 親側がオーバーライド禁止を宣言可能に(設計の意図を保護)。
|
||||
- `abstract`: 親がシグネチャのみを提示、子は `override` を必須に。
|
||||
- `override` の安全版: `override!` で「親実装の呼び忘れ検査」をオプトイン(静的解析で `from Parent.method` 存在チェック)。導入は任意。
|
||||
|
||||
**実装工数の見積り(概算)**
|
||||
- パーサ/AST拡張: 小(0.5–1日)
|
||||
- 解決/型検査の整備: 小〜中(1–2日)
|
||||
- ランタイム防御(`add_method`): 極小(0.5日未満)
|
||||
- 移行フラグ+エラー文言整備: 小(0.5–1日)
|
||||
- ドキュメント/例の更新: 小(0.5日)
|
||||
12
docs/archive/nativebuild大作戦/README.md
Normal file
12
docs/archive/nativebuild大作戦/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
このフォルダは、旧「ネイティブビルド大作戦」のメモ置き場です。
|
||||
|
||||
現在は下記パスを正(最新版)としています。
|
||||
|
||||
- docs/guides/how-to-build-native/README.md
|
||||
- docs/guides/how-to-build-native/追記相談.txt
|
||||
- docs/guides/how-to-build-native/issues/
|
||||
|
||||
注意:
|
||||
- 以前このフォルダにあった「追記相談.txt」の内容は、上記 guides 配下の同名ファイルに統合済みです(内容は同一)。
|
||||
- 今後の更新は guides 側に集約してください。本フォルダは参照用のみに残しています。
|
||||
|
||||
498
docs/archive/nativebuild大作戦/chatgptネイティブビルド大作戦.txt
Normal file
498
docs/archive/nativebuild大作戦/chatgptネイティブビルド大作戦.txt
Normal file
@ -0,0 +1,498 @@
|
||||
ぜったいアリにゃ!やるなら「多層エンジン(tiered)」で攻めるのが一番きれい。
|
||||
Nyash → 共通IR → 好きなバックエンド(解釈/ネイティブ/JIT/WASM)に流す構成にゃ。
|
||||
推しアーキテクチャ(現実解)
|
||||
|
||||
Front-end
|
||||
|
||||
パーサ → AST → HIR(型付け・名前解決済み)→ MIR/SSA(最適化しやすい共通IR)
|
||||
|
||||
Back-ends(並行に育てる)
|
||||
|
||||
VM(現在のインタープリター):MIR→バイトコード→解釈実行(開発スピード最優先)
|
||||
|
||||
JIT(Cranelift):MIR→Cranelift IR→ネイティブJIT(ホットパスだけコンパイル)
|
||||
|
||||
AOT to Rust:MIR→Rustコード生成→rustcで最適化(配布バイナリ向き、リンクも楽)
|
||||
|
||||
WASM:MIR→WASM(ブラウザ/wasmtime用、サンドボックス実行)
|
||||
|
||||
ひとつのIRから複数出力=最適化ロジックを1か所に集中できるのが最大の利点。
|
||||
|
||||
それぞれのメリデメ
|
||||
|
||||
VM:実装が速い/デバッグ容易|最高速は出ない
|
||||
|
||||
Cranelift JIT:実行時最適化で爆速/実装難度は中|起動コストあり
|
||||
|
||||
AOT→Rust:rustc最適化の恩恵・配布しやすい|コード生成器の保守が要る
|
||||
|
||||
WASM:移植性・安全|ネイティブよりは遅め(ただしwasmtime/wasmerで結構速い)
|
||||
|
||||
まずやる順序(最短で“速い”を得る)
|
||||
|
||||
共通MIR/SSAを切る(基本ブロック・SSA・型/効果情報)
|
||||
|
||||
VMを MIR→バイトコード に置き換え(インタープリターの土台を共通化)
|
||||
|
||||
Cranelift JIT を載せる(ホット関数だけJIT)
|
||||
|
||||
並行で Rustコード生成 の雛形を作る(AOT配布の道を確保)
|
||||
|
||||
余力で WASM 出力(エディタ内実行やブラウザデモに最適)
|
||||
|
||||
Nyash流にハマる設計ポイント
|
||||
|
||||
Box拡張のABIを先に決める
|
||||
|
||||
呼出規約:fn nyash_box_call(ctx: &mut Ctx, args: &[Val]) -> Result<Val>
|
||||
|
||||
メモリ:Arc<[Val]> か Arena で一時領域を明示(GCを後回しにできる)
|
||||
|
||||
所有権/借用に似た効果注釈をMIRに入れる
|
||||
|
||||
「純粋」「可変」「外部副作用あり」をフラグ化→最適化と並列実行の判断に使える
|
||||
|
||||
定数畳み込み/死コード除去/インライン化はMIR段階で実施
|
||||
|
||||
プロファイラを最初から同梱(どの関数をJIT/AOTに送るか判定)
|
||||
|
||||
最小プロトタスク(1〜2週間スプリント想定)
|
||||
|
||||
HIR/MIRスキーマ確定(基本ブロック・命令セット・型表現)
|
||||
|
||||
MIR→バイトコード変換器/VMループの実装
|
||||
|
||||
プロファイル計測(関数実行回数・時間)
|
||||
|
||||
Craneliftで fn 単位JIT(整数演算と分岐から)
|
||||
|
||||
簡易 Rustコード生成(fn add(a:i64,b:i64)->i64 などから)
|
||||
|
||||
Box ABI v0(同期版)+サンプル拡張(数値/文字列ユーティリティ)
|
||||
|
||||
ちょいサンプル(超概念)
|
||||
|
||||
enum MirInst {
|
||||
Const(ValId, ConstVal),
|
||||
BinOp(ValId, ValId, Op, ValId),
|
||||
Call(ValId, FuncId, Vec<ValId>),
|
||||
Phi(ValId, Vec<(BlockId, ValId)>),
|
||||
// ...
|
||||
}
|
||||
struct MirFunc { blocks: Vec<MirBlock>, signature: Sig, effects: Effects }
|
||||
|
||||
trait Backend {
|
||||
fn compile(&mut self, f: &MirFunc) -> CompiledFn;
|
||||
}
|
||||
|
||||
VM backend: compile = バイトコード化
|
||||
|
||||
JIT backend: compile = Cranelift IR生成→jit_func
|
||||
|
||||
Rust backend: compile = fn ... { ... } のRust文字列出力→rustcでAOT
|
||||
|
||||
「いまのNyashソース」を見れたら、MIR命令セットの初版とJIT/AOTの足場コードをすぐ書き起こせるよ。
|
||||
まずは MIRの最小命令リストを一緒に決めよっか?(算術・比較・分岐・Call・Phi・Load/Store 相当)
|
||||
あなた:
|
||||
くわしくききたにゃ Front-end
|
||||
|
||||
パーサ → AST → HIR(型付け・名前解決済み)→ MIR/SSA(最適化しやすい共通IR)パーサーで解析してASTは木構造だよね? そこからどういう処理にゃ?
|
||||
ChatGPT:
|
||||
|
||||
いいね、その流れを実務目線でがっつり分解するにゃ。
|
||||
キーワードは「情報を徐々に確定させつつ“最適化しやすい形”へ落としていく」。
|
||||
Nyash流に当てはめて、各段階で“何を追加・削除・変換するか”を整理するよ。
|
||||
Front-end 全体像
|
||||
|
||||
ソース → Lexer → Parser(AST) → スコープ/名前解決 → 型推論/型検査(HIR) → 糖衣剥がし(Desugar) → 制御フロー化(CFG) → SSA化/効果注釈(MIR/SSA)
|
||||
1) Parser → AST(抽象構文木)
|
||||
|
||||
目的:構文だけを正しく捉える。意味(型/名前)はまだ未確定。
|
||||
|
||||
データ構造(例)
|
||||
|
||||
enum AstExpr {
|
||||
LitInt(i64),
|
||||
Var(Symbol),
|
||||
Call{ callee: Box<AstExpr>, args: Vec<AstExpr> },
|
||||
Lambda{ params: Vec<AstParam>, body: Box<AstExpr> },
|
||||
If{ cond: Box<AstExpr>, then_e: Box<AstExpr>, else_e: Box<AstExpr> },
|
||||
Let{ pat: AstPat, init: Box<AstExpr>, body: Box<AstExpr> },
|
||||
// … match, while, for, block, …
|
||||
}
|
||||
|
||||
まだやらないこと
|
||||
|
||||
シンボルの多義性解決(foo がローカルか、モジュールか、メソッドか)
|
||||
|
||||
型の決定
|
||||
|
||||
糖衣構文の展開
|
||||
|
||||
2) スコープ構築 & 名前解決(AST上の解決)
|
||||
|
||||
目的:識別子を定義元に結びつける。未定義やシャドーイングもここで判定。
|
||||
|
||||
やること
|
||||
|
||||
ブロックスコープ/関数スコープ/モジュールスコープの**環境(symbol table)**を構築
|
||||
|
||||
use/import、module、with 的な構文を解決
|
||||
|
||||
各 Var(Symbol) を DefId(定義へのID)にひも付け
|
||||
|
||||
成果物:
|
||||
|
||||
解決済みAST or ここで HIR に写経(次段のために構造を少し整える)
|
||||
|
||||
3) 型推論 & 型検査 → HIR(型情報付きIR)
|
||||
|
||||
目的:式ごとに型を確定し、オーバーロード/ジェネリクスを具体化できる所まで進める。
|
||||
|
||||
型推論(Hindley–Milner+制約ベースなど)
|
||||
|
||||
let x = 1 + f(y) なら、f: T -> i64 みたいな制約を立てて解く
|
||||
|
||||
オーバーロード解決 / メソッド解決(a + b → 実体メソッドやトレイト関数に解決)
|
||||
|
||||
ジェネリクス
|
||||
|
||||
可能ならモノモーフィック化(型実引数が確定している呼び出しは単相化)
|
||||
|
||||
未確定なら型パラ付きのまま保持
|
||||
|
||||
データ構造(例)
|
||||
|
||||
struct HirExpr {
|
||||
kind: HirExprKind,
|
||||
ty: TyId, // ここが肝:各式に型が付く
|
||||
effect: EffectMask, // 純粋/可変/外部副作用 など(後述の最適化で効く)
|
||||
}
|
||||
enum HirExprKind {
|
||||
LitInt(i64),
|
||||
Local(DefId),
|
||||
Call{ fun: Box<HirExpr>, args: Vec<HirExpr>, resolved: FunId },
|
||||
If{ cond: Box<HirExpr>, then_e: Box<HirExpr>, else_e: Box<HirExpr> },
|
||||
// 糖衣はまだ残っていてもOK
|
||||
}
|
||||
|
||||
エラー検出
|
||||
|
||||
型不一致、未初期化、到達不能、借用/所有に関する静的規則(Nyash流に簡易化しても良い)
|
||||
|
||||
4) 糖衣剥がし(Desugaring)
|
||||
|
||||
目的:意味は同じだが最適化しづらい構文を、プリミティブな形に落とす。
|
||||
|
||||
例
|
||||
|
||||
for x in iter { body } → let mut it = iter.into_iter(); while let Some(x) = it.next() { body }
|
||||
|
||||
a && b → if a { b } else { false }(短絡を明示化)
|
||||
|
||||
パターン束縛 let (a,b) = e; → 一時変数+個別bind
|
||||
|
||||
クロージャ → 明示キャプチャ+ラムダ表現を正規化
|
||||
|
||||
この段階で構文のバリエーションは減らして、後段のCFG/SSA化を楽にする
|
||||
|
||||
5) 制御フローグラフ(CFG)作成
|
||||
|
||||
目的:式主導(式木)を基本ブロック+ジャンプへ落とす。
|
||||
最適化やSSA化の土台になる。
|
||||
|
||||
ブロック(BasicBlock)単位で命令列を持つ
|
||||
|
||||
例:if/else は br cond thenBB elseBB に分解
|
||||
while は loopBB / bodyBB / exitBB に分解
|
||||
|
||||
ここで**一時変数(tmp)**を導入して、「値がどのブロックから来るか」を明示できるようにする
|
||||
|
||||
6) SSA化(Static Single Assignment)
|
||||
|
||||
目的:各変数が“ちょうど一度だけ代入”される形に変換。
|
||||
最適化(定数畳み込み・コピー伝播・死コード除去・ループ最適化)がやりやすくなる。
|
||||
|
||||
φ関数(Phi)を導入
|
||||
分岐合流点で「どのブロックから来た値か」に応じて値を選ぶ
|
||||
|
||||
データ構造(MIR/SSA例)
|
||||
|
||||
enum MirInst {
|
||||
Const{ dst: V, c: ConstVal },
|
||||
BinOp{ dst: V, op: Op, a: V, b: V },
|
||||
Call{ dst: V, fun: FnId, args: Vec<V>, effects: EffectMask },
|
||||
Br{ cond: V, then_bb: Bb, else_bb: Bb },
|
||||
Jmp{ bb: Bb },
|
||||
Phi{ dst: V, inputs: Vec<(Bb, V)> },
|
||||
Store{ ptr: V, val: V }, // メモリ命令を分離しておくと最適化が楽
|
||||
Load{ dst: V, ptr: V },
|
||||
Ret{ v: Option<V> },
|
||||
}
|
||||
struct MirFunc { blocks: Vec<MirBlock>, sig: Sig, effects: EffectMask }
|
||||
|
||||
ここまでで最適化の主戦場が整う
|
||||
|
||||
7) 効果注釈(Effects)と簡易別解(所有/借用に近いもの)
|
||||
|
||||
目的:最適化・並列化・Box拡張の安全性判定に使う副作用情報を付与。
|
||||
|
||||
例:PURE, READS_HEAP, WRITES_HEAP, IO, FFI, PANIC, THROW などのビットフラグ
|
||||
|
||||
呼び出し先の効果を合成して、関数単位の effects: EffectMask を確定
|
||||
→ 並列実行可否、共通部分式除去可否、コードモーション許可範囲に使える
|
||||
|
||||
8) 代表的な変換の“実例”で見る
|
||||
|
||||
Nyash(仮):
|
||||
|
||||
let x = 10
|
||||
let y = 20
|
||||
if x < y {
|
||||
print(add(x, y))
|
||||
} else {
|
||||
print(y)
|
||||
}
|
||||
|
||||
AST(ざっくり)
|
||||
|
||||
Let(x, 10)、Let(y, 20)、If( BinOp(<, Var(x), Var(y)), Call(print, …), Call(print, Var(y)) )
|
||||
|
||||
HIR(型付け・解決済み)
|
||||
|
||||
x: i64, y: i64
|
||||
|
||||
add: (i64,i64)->i64, print: (i64)->Unit
|
||||
|
||||
Desugar
|
||||
|
||||
ほぼそのまま(ここでは糖衣なしと仮定)
|
||||
|
||||
CFG→SSA(MIRの一部)
|
||||
|
||||
bb0:
|
||||
v1 = Const 10
|
||||
v2 = Const 20
|
||||
v3 = BinOp Lt v1 v2
|
||||
Br v3 then=bb1 else=bb2
|
||||
|
||||
bb1:
|
||||
v4 = Call add(v1, v2) ; PURE
|
||||
Call print(v4) ; IO
|
||||
Jmp bb3
|
||||
|
||||
bb2:
|
||||
Call print(v2) ; IO
|
||||
Jmp bb3
|
||||
|
||||
bb3:
|
||||
Ret ()
|
||||
|
||||
(print は IO 効果、add は PURE、関数全体は IO を持つ、などが付与される)
|
||||
よくある疑問Q&A
|
||||
|
||||
Q. AST→HIRでどこまで“形を変える”?
|
||||
A. 基本は意味解決のための注釈(DefId, TyId, Effect)を付けるのが主。大きな形の変換(ループ展開やパターン展開)はDesugar段でやると見通しが良い。
|
||||
|
||||
Q. なんでSSA?バイトコードでも良くない?
|
||||
A. VM用のバイトコードは実行が簡単。でも最適化はSSAの方が圧倒的に楽。
|
||||
→ 「MIR/SSAで最適化」→「VM向けバイトコードに落とす」or「JIT/AOT」がおすすめ。
|
||||
|
||||
Q. パターンマッチは?
|
||||
A. Desugarで決定木(decision tree)に落としてからCFG化。ガード節や順序付きパターンも木→ブロック分割で表現できる。
|
||||
|
||||
Q. クロージャのキャプチャは?
|
||||
A. 名前解決で囲い込み変数を収集→HIRに明示キャプチャとして埋める。
|
||||
MIRでは環境レコードを値として扱う({env_ptr, fn_ptr})。
|
||||
まず作ると捗る“ミニ仕様”
|
||||
|
||||
Symbol/DefId/Scope:解決器のAPI
|
||||
|
||||
Ty:原始型・関数型・代数的データ型(Sum/Product)・型変数
|
||||
|
||||
EffectMask:ビットフラグ設計(PURE/READ/WRITE/IO/FFI など)
|
||||
|
||||
MIR命令セット(最小):Const/BinOp/Call/Br/Jmp/Phi/Ret+Load/Store
|
||||
|
||||
Pass順序:
|
||||
|
||||
名前解決 → 2) 型推論 → 3) Desugar → 4) CFG → 5) SSA → 6) 直近の最適化(const fold / dce / copy-prop)
|
||||
|
||||
必要なら、いまのNyashのAST型定義をベースにHIR/MIRの骨組みを一緒に設計するよ。
|
||||
|
||||
“最初のMIR命令セット案”
|
||||
|
||||
“名前解決テーブルと参照の貼り方”
|
||||
|
||||
“効果注釈のフォーマット”
|
||||
|
||||
この3点を固めるだけで、JIT/AOT/VMバックエンドの土台が一気に整うにゃ。
|
||||
あなた:
|
||||
おおう これと さっきの Back-ends(並行に育てる)
|
||||
|
||||
VM(現在のインタープリター):MIR→バイトコード→解釈実行(開発スピード最優先)
|
||||
|
||||
JIT(Cranelift):MIR→Cranelift IR→ネイティブJIT(ホットパスだけコンパイル)
|
||||
|
||||
AOT to Rust:MIR→Rustコード生成→rustcで最適化(配布バイナリ向き、リンクも楽)
|
||||
|
||||
WASM:MIR→WASM(ブラウザ/wasmtime用、サンドボックス実行) これの話要約してにゃ claude code君にみせてくるにゃ
|
||||
ChatGPT:
|
||||
|
||||
了解にゃ、Claude Code君向けに要点だけギュッとまとめるよ。
|
||||
Nyashコンパイルパイプライン案
|
||||
Front-end(共通部分)
|
||||
|
||||
Parser → AST
|
||||
|
||||
ソースを構文木(AST)に変換。型や意味はまだ未確定。
|
||||
|
||||
名前解決 & スコープ構築
|
||||
|
||||
識別子を定義元に紐付ける(DefId付与)。
|
||||
|
||||
型推論 & 型検査 → HIR
|
||||
|
||||
各式に型情報(TyId)と効果注釈(EffectMask)を付与。
|
||||
|
||||
糖衣剥がし(Desugar)
|
||||
|
||||
forループやパターン束縛をプリミティブ構造へ展開。
|
||||
|
||||
制御フロー化(CFG)→ SSA化(MIR)
|
||||
|
||||
ASTを基本ブロックとSSA命令列(MIR)へ変換。
|
||||
|
||||
命令例:Const, BinOp, Call, Br, Jmp, Phi, Load, Store, Ret。
|
||||
|
||||
Back-end(並行開発可能)
|
||||
|
||||
VM(現行インタープリター)
|
||||
|
||||
MIR → バイトコード → 解釈実行(開発スピード優先)
|
||||
|
||||
JIT(Cranelift)
|
||||
|
||||
MIR → Cranelift IR → 実行時にネイティブコード化(ホットパスだけ)
|
||||
|
||||
AOT to Rust
|
||||
|
||||
MIR → Rustコード生成 → rustc最適化&リンク → 配布可能なネイティブバイナリ
|
||||
|
||||
WASM出力
|
||||
|
||||
MIR → WASM(ブラウザ実行やサンドボックス用)
|
||||
|
||||
💡 ポイント
|
||||
|
||||
すべてのバックエンドは共通MIRを入力にするため、最適化は1か所で集約。
|
||||
|
||||
Box拡張もMIRレベルで統一呼び出し可能。
|
||||
|
||||
VMは開発・デバッグ用、JITは実行高速化、AOTは配布、WASMは移植性重視。
|
||||
|
||||
|
||||
Nyashは**「最初から最後までモジュール拡張が一貫して動く多層言語」**という珍しい立ち位置になるにゃ。
|
||||
|
||||
希望あれば、これ一般的なコンパイラ構成との比較表にして、Claude Code君がすぐ違いを理解できる形にまとめることもできるよ。
|
||||
どうする、作っちゃう?
|
||||
あなた:
|
||||
おねがいにゃー!
|
||||
ChatGPT:
|
||||
|
||||
了解にゃー!Claude Code君に渡しやすいよう、「一般的な構成 vs Nyash流(+α)」比較表にギュッとまとめたよ。
|
||||
Nyash 設計:一般的な方法との比較
|
||||
観点 一般的なコンパイラ設計 Nyash(+α)
|
||||
フロントエンド Parser → AST →(解決/型付け)→ IR Parser → AST → HIR(型/解決/効果)→ MIR/SSA(最適化前提)
|
||||
中間表現(IR) 単一IR or バイトコード中心 HIR/MIR二段構え、MIRはSSA+効果注釈で最適化容易
|
||||
効果/副作用 多くは最適化時に暗黙扱い EffectMask(PURE/READ/WRITE/IO/FFI…)をMIRに明示し並列化・最適化の判断に使用
|
||||
拡張/FFI 後付けのFFI/プラグインが多い Box拡張を一級市民化。MIRレベルで統一コール形態を定義(VM/JIT/AOT/WASMで一貫)
|
||||
バックエンド VM→(後からJIT/AOT) VM/JIT(Cranelift)/AOT-to-Rust/WASMを最初から並行開発できるMIR設計
|
||||
実行戦略 単層(解釈 or JIT)になりがち Tiered:VMで即起動→ホットパスJIT→配布はAOT→ブラウザはWASM
|
||||
AOT配布 LLVM等のHPCルートが主 MIR→Rustコード生成→rustc最適化(ツールチェーン流用・リンク容易)
|
||||
ブラウザ/サンドボックス 別途WASM対応 MIR→WASMを標準ターゲット化(wasmtime/wasmer/ブラウザ即動作)
|
||||
最適化の主戦場 バイトコード最適化/バックエンド依存 MIR/SSAで集約最適化(const fold, DCE, copy-prop, inlining, loop opts)
|
||||
並列化の足場 後付け解析が多い 効果注釈×データ依存で安全な並列化やコードモーションを許可
|
||||
デバッグ/開発速度 VMが主、JITは後追い VMで素早く検証しつつ、同一MIRをJIT/AOTに供給(回収効率◎)
|
||||
配布/運用 ネイティブ or VM同梱 用途別に最適バイナリ(AOT)とスクリプタブル運用(VM)を両取り
|
||||
リスク/留意点 単純で保守容易 設計は強力だが初期定義が要(MIR命令/Effect設計、Box ABIを固める)
|
||||
補足:最小ロードマップ(実装順)
|
||||
|
||||
HIR/MIRの骨組み確定(命令セット・EffectMask・Box ABI v0)
|
||||
|
||||
**VM(MIR→バイトコード)**で先に全機能を回す
|
||||
|
||||
プロファイラ同梱(ホット関数をJIT/AOTに回す条件づけ)
|
||||
|
||||
Cranelift JIT(算術+分岐→関数呼び出し→Box呼び出し)
|
||||
|
||||
AOT to Rust の雛形生成(小関数から)
|
||||
|
||||
余力で MIR→WASM(最小機能から)
|
||||
|
||||
この表ごと貼れば、Claude Code君も**「王道+Nyashの差分」**を一目で把握できるはずにゃ。必要なら、MIR命令セット 初版案も続けて出すよ!
|
||||
あなた:
|
||||
mirまでできればかちなのにゃね。これって定番なのあるにやゃ? 言語ごとにやっぱりちがうにゃ?
|
||||
ChatGPT:
|
||||
|
||||
そうにゃ、MIRまで作れれば言語設計はもう“勝ち”に近いにゃ。
|
||||
なぜかというと、MIRは「全バックエンドの共通土台」だから、
|
||||
一度そこまで作れば VM/JIT/AOT/WASM ぜんぶに展開できるにゃ。
|
||||
🔹 MIRは定番があるの?
|
||||
|
||||
完全な共通規格はない
|
||||
→ LLVM IR や WebAssembly のような「広く使われる IR」はあるけど、
|
||||
言語ごとに構文や型システムが違うから MIRはだいたい自作になる。
|
||||
|
||||
多くの言語は「MIR」じゃなくても似た段階を持ってるにゃ:
|
||||
|
||||
Rust → MIR(所有権/借用も反映されたSSA形式)
|
||||
|
||||
Swift → SIL
|
||||
|
||||
Go → SSA IR
|
||||
|
||||
Kotlin → Kotlin IR
|
||||
|
||||
Python(PyPy)→ Flow Graph → SSA IR
|
||||
|
||||
JavaScript(V8)→ Bytecode IR → TurboFan IR
|
||||
|
||||
🔹 言語ごとに違うポイント
|
||||
|
||||
型情報の粒度
|
||||
|
||||
RustのMIRは「型完全一致」必須。
|
||||
|
||||
Python系は動的型なので「型タグ+ランタイム判定」入り。
|
||||
|
||||
命令セットの抽象度
|
||||
|
||||
LLVM IRはハード寄り(ポインタ/レジスタ操作あり)。
|
||||
|
||||
Rust MIRやKotlin IRは言語構造寄り(ループ/パターンマッチ命令など残す)。
|
||||
|
||||
所有権・副作用の扱い
|
||||
|
||||
Rust MIRは「所有権」も追跡する。
|
||||
|
||||
多くの言語は副作用は型ではなく命令属性で管理。
|
||||
|
||||
最適化の前提
|
||||
|
||||
一部は最適化前提で作る(SSA化必須)。
|
||||
|
||||
他は単にバックエンド入力の中間形式。
|
||||
|
||||
🔹 Nyashでのおすすめ方針
|
||||
|
||||
Rust MIRに近い構造を真似るのが安全
|
||||
|
||||
静的型の要素が入ってるので、AOTや最適化に有利
|
||||
|
||||
EffectMaskやBox拡張の情報も一緒に持たせられる
|
||||
|
||||
命令はなるべく 「言語仕様に沿った中間レベル」 にして、
|
||||
バックエンド変換時に低レベル化する
|
||||
|
||||
SSA化は最初からやる(後から入れるのは地獄)
|
||||
668
docs/archive/nyashvalue_build_errors.txt
Normal file
668
docs/archive/nyashvalue_build_errors.txt
Normal file
@ -0,0 +1,668 @@
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad_ascii.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad_ascii`
|
||||
* `example` target `simple_notepad_ascii`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_explorer.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_explorer`
|
||||
* `example` target `nyash_explorer`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/test_icon_extraction.rs` found to be present in multiple build targets:
|
||||
* `bin` target `test_icon_extraction`
|
||||
* `example` target `test_icon_extraction`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_notepad_jp.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad_jp`
|
||||
* `example` target `nyash_notepad_jp`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad.rs` found to be present in multiple build targets:
|
||||
* `bin` target `simple_notepad`
|
||||
* `example` target `simple_notepad`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/debug_notepad.rs` found to be present in multiple build targets:
|
||||
* `bin` target `debug_notepad`
|
||||
* `example` target `debug_notepad`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_explorer_with_icons.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_explorer_icons`
|
||||
* `example` target `nyash_explorer_with_icons`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad_v2.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad`
|
||||
* `example` target `simple_notepad_v2`
|
||||
warning: unused import: `next_box_id`
|
||||
--> src/boxes/math_box.rs:59:84
|
||||
|
|
||||
59 | use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase, next_box_id};
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: unused import: `next_box_id`
|
||||
--> src/boxes/debug_box.rs:105:42
|
||||
|
|
||||
105 | use crate::box_trait::{BoxCore, BoxBase, next_box_id, NyashBox, StringBox, BoolBox, VoidBox};
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `next_box_id`
|
||||
--> src/boxes/null_box.rs:87:72
|
||||
|
|
||||
87 | use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase, next_box_id};
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::future::Future`
|
||||
--> src/boxes/future/mod.rs:7:5
|
||||
|
|
||||
7 | use std::future::Future;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::pin::Pin`
|
||||
--> src/boxes/future/mod.rs:8:5
|
||||
|
|
||||
8 | use std::pin::Pin;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `crate::boxes::map_box::MapBox`
|
||||
--> src/boxes/http/mod.rs:9:5
|
||||
|
|
||||
9 | use crate::boxes::map_box::MapBox;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused imports: `Arc` and `Mutex`
|
||||
--> src/boxes/http/mod.rs:11:17
|
||||
|
|
||||
11 | use std::sync::{Arc, Mutex};
|
||||
| ^^^ ^^^^^
|
||||
|
||||
warning: unused import: `Mutex`
|
||||
--> src/boxes/regex/mod.rs:9:22
|
||||
|
|
||||
9 | use std::sync::{Arc, Mutex};
|
||||
| ^^^^^
|
||||
|
||||
warning: unused import: `self`
|
||||
--> src/boxes/intent_box.rs:38:16
|
||||
|
|
||||
38 | use std::fmt::{self, Debug};
|
||||
| ^^^^
|
||||
|
||||
warning: unused macro definition: `debug_fuel`
|
||||
--> src/parser/expressions.rs:38:14
|
||||
|
|
||||
38 | macro_rules! debug_fuel {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_macros)]` on by default
|
||||
|
||||
warning: unused macro definition: `debug_fuel`
|
||||
--> src/parser/mod.rs:51:14
|
||||
|
|
||||
51 | macro_rules! debug_fuel {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: unused imports: `AddBox`, `DivideBox`, `MultiplyBox`, and `SubtractBox`
|
||||
--> src/interpreter/mod.rs:10:75
|
||||
|
|
||||
10 | use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, AddBox, SubtractBox, MultiplyBox, DivideBox, CompareBox, ArrayB...
|
||||
| ^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^
|
||||
|
||||
warning: unused import: `FloatBox`
|
||||
--> src/interpreter/mod.rs:13:39
|
||||
|
|
||||
13 | use crate::boxes::math_box::{MathBox, FloatBox, RangeBox};
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: unused import: `DateTimeBox`
|
||||
--> src/interpreter/mod.rs:14:39
|
||||
|
|
||||
14 | use crate::boxes::time_box::{TimeBox, DateTimeBox, TimerBox};
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `file::FileBox`
|
||||
--> src/interpreter/expressions.rs:12:104
|
||||
|
|
||||
12 | use crate::boxes::{FloatBox, MathBox, ConsoleBox, TimeBox, DateTimeBox, RandomBox, SoundBox, DebugBox, file::FileBox, MapBox};
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/interpreter/objects.rs:12:5
|
||||
|
|
||||
12 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `StringBox`
|
||||
--> src/interpreter/methods/collection_methods.rs:11:24
|
||||
|
|
||||
11 | use crate::box_trait::{StringBox, IntegerBox, NyashBox, BoolBox};
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: unused imports: `IntegerBox` and `StringBox`
|
||||
--> src/interpreter/methods/data_methods.rs:11:34
|
||||
|
|
||||
11 | use crate::box_trait::{NyashBox, StringBox, IntegerBox};
|
||||
| ^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
warning: unused import: `StringBox`
|
||||
--> src/interpreter/methods/network_methods.rs:10:34
|
||||
|
|
||||
10 | use crate::box_trait::{NyashBox, StringBox};
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: unused import: `BoolBox`
|
||||
--> src/interpreter/methods/p2p_methods.rs:9:45
|
||||
|
|
||||
9 | use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||
| ^^^^^^^
|
||||
|
||||
warning: unused import: `crate::method_box::MethodBox`
|
||||
--> src/interpreter/methods/p2p_methods.rs:11:5
|
||||
|
|
||||
11 | use crate::method_box::MethodBox;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `basic_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:27:9
|
||||
|
|
||||
27 | pub use basic_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `collection_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:28:9
|
||||
|
|
||||
28 | pub use collection_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `io_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:29:9
|
||||
|
|
||||
29 | pub use io_methods::*;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `data_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:30:9
|
||||
|
|
||||
30 | pub use data_methods::*;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `network_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:31:9
|
||||
|
|
||||
31 | pub use network_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/operator_traits.rs:16:5
|
||||
|
|
||||
16 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/transport/mod.rs:10:5
|
||||
|
|
||||
10 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `Write`
|
||||
--> src/boxes/stream/mod.rs:10:21
|
||||
|
|
||||
10 | use std::io::{Read, Write, Result};
|
||||
| ^^^^^
|
||||
|
||||
warning: unused import: `Read`
|
||||
--> src/boxes/stream/mod.rs:10:15
|
||||
|
|
||||
10 | use std::io::{Read, Write, Result};
|
||||
| ^^^^
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:26:28
|
||||
|
|
||||
26 | pub fn http_get(&self, url: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
|
||||
= note: `#[warn(unused_variables)]` on by default
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:31:24
|
||||
|
|
||||
31 | pub fn post(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `body`
|
||||
--> src/boxes/http/mod.rs:31:48
|
||||
|
|
||||
31 | pub fn post(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_body`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:36:23
|
||||
|
|
||||
36 | pub fn put(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `body`
|
||||
--> src/boxes/http/mod.rs:36:47
|
||||
|
|
||||
36 | pub fn put(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_body`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:41:26
|
||||
|
|
||||
41 | pub fn delete(&self, url: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `method`
|
||||
--> src/boxes/http/mod.rs:46:27
|
||||
|
|
||||
46 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_method`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:46:54
|
||||
|
|
||||
46 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `options`
|
||||
--> src/boxes/http/mod.rs:46:78
|
||||
|
|
||||
46 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_options`
|
||||
|
||||
warning: variable `arg_count` is assigned to, but never used
|
||||
--> src/parser/expressions.rs:246:33
|
||||
|
|
||||
246 | let mut arg_count = 0;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_arg_count` instead
|
||||
|
||||
warning: unused variable: `name`
|
||||
--> src/parser/statements.rs:69:35
|
||||
|
|
||||
69 | TokenType::IDENTIFIER(name) => {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_name`
|
||||
|
||||
warning: variable `statement_count` is assigned to, but never used
|
||||
--> src/parser/mod.rs:132:17
|
||||
|
|
||||
132 | let mut statement_count = 0;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_statement_count` instead
|
||||
|
||||
warning: unused variable: `i`
|
||||
--> src/interpreter/expressions.rs:554:22
|
||||
|
|
||||
554 | for (i, arg) in arguments.iter().enumerate() {
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_i`
|
||||
|
||||
warning: variable `result` is assigned to, but never used
|
||||
--> src/interpreter/expressions.rs:899:21
|
||||
|
|
||||
899 | let mut result: Box<dyn NyashBox> = Box::new(VoidBox::new());
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: consider using `_result` instead
|
||||
|
||||
warning: value assigned to `result` is never read
|
||||
--> src/interpreter/expressions.rs:901:17
|
||||
|
|
||||
901 | result = self.execute_statement(statement)?;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
= note: `#[warn(unused_assignments)]` on by default
|
||||
|
||||
warning: value assigned to `result` is never read
|
||||
--> src/interpreter/expressions.rs:905:21
|
||||
|
|
||||
905 | result = return_val.clone_box();
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
warning: unused variable: `current_instance`
|
||||
--> src/interpreter/expressions.rs:924:78
|
||||
|
|
||||
924 | fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||
| ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_current_instance`
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> src/interpreter/expressions.rs:924:74
|
||||
|
|
||||
924 | fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||
| ----^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
= note: `#[warn(unused_mut)]` on by default
|
||||
|
||||
warning: unused variable: `node_id`
|
||||
--> src/interpreter/objects.rs:545:21
|
||||
|
|
||||
545 | let node_id = if let Some(id_str) = node_id_value.as_any().downcast_ref::<StringBox>() {
|
||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_node_id`
|
||||
|
||||
warning: unused variable: `transport_str`
|
||||
--> src/interpreter/objects.rs:555:21
|
||||
|
|
||||
555 | let transport_str = if let Some(t_str) = transport_value.as_any().downcast_ref::<StringBox>() {
|
||||
| ^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_transport_str`
|
||||
|
||||
warning: unused variable: `existing_method`
|
||||
--> src/instance.rs:89:21
|
||||
|
|
||||
89 | if let Some(existing_method) = new_methods.get(&method_name) {
|
||||
| ^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_existing_method`
|
||||
|
||||
warning: field `evaluation_stack` is never read
|
||||
--> src/interpreter/core.rs:207:16
|
||||
|
|
||||
190 | pub struct NyashInterpreter {
|
||||
| ---------------- field in this struct
|
||||
...
|
||||
207 | pub(super) evaluation_stack: Vec<usize>,
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: methods `get_object_id` and `hash_string` are never used
|
||||
--> src/interpreter/expressions.rs:697:8
|
||||
|
|
||||
18 | impl NyashInterpreter {
|
||||
| --------------------- methods in this implementation
|
||||
...
|
||||
697 | fn get_object_id(&self, node: &ASTNode) -> Option<usize> {
|
||||
| ^^^^^^^^^^^^^
|
||||
...
|
||||
716 | fn hash_string(&self, s: &str) -> usize {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
Compiling nyash-rust v0.1.0 (/mnt/c/git/nyash-project/nyash)
|
||||
warning: `nyash-rust` (lib) generated 53 warnings (run `cargo fix --lib -p nyash-rust` to apply 27 suggestions)
|
||||
error: couldn't read `examples/C:/Windows/Fonts/arial.ttf`: No such file or directory (os error 2)
|
||||
--> examples/simple_notepad_win.rs:32:57
|
||||
|
|
||||
32 | std::sync::Arc::new(egui::FontData::from_static(include_bytes!(
|
||||
| _________________________________________________________^
|
||||
33 | | "C:/Windows/Fonts/arial.ttf"
|
||||
34 | | ))),
|
||||
| |_________^
|
||||
|
||||
warning: unused import: `std::path::PathBuf`
|
||||
--> examples/nyash_explorer.rs:5:5
|
||||
|
|
||||
5 | use std::path::PathBuf;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: use of deprecated method `eframe::egui::Ui::allocate_ui_at_rect`: Use `allocate_new_ui` instead
|
||||
--> examples/nyash_explorer.rs:287:28
|
||||
|
|
||||
287 | ui.allocate_ui_at_rect(response.rect, |ui| {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(deprecated)]` on by default
|
||||
|
||||
warning: fields `letter` and `icon_data` are never read
|
||||
--> examples/nyash_explorer.rs:63:5
|
||||
|
|
||||
62 | struct DriveInfo {
|
||||
| --------- fields in this struct
|
||||
63 | letter: String,
|
||||
| ^^^^^^
|
||||
...
|
||||
68 | icon_data: Option<Vec<u8>>,
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: `DriveInfo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: field `letter` is never read
|
||||
--> examples/nyash_explorer_with_icons.rs:70:5
|
||||
|
|
||||
69 | struct DriveInfo {
|
||||
| --------- field in this struct
|
||||
70 | letter: String,
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: associated function `load_bmp_icon` is never used
|
||||
--> examples/nyash_explorer_with_icons.rs:145:8
|
||||
|
|
||||
85 | impl NyashExplorer {
|
||||
| ------------------ associated function in this implementation
|
||||
...
|
||||
145 | fn load_bmp_icon(file_path: &str) -> Option<ColorImage> {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: fields `from_output` and `to_input` are never read
|
||||
--> development/egui_research/experiments/visual_node_prototype.rs:118:5
|
||||
|
|
||||
116 | struct Connection {
|
||||
| ---------- fields in this struct
|
||||
117 | from_node: usize,
|
||||
118 | from_output: String,
|
||||
| ^^^^^^^^^^^
|
||||
119 | to_node: usize,
|
||||
120 | to_input: String,
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: `Connection` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: fields `connecting_from`, `pan_offset`, and `zoom` are never read
|
||||
--> development/egui_research/experiments/visual_node_prototype.rs:128:5
|
||||
|
|
||||
123 | struct VisualProgramming {
|
||||
| ----------------- fields in this struct
|
||||
...
|
||||
128 | connecting_from: Option<(usize, String)>,
|
||||
| ^^^^^^^^^^^^^^^
|
||||
129 | pan_offset: Vec2,
|
||||
| ^^^^^^^^^^
|
||||
130 | zoom: f32,
|
||||
| ^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> examples/simple_notepad_win.rs:32:9
|
||||
|
|
||||
30 | fonts.font_data.insert(
|
||||
| ------ arguments to this method are incorrect
|
||||
31 | "system".to_owned(),
|
||||
32 | / std::sync::Arc::new(egui::FontData::from_static(include_bytes!(
|
||||
33 | | "C:/Windows/Fonts/arial.ttf"
|
||||
34 | | ))),
|
||||
| |___________^ expected `FontData`, found `Arc<FontData>`
|
||||
|
|
||||
= note: expected struct `FontData`
|
||||
found struct `Arc<FontData>`
|
||||
help: the return type of this call is `Arc<FontData>` due to the type of the argument passed
|
||||
--> examples/simple_notepad_win.rs:30:5
|
||||
|
|
||||
30 | / fonts.font_data.insert(
|
||||
31 | | "system".to_owned(),
|
||||
32 | |/ std::sync::Arc::new(egui::FontData::from_static(include_bytes!(
|
||||
33 | || "C:/Windows/Fonts/arial.ttf"
|
||||
34 | || ))),
|
||||
| ||___________- this argument influences the return type of `insert`
|
||||
35 | | );
|
||||
| |______^
|
||||
note: method defined here
|
||||
--> /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/alloc/src/collections/btree/map.rs:1023:12
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
error: could not compile `nyash-rust` (example "simple_notepad_win") due to 2 previous errors
|
||||
warning: build failed, waiting for other jobs to finish...
|
||||
warning: unused import: `std::collections::HashMap`
|
||||
--> tests/integration_tests.rs:9:5
|
||||
|
|
||||
9 | use std::collections::HashMap;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: function `execute_nyash_code` is never used
|
||||
--> tests/integration_tests.rs:12:4
|
||||
|
|
||||
12 | fn execute_nyash_code(code: &str) -> Result<String, String> {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: unused import: `std::env`
|
||||
--> src/main.rs:33:5
|
||||
|
|
||||
33 | use std::env;
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: unused imports: `BoolBox`, `IntegerBox`, and `StringBox`
|
||||
--> src/ast.rs:864:28
|
||||
|
|
||||
864 | use crate::box_trait::{StringBox, IntegerBox, BoolBox};
|
||||
| ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^
|
||||
|
||||
error[E0063]: missing field `is_override` in initializer of `ast::ASTNode`
|
||||
--> src/ast.rs:915:48
|
||||
|
|
||||
915 | methods.insert("getValue".to_string(), ASTNode::FunctionDeclaration {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `is_override`
|
||||
|
||||
error[E0063]: missing fields `is_static`, `static_init` and `type_parameters` in initializer of `ast::ASTNode`
|
||||
--> src/ast.rs:932:24
|
||||
|
|
||||
932 | let box_decl = ASTNode::BoxDeclaration {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ missing `is_static`, `static_init` and `type_parameters`
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
||||
warning: `nyash-rust` (bin "nyash" test) generated 53 warnings (52 duplicates)
|
||||
error: could not compile `nyash-rust` (bin "nyash" test) due to 2 previous errors; 53 warnings emitted
|
||||
error[E0599]: no method named `len` found for struct `boxes::array::ArrayBox` in the current scope
|
||||
--> src/tests/box_tests.rs:19:26
|
||||
|
|
||||
19 | assert_eq!(array.len(), 2);
|
||||
| ^^^
|
||||
|
|
||||
::: src/boxes/array/mod.rs:11:1
|
||||
|
|
||||
11 | pub struct ArrayBox {
|
||||
| ------------------- method `len` not found for this struct
|
||||
|
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following traits define an item `len`, perhaps you need to implement one of them:
|
||||
candidate #1: `CacheTrait`
|
||||
candidate #2: `ExactSizeIterator`
|
||||
candidate #3: `avif_serialize::boxes::MpegBox`
|
||||
candidate #4: `nom::traits::AsChar`
|
||||
candidate #5: `rayon::iter::IndexedParallelIterator`
|
||||
candidate #6: `rayon::range::private::IndexedRangeInteger`
|
||||
candidate #7: `rayon::range_inclusive::private::IndexedRangeInteger`
|
||||
help: there is a method `length` with a similar name
|
||||
|
|
||||
19 | assert_eq!(array.length(), 2);
|
||||
| +++
|
||||
|
||||
error[E0599]: no method named `len` found for struct `buffer::BufferBox` in the current scope
|
||||
--> src/tests/box_tests.rs:35:27
|
||||
|
|
||||
35 | assert_eq!(buffer.len(), 5);
|
||||
| ^^^
|
||||
|
|
||||
::: src/boxes/buffer/mod.rs:38:1
|
||||
|
|
||||
38 | pub struct BufferBox {
|
||||
| -------------------- method `len` not found for this struct
|
||||
|
|
||||
= help: items from traits can only be used if the trait is implemented and in scope
|
||||
= note: the following traits define an item `len`, perhaps you need to implement one of them:
|
||||
candidate #1: `CacheTrait`
|
||||
candidate #2: `ExactSizeIterator`
|
||||
candidate #3: `avif_serialize::boxes::MpegBox`
|
||||
candidate #4: `nom::traits::AsChar`
|
||||
candidate #5: `rayon::iter::IndexedParallelIterator`
|
||||
candidate #6: `rayon::range::private::IndexedRangeInteger`
|
||||
candidate #7: `rayon::range_inclusive::private::IndexedRangeInteger`
|
||||
help: there is a method `length` with a similar name
|
||||
|
|
||||
35 | assert_eq!(buffer.length(), 5);
|
||||
| +++
|
||||
|
||||
error[E0600]: cannot apply unary operator `!` to type `Box<(dyn box_trait::NyashBox + 'static)>`
|
||||
--> src/tests/box_tests.rs:114:9
|
||||
|
|
||||
114 | assert!(success_result.is_ok());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot apply unary operator `!`
|
||||
|
|
||||
note: the foreign item type `Box<(dyn box_trait::NyashBox + 'static)>` doesn't implement `Not`
|
||||
--> /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/alloc/src/boxed.rs:231:1
|
||||
::: /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/alloc/src/boxed.rs:234:1
|
||||
|
|
||||
= note: not implement `Not`
|
||||
|
||||
error[E0600]: cannot apply unary operator `!` to type `Box<(dyn box_trait::NyashBox + 'static)>`
|
||||
--> src/tests/box_tests.rs:122:17
|
||||
|
|
||||
122 | assert!(!error_result.is_ok());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ cannot apply unary operator `!`
|
||||
|
|
||||
note: the foreign item type `Box<(dyn box_trait::NyashBox + 'static)>` doesn't implement `Not`
|
||||
--> /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/alloc/src/boxed.rs:231:1
|
||||
::: /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/alloc/src/boxed.rs:234:1
|
||||
|
|
||||
= note: not implement `Not`
|
||||
|
||||
error[E0599]: no method named `box_id` found for struct `boxes::array::ArrayBox` in the current scope
|
||||
--> src/tests/box_tests.rs:135:25
|
||||
|
|
||||
135 | assert_ne!(box1.box_id(), box2.box_id());
|
||||
| ^^^^^^ method not found in `ArrayBox`
|
||||
|
|
||||
::: src/boxes/array/mod.rs:11:1
|
||||
|
|
||||
11 | pub struct ArrayBox {
|
||||
| ------------------- method `box_id` not found for this struct
|
||||
|
|
||||
::: src/box_trait.rs:55:8
|
||||
|
|
||||
55 | fn box_id(&self) -> u64;
|
||||
| ------ the method is available for `boxes::array::ArrayBox` here
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
help: trait `BoxCore` which provides `box_id` is implemented but not in scope; perhaps you want to import it
|
||||
|
|
||||
7 + use crate::box_trait::BoxCore;
|
||||
|
|
||||
|
||||
error[E0599]: no method named `box_id` found for struct `boxes::array::ArrayBox` in the current scope
|
||||
--> src/tests/box_tests.rs:135:40
|
||||
|
|
||||
135 | assert_ne!(box1.box_id(), box2.box_id());
|
||||
| ^^^^^^ method not found in `ArrayBox`
|
||||
|
|
||||
::: src/boxes/array/mod.rs:11:1
|
||||
|
|
||||
11 | pub struct ArrayBox {
|
||||
| ------------------- method `box_id` not found for this struct
|
||||
|
|
||||
::: src/box_trait.rs:55:8
|
||||
|
|
||||
55 | fn box_id(&self) -> u64;
|
||||
| ------ the method is available for `boxes::array::ArrayBox` here
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
help: trait `BoxCore` which provides `box_id` is implemented but not in scope; perhaps you want to import it
|
||||
|
|
||||
7 + use crate::box_trait::BoxCore;
|
||||
|
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> src/tests/box_tests.rs:90:13
|
||||
|
|
||||
90 | let mut stream = NyashStreamBox::from_data(vec![72, 101, 108, 108, 111]); // "Hello"
|
||||
| ----^^^^^^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
||||
Some errors have detailed explanations: E0063, E0599, E0600.
|
||||
For more information about an error, try `rustc --explain E0063`.
|
||||
warning: `nyash-rust` (lib test) generated 53 warnings (52 duplicates)
|
||||
error: could not compile `nyash-rust` (lib test) due to 8 previous errors; 53 warnings emitted
|
||||
warning: `nyash-rust` (bin "nyash_explorer_icons" test) generated 2 warnings (2 duplicates)
|
||||
warning: `nyash-rust` (bin "nyash_explorer" test) generated 3 warnings (3 duplicates)
|
||||
warning: `nyash-rust` (test "integration_tests") generated 2 warnings (run `cargo fix --test "integration_tests"` to apply 1 suggestion)
|
||||
434
docs/archive/nyashvalue_check_errors.txt
Normal file
434
docs/archive/nyashvalue_check_errors.txt
Normal file
@ -0,0 +1,434 @@
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/debug_notepad.rs` found to be present in multiple build targets:
|
||||
* `bin` target `debug_notepad`
|
||||
* `example` target `debug_notepad`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/test_icon_extraction.rs` found to be present in multiple build targets:
|
||||
* `bin` target `test_icon_extraction`
|
||||
* `example` target `test_icon_extraction`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad_ascii.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad_ascii`
|
||||
* `example` target `simple_notepad_ascii`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad_v2.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad`
|
||||
* `example` target `simple_notepad_v2`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_notepad_jp.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_notepad_jp`
|
||||
* `example` target `nyash_notepad_jp`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_explorer_with_icons.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_explorer_icons`
|
||||
* `example` target `nyash_explorer_with_icons`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/nyash_explorer.rs` found to be present in multiple build targets:
|
||||
* `bin` target `nyash_explorer`
|
||||
* `example` target `nyash_explorer`
|
||||
warning: file `/mnt/c/git/nyash-project/nyash/examples/simple_notepad.rs` found to be present in multiple build targets:
|
||||
* `bin` target `simple_notepad`
|
||||
* `example` target `simple_notepad`
|
||||
warning: unused import: `next_box_id`
|
||||
--> src/boxes/math_box.rs:59:84
|
||||
|
|
||||
59 | use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase, next_box_id};
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: unused import: `next_box_id`
|
||||
--> src/boxes/debug_box.rs:105:42
|
||||
|
|
||||
105 | use crate::box_trait::{BoxCore, BoxBase, next_box_id, NyashBox, StringBox, BoolBox, VoidBox};
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `next_box_id`
|
||||
--> src/boxes/null_box.rs:87:72
|
||||
|
|
||||
87 | use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase, next_box_id};
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::future::Future`
|
||||
--> src/boxes/future/mod.rs:7:5
|
||||
|
|
||||
7 | use std::future::Future;
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::pin::Pin`
|
||||
--> src/boxes/future/mod.rs:8:5
|
||||
|
|
||||
8 | use std::pin::Pin;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `crate::boxes::map_box::MapBox`
|
||||
--> src/boxes/http/mod.rs:9:5
|
||||
|
|
||||
9 | use crate::boxes::map_box::MapBox;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused imports: `Arc` and `Mutex`
|
||||
--> src/boxes/http/mod.rs:11:17
|
||||
|
|
||||
11 | use std::sync::{Arc, Mutex};
|
||||
| ^^^ ^^^^^
|
||||
|
||||
warning: unused import: `Mutex`
|
||||
--> src/boxes/regex/mod.rs:9:22
|
||||
|
|
||||
9 | use std::sync::{Arc, Mutex};
|
||||
| ^^^^^
|
||||
|
||||
warning: unused import: `self`
|
||||
--> src/boxes/intent_box.rs:38:16
|
||||
|
|
||||
38 | use std::fmt::{self, Debug};
|
||||
| ^^^^
|
||||
|
||||
warning: unused macro definition: `debug_fuel`
|
||||
--> src/parser/expressions.rs:38:14
|
||||
|
|
||||
38 | macro_rules! debug_fuel {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_macros)]` on by default
|
||||
|
||||
warning: unused macro definition: `debug_fuel`
|
||||
--> src/parser/mod.rs:51:14
|
||||
|
|
||||
51 | macro_rules! debug_fuel {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
warning: unused imports: `AddBox`, `DivideBox`, `MultiplyBox`, and `SubtractBox`
|
||||
--> src/interpreter/mod.rs:10:75
|
||||
|
|
||||
10 | use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, AddBox, SubtractBox, MultiplyBox, DivideBox, CompareBox, ArrayB...
|
||||
| ^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^
|
||||
|
||||
warning: unused import: `FloatBox`
|
||||
--> src/interpreter/mod.rs:13:39
|
||||
|
|
||||
13 | use crate::boxes::math_box::{MathBox, FloatBox, RangeBox};
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: unused import: `DateTimeBox`
|
||||
--> src/interpreter/mod.rs:14:39
|
||||
|
|
||||
14 | use crate::boxes::time_box::{TimeBox, DateTimeBox, TimerBox};
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `file::FileBox`
|
||||
--> src/interpreter/expressions.rs:12:104
|
||||
|
|
||||
12 | use crate::boxes::{FloatBox, MathBox, ConsoleBox, TimeBox, DateTimeBox, RandomBox, SoundBox, DebugBox, file::FileBox, MapBox};
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/interpreter/objects.rs:12:5
|
||||
|
|
||||
12 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `StringBox`
|
||||
--> src/interpreter/methods/collection_methods.rs:11:24
|
||||
|
|
||||
11 | use crate::box_trait::{StringBox, IntegerBox, NyashBox, BoolBox};
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: unused imports: `IntegerBox` and `StringBox`
|
||||
--> src/interpreter/methods/data_methods.rs:11:34
|
||||
|
|
||||
11 | use crate::box_trait::{NyashBox, StringBox, IntegerBox};
|
||||
| ^^^^^^^^^ ^^^^^^^^^^
|
||||
|
||||
warning: unused import: `StringBox`
|
||||
--> src/interpreter/methods/network_methods.rs:10:34
|
||||
|
|
||||
10 | use crate::box_trait::{NyashBox, StringBox};
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: unused import: `BoolBox`
|
||||
--> src/interpreter/methods/p2p_methods.rs:9:45
|
||||
|
|
||||
9 | use crate::box_trait::{NyashBox, StringBox, BoolBox};
|
||||
| ^^^^^^^
|
||||
|
||||
warning: unused import: `crate::method_box::MethodBox`
|
||||
--> src/interpreter/methods/p2p_methods.rs:11:5
|
||||
|
|
||||
11 | use crate::method_box::MethodBox;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `basic_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:27:9
|
||||
|
|
||||
27 | pub use basic_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `collection_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:28:9
|
||||
|
|
||||
28 | pub use collection_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `io_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:29:9
|
||||
|
|
||||
29 | pub use io_methods::*;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `data_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:30:9
|
||||
|
|
||||
30 | pub use data_methods::*;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `network_methods::*`
|
||||
--> src/interpreter/methods/mod.rs:31:9
|
||||
|
|
||||
31 | pub use network_methods::*;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/operator_traits.rs:16:5
|
||||
|
|
||||
16 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `std::sync::Arc`
|
||||
--> src/transport/mod.rs:10:5
|
||||
|
|
||||
10 | use std::sync::Arc;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `Write`
|
||||
--> src/boxes/stream/mod.rs:10:21
|
||||
|
|
||||
10 | use std::io::{Read, Write, Result};
|
||||
| ^^^^^
|
||||
|
||||
warning: unused import: `Read`
|
||||
--> src/boxes/stream/mod.rs:10:15
|
||||
|
|
||||
10 | use std::io::{Read, Write, Result};
|
||||
| ^^^^
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:26:28
|
||||
|
|
||||
26 | pub fn http_get(&self, url: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
|
||||
= note: `#[warn(unused_variables)]` on by default
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:31:24
|
||||
|
|
||||
31 | pub fn post(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `body`
|
||||
--> src/boxes/http/mod.rs:31:48
|
||||
|
|
||||
31 | pub fn post(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_body`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:36:23
|
||||
|
|
||||
36 | pub fn put(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `body`
|
||||
--> src/boxes/http/mod.rs:36:47
|
||||
|
|
||||
36 | pub fn put(&self, url: Box<dyn NyashBox>, body: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_body`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:41:26
|
||||
|
|
||||
41 | pub fn delete(&self, url: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `method`
|
||||
--> src/boxes/http/mod.rs:46:27
|
||||
|
|
||||
46 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_method`
|
||||
|
||||
warning: unused variable: `url`
|
||||
--> src/boxes/http/mod.rs:46:54
|
||||
|
|
||||
46 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^ help: if this is intentional, prefix it with an underscore: `_url`
|
||||
|
||||
warning: unused variable: `options`
|
||||
--> src/boxes/http/mod.rs:46:78
|
||||
|
|
||||
46 | pub fn request(&self, method: Box<dyn NyashBox>, url: Box<dyn NyashBox>, options: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
|
||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_options`
|
||||
|
||||
warning: variable `arg_count` is assigned to, but never used
|
||||
--> src/parser/expressions.rs:246:33
|
||||
|
|
||||
246 | let mut arg_count = 0;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_arg_count` instead
|
||||
|
||||
warning: unused variable: `name`
|
||||
--> src/parser/statements.rs:69:35
|
||||
|
|
||||
69 | TokenType::IDENTIFIER(name) => {
|
||||
| ^^^^ help: if this is intentional, prefix it with an underscore: `_name`
|
||||
|
||||
warning: variable `statement_count` is assigned to, but never used
|
||||
--> src/parser/mod.rs:132:17
|
||||
|
|
||||
132 | let mut statement_count = 0;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: consider using `_statement_count` instead
|
||||
|
||||
warning: unused variable: `i`
|
||||
--> src/interpreter/expressions.rs:554:22
|
||||
|
|
||||
554 | for (i, arg) in arguments.iter().enumerate() {
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_i`
|
||||
|
||||
warning: variable `result` is assigned to, but never used
|
||||
--> src/interpreter/expressions.rs:899:21
|
||||
|
|
||||
899 | let mut result: Box<dyn NyashBox> = Box::new(VoidBox::new());
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: consider using `_result` instead
|
||||
|
||||
warning: value assigned to `result` is never read
|
||||
--> src/interpreter/expressions.rs:901:17
|
||||
|
|
||||
901 | result = self.execute_statement(statement)?;
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
= note: `#[warn(unused_assignments)]` on by default
|
||||
|
||||
warning: value assigned to `result` is never read
|
||||
--> src/interpreter/expressions.rs:905:21
|
||||
|
|
||||
905 | result = return_val.clone_box();
|
||||
| ^^^^^^
|
||||
|
|
||||
= help: maybe it is overwritten before being read?
|
||||
|
||||
warning: unused variable: `current_instance`
|
||||
--> src/interpreter/expressions.rs:924:78
|
||||
|
|
||||
924 | fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||
| ^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_current_instance`
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> src/interpreter/expressions.rs:924:74
|
||||
|
|
||||
924 | fn execute_builtin_box_method(&mut self, parent: &str, method: &str, mut current_instance: Box<dyn NyashBox>, arguments: &[ASTNode])
|
||||
| ----^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
= note: `#[warn(unused_mut)]` on by default
|
||||
|
||||
warning: unused variable: `node_id`
|
||||
--> src/interpreter/objects.rs:545:21
|
||||
|
|
||||
545 | let node_id = if let Some(id_str) = node_id_value.as_any().downcast_ref::<StringBox>() {
|
||||
| ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_node_id`
|
||||
|
||||
warning: unused variable: `transport_str`
|
||||
--> src/interpreter/objects.rs:555:21
|
||||
|
|
||||
555 | let transport_str = if let Some(t_str) = transport_value.as_any().downcast_ref::<StringBox>() {
|
||||
| ^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_transport_str`
|
||||
|
||||
warning: unused variable: `existing_method`
|
||||
--> src/instance.rs:89:21
|
||||
|
|
||||
89 | if let Some(existing_method) = new_methods.get(&method_name) {
|
||||
| ^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_existing_method`
|
||||
|
||||
warning: field `evaluation_stack` is never read
|
||||
--> src/interpreter/core.rs:207:16
|
||||
|
|
||||
190 | pub struct NyashInterpreter {
|
||||
| ---------------- field in this struct
|
||||
...
|
||||
207 | pub(super) evaluation_stack: Vec<usize>,
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: methods `get_object_id` and `hash_string` are never used
|
||||
--> src/interpreter/expressions.rs:697:8
|
||||
|
|
||||
18 | impl NyashInterpreter {
|
||||
| --------------------- methods in this implementation
|
||||
...
|
||||
697 | fn get_object_id(&self, node: &ASTNode) -> Option<usize> {
|
||||
| ^^^^^^^^^^^^^
|
||||
...
|
||||
716 | fn hash_string(&self, s: &str) -> usize {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: `nyash-rust` (lib) generated 53 warnings (run `cargo fix --lib -p nyash-rust` to apply 27 suggestions)
|
||||
warning: unused import: `std::env`
|
||||
--> src/main.rs:33:5
|
||||
|
|
||||
33 | use std::env;
|
||||
| ^^^^^^^^
|
||||
|
||||
warning: unused import: `std::path::PathBuf`
|
||||
--> examples/nyash_explorer.rs:5:5
|
||||
|
|
||||
5 | use std::path::PathBuf;
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: use of deprecated method `eframe::egui::Ui::allocate_ui_at_rect`: Use `allocate_new_ui` instead
|
||||
--> examples/nyash_explorer.rs:287:28
|
||||
|
|
||||
287 | ui.allocate_ui_at_rect(response.rect, |ui| {
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(deprecated)]` on by default
|
||||
|
||||
warning: fields `letter` and `icon_data` are never read
|
||||
--> examples/nyash_explorer.rs:63:5
|
||||
|
|
||||
62 | struct DriveInfo {
|
||||
| --------- fields in this struct
|
||||
63 | letter: String,
|
||||
| ^^^^^^
|
||||
...
|
||||
68 | icon_data: Option<Vec<u8>>,
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: `DriveInfo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: field `letter` is never read
|
||||
--> examples/nyash_explorer_with_icons.rs:70:5
|
||||
|
|
||||
69 | struct DriveInfo {
|
||||
| --------- field in this struct
|
||||
70 | letter: String,
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: associated function `load_bmp_icon` is never used
|
||||
--> examples/nyash_explorer_with_icons.rs:145:8
|
||||
|
|
||||
85 | impl NyashExplorer {
|
||||
| ------------------ associated function in this implementation
|
||||
...
|
||||
145 | fn load_bmp_icon(file_path: &str) -> Option<ColorImage> {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
warning: `nyash-rust` (bin "nyash") generated 54 warnings (53 duplicates) (run `cargo fix --bin "nyash"` to apply 1 suggestion)
|
||||
warning: `nyash-rust` (bin "nyash_explorer") generated 3 warnings (run `cargo fix --bin "nyash_explorer"` to apply 1 suggestion)
|
||||
warning: `nyash-rust` (bin "nyash_explorer_icons") generated 2 warnings
|
||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.59s
|
||||
77
docs/archive/sessions/architecture_consultation.txt
Normal file
77
docs/archive/sessions/architecture_consultation.txt
Normal file
@ -0,0 +1,77 @@
|
||||
Nyashプログラミング言語のBox型アーキテクチャ設計について深い技術相談です。
|
||||
|
||||
【現在の状況】
|
||||
- Rust実装のプログラミング言語Nyash開発中
|
||||
- "Everything is Box"哲学:全データがBoxオブジェクト
|
||||
- 現在16種類のBox型実装済み(StringBox, IntegerBox, P2PBox等)
|
||||
- Arc<Mutex>統一パターンでスレッドセーフ性確保
|
||||
|
||||
【現在のアーキテクチャ問題】
|
||||
現在、全Box型をtype aliasで統一しているが、実装で型エラー地獄が発生:
|
||||
|
||||
```rust
|
||||
// 現在の問題のある設計
|
||||
type StringBox = Arc<Mutex<StringBoxData>>;
|
||||
type IntegerBox = Arc<Mutex<IntegerBoxData>>;
|
||||
type P2PBox = Arc<Mutex<P2PBoxData>>;
|
||||
|
||||
// 問題:型エイリアス複雑化、trait object Debug実装困難
|
||||
// 結果:Copilot実装で型エラー多発、開発効率低下
|
||||
```
|
||||
|
||||
【検討中のシンプル設計】
|
||||
newtype patternによるシンプル化:
|
||||
|
||||
```rust
|
||||
// 案1: newtype pattern
|
||||
struct StringBox(Arc<Mutex<StringBoxData>>);
|
||||
struct IntegerBox(Arc<Mutex<IntegerBoxData>>);
|
||||
struct P2PBox(Arc<Mutex<P2PBoxData>>);
|
||||
|
||||
// 案2: 生構造体(必要時のみArc化)
|
||||
struct StringBox { data: String }
|
||||
struct IntegerBox { value: i64 }
|
||||
// 共有が必要な時だけArc::new()で包む
|
||||
```
|
||||
|
||||
【技術的検討ポイント】
|
||||
|
||||
1. **型安全性とシンプルさのバランス**
|
||||
- type alias vs newtype vs 生構造体
|
||||
- コンパイル時エラー検出 vs 実装しやすさ
|
||||
|
||||
2. **スレッドセーフ性の要件**
|
||||
- 全Box型で並行処理が必要か?
|
||||
- StringBox等の基本型にもMutex必要?
|
||||
- 必要な時だけArc<Mutex>化する方が良い?
|
||||
|
||||
3. **拡張性・保守性**
|
||||
- 新Box型追加時の実装コスト
|
||||
- エラーメッセージの分かりやすさ
|
||||
- 他開発者(AI含む)の理解しやすさ
|
||||
|
||||
4. **パフォーマンス**
|
||||
- Arc<Mutex>のオーバーヘッド
|
||||
- ゼロコスト抽象化の実現可能性
|
||||
- メモリ使用量の最適化
|
||||
|
||||
5. **現実的な実装戦略**
|
||||
- 段階的移行 vs 一括変更
|
||||
- 既存コードとの互換性
|
||||
- 開発スピード重視 vs 理想設計重視
|
||||
|
||||
【具体的相談事項】
|
||||
1. type alias vs newtype vs 生構造体、どの設計が最適?
|
||||
2. 全Box型に一律Arc<Mutex>は過剰?必要な箇所のみの方が良い?
|
||||
3. Rust専門家から見て推奨されるBox型統一アーキテクチャは?
|
||||
4. プログラミング言語実装において、型システムのベストプラクティスは?
|
||||
5. 実装効率と設計美学のバランスをどう取るべき?
|
||||
|
||||
【制約条件】
|
||||
- Rust実装必須
|
||||
- Everything is Box哲学維持
|
||||
- スレッドセーフ性確保
|
||||
- 16種類+今後追加予定のBox型すべてで統一
|
||||
- 実装・保守の現実性重視
|
||||
|
||||
プログラミング言語設計・Rust専門家の視点から、実装可能で美しく、長期保守に適したアーキテクチャ設計を提案してください。
|
||||
64
docs/archive/sessions/chatgpt_consultation_overload.txt
Normal file
64
docs/archive/sessions/chatgpt_consultation_overload.txt
Normal file
@ -0,0 +1,64 @@
|
||||
Nyashプログラミング言語の関数オーバーロード設計について深い技術的相談です。
|
||||
|
||||
【Nyashの技術的特徴】
|
||||
- Everything is Box哲学: 全データがBoxオブジェクト
|
||||
- Arc<Mutex>統一アーキテクチャ: 完全スレッドセーフ設計
|
||||
- 明示性重視: 変数宣言先の即座特定可能
|
||||
- Rust実装: メモリ安全性+高性能
|
||||
- 目的: 初学者フレンドリー + 実用性
|
||||
|
||||
【検討する技術的課題】
|
||||
現在P2PBox実装において、関数オーバーロード(引数数による分岐)採用の是非を検討中。
|
||||
|
||||
具体例:
|
||||
```rust
|
||||
// Option A: オーバーロードあり
|
||||
impl P2PBox {
|
||||
pub fn send(&self, message: IntentBox) -> Result<(), SendError> // ブロードキャスト
|
||||
pub fn send(&self, to: &str, message: IntentBox) -> Result<(), SendError> // 個別送信
|
||||
pub fn send(&self, to: &str, message: IntentBox, opts: SendOpts) -> Result<(), SendError> // オプション付き
|
||||
}
|
||||
|
||||
// Option B: オーバーロードなし(現在)
|
||||
impl P2PBox {
|
||||
pub fn broadcast(&self, message: IntentBox) -> Result<(), SendError>
|
||||
pub fn send(&self, to: &str, message: IntentBox) -> Result<(), SendError>
|
||||
pub fn send_with_options(&self, to: &str, message: IntentBox, opts: SendOpts) -> Result<(), SendError>
|
||||
}
|
||||
```
|
||||
|
||||
【技術的検討ポイント】
|
||||
|
||||
1. **Rust実装との整合性**
|
||||
- Rustにはメソッドオーバーロードがない
|
||||
- 引数数による分岐をインタープリターで実装する必要
|
||||
- パフォーマンスへの影響
|
||||
|
||||
2. **Arc<Mutex>アーキテクチャとの親和性**
|
||||
- 動的ディスパッチの複雑さ
|
||||
- エラーハンドリングの一貫性
|
||||
- スレッドセーフティの保持
|
||||
|
||||
3. **インタープリター実装の複雑度**
|
||||
- パーサーでの引数数判定
|
||||
- 実行時メソッド選択アルゴリズム
|
||||
- デバッグ情報の提供
|
||||
|
||||
4. **型安全性とパフォーマンス**
|
||||
- 実行時型チェックのオーバーヘッド
|
||||
- エラーメッセージの品質
|
||||
- 開発時デバッグ体験
|
||||
|
||||
5. **エコシステム設計との整合性**
|
||||
- 他のBox型との一貫性
|
||||
- 拡張性(新しいオーバーロード追加)
|
||||
- メンテナンス性
|
||||
|
||||
【深く検討してほしい点】
|
||||
1. 技術的実装の複雑さ vs ユーザー体験の向上
|
||||
2. Nyashの「明示性重視」哲学との技術的整合性
|
||||
3. 初学者がエラーに遭遇した時のデバッグ体験
|
||||
4. P2P通信という特定ドメインでの最適解
|
||||
5. 言語の長期進化における影響
|
||||
|
||||
プログラミング言語実装の専門的視点から、技術的に最良で保守しやすい設計を分析してください。
|
||||
46
docs/archive/sessions/gemini_consultation_overload.txt
Normal file
46
docs/archive/sessions/gemini_consultation_overload.txt
Normal file
@ -0,0 +1,46 @@
|
||||
Nyashプログラミング言語の関数オーバーロード採用可否について言語設計の専門的観点から相談です。
|
||||
|
||||
【背景】
|
||||
Nyashは「Everything is Box」哲学で、明示性重視・初学者フレンドリー・メモリ安全性を重視する言語です。現在Phase 2でP2PBox実装中で、関数オーバーロード(引数数による分岐)を採用するか重要な決断が必要です。
|
||||
|
||||
【具体的争点】
|
||||
send(a) と send(a, b) のような関数オーバーロードを許すか?
|
||||
|
||||
例:
|
||||
```nyash
|
||||
// オーバーロードありの場合
|
||||
node.send("hello") // ブロードキャスト
|
||||
node.send("bob", "hello") // 個別送信
|
||||
node.send("bob", msg, options) // オプション付き
|
||||
|
||||
// オーバーロードなしの場合(現在)
|
||||
node.broadcast("hello") // 明示的メソッド名
|
||||
node.send("bob", "hello") // 必ず2引数
|
||||
node.sendWithOptions("bob", msg, options) // 明示的メソッド名
|
||||
```
|
||||
|
||||
【メリット】
|
||||
1. API使いやすさ向上
|
||||
2. 他言語からの移行しやすさ
|
||||
3. 直感的な呼び出し
|
||||
|
||||
【デメリット】
|
||||
1. 間違った関数を呼ぶリスク
|
||||
2. デバッグ困難
|
||||
3. Nyashの明示性哲学と矛盾
|
||||
4. 初学者混乱
|
||||
5. 型推論複雑化
|
||||
|
||||
【Nyashの設計思想との照合】
|
||||
- 明示性重視: プログラマーが変数の宣言先を即座に特定可能
|
||||
- 初学者フレンドリー: 学習コストが低い
|
||||
- Everything is Box: 統一されたオブジェクトモデル
|
||||
|
||||
【質問】
|
||||
1. Nyashの設計思想から見て、関数オーバーロードは採用すべきか?
|
||||
2. 明示性 vs 利便性のトレードオフをどう判断すべきか?
|
||||
3. 初学者向け言語として適切な選択は?
|
||||
4. P2P通信APIにおける最良の設計は?
|
||||
5. 他の現代的言語設計トレンドとの整合性は?
|
||||
|
||||
プログラミング言語設計の専門的視点から、Nyashの将来を決めるアドバイスをお願いします。
|
||||
Reference in New Issue
Block a user