290 lines
9.4 KiB
Markdown
290 lines
9.4 KiB
Markdown
Perfect! I've completed all the non-human TODOs. Now let me discuss the human TODOs with detailed suggestions:
|
|
|
|
---
|
|
|
|
## Human TODOs - Discussion & Recommendations
|
|
|
|
### 1. **How to identify an unspecified number of arguments?**
|
|
|
|
**The Problem**: Some operations need variable numbers of arguments:
|
|
- `depth` consumes the entire stack to count it
|
|
- `printf` might take a format string + arbitrary values
|
|
|
|
**Options:**
|
|
|
|
**A) Ellipsis notation: `...`**
|
|
```
|
|
(... -- Size) depth: // Entire stack
|
|
(String ... --) printf: // String + any number of args
|
|
```
|
|
- **Pros**: Common in many languages, intuitive, clear intent
|
|
- **Cons**: Ambiguous about types, makes type checking harder
|
|
|
|
**B) Array-based variadic: `[T]`**
|
|
```
|
|
([T] -- Size) depth: // Takes array of any type
|
|
(String [T] --) printf: // String + array of values
|
|
```
|
|
- **Pros**: Type-safe, forces bundling arguments, easier to implement
|
|
- **Cons**: Requires wrapping args in array syntax, less ergonomic
|
|
|
|
**C) Special stack type: `Stack<T>`**
|
|
```
|
|
(Stack<Any> -- Size) depth: // Full stack reference
|
|
(String Stack<Any> --) printf: // String + stack reference
|
|
```
|
|
- **Pros**: Explicit that it operates on the stack itself, type-safe
|
|
- **Cons**: Adds conceptual complexity, what does consuming `Stack<T>` mean?
|
|
|
|
**D) Constraint-based: `T...` (typed variadic)**
|
|
```
|
|
(T... -- Size) depth: // Homogeneous variadics
|
|
(String Stringifiable... --) printf: // Constrained variadics
|
|
```
|
|
- **Pros**: Type-safe, clear constraints, flexible
|
|
- **Cons**: More complex type system, harder to implement
|
|
|
|
**E) Just use current system (no variadic syntax)**
|
|
```
|
|
// For depth: it actually just returns depth, doesn't consume
|
|
(-- Size) depth: // Just pushes depth
|
|
|
|
// For printf: use array
|
|
(String [Stringifiable] --) printf:
|
|
"x=%d y=%d" [x y] printf
|
|
```
|
|
- **Pros**: Simplest, no language changes needed
|
|
- **Cons**: `depth` semantics unclear, printf less ergonomic
|
|
|
|
**My Recommendation**: **Option E + D (hybrid)**
|
|
- For now, don't add variadic syntax - use arrays
|
|
- Document that `depth` is a special zero-argument operator that just pushes depth
|
|
- If variadics become essential later, add **Option D** (typed variadics with `T...`)
|
|
|
|
### 2. **Do all inheritances need to be defined before the trait is?**
|
|
|
|
**Options:**
|
|
|
|
**A) Yes, inheritance must be before trait**
|
|
```
|
|
[ ::Addable ::Multiplyable ] ::Number inher
|
|
{ } ::Number trait
|
|
```
|
|
- **Pros**: Clear declaration order, simpler parser, inheritance is explicit
|
|
- **Cons**: Separates related declarations, two statements needed
|
|
|
|
**B) No, allow inline inheritance**
|
|
```
|
|
{ } ::Number<::Addable ::Multiplyable> trait
|
|
```
|
|
- **Pros**: Single statement, more compact
|
|
- **Cons**: Confusing syntax, inheritance looks like generics
|
|
|
|
**C) Inheritance in trait body**
|
|
```
|
|
{
|
|
inherits: Addable Multiplyable
|
|
// methods here
|
|
} ::Number trait
|
|
```
|
|
- **Pros**: Single statement, clear syntax
|
|
- **Cons**: Breaks postfix philosophy, special syntax inside trait body
|
|
|
|
**My Recommendation**: **Option A (current design)**
|
|
- Keeps declarations explicit and ordered
|
|
- Maintains postfix consistency
|
|
- Parser knows about inheritance before processing trait body
|
|
|
|
### 3. **Is the `inher` operator required?**
|
|
|
|
**The Question**: Can empty inheritance work without `inher`?
|
|
|
|
**Options:**
|
|
|
|
**A) Yes, `inher` is required** (current)
|
|
```
|
|
[ ::Addable ::Multiplyable ] ::Number inher
|
|
{ } ::Number trait
|
|
```
|
|
- **Pros**: Explicit, clear intent, separates inheritance declaration
|
|
- **Cons**: Extra operator, more verbose
|
|
|
|
**B) No, merge into `trait` operator**
|
|
```
|
|
[ ::Addable ::Multiplyable ] { } ::Number trait
|
|
```
|
|
- **Pros**: More concise, fewer operators, still clear
|
|
- **Cons**: Array prefix becomes ambiguous - is it inheritance or something else?
|
|
|
|
**My Recommendation**: **Option A (keep `inher`)**
|
|
- Makes inheritance explicit and unambiguous
|
|
- Allows future extensions (diamond inheritance rules, conflict resolution)
|
|
- Parser can validate inheritance separately from trait definition
|
|
|
|
### 4. **Consider removing `inher` and replacing with `impl`?**
|
|
### 4. **Consider removing `inher` and replacing with `impl`?**
|
|
|
|
**The Idea**: Could trait inheritance use the same mechanism as trait implementation?
|
|
|
|
**Current System**:
|
|
```
|
|
// Inheritance
|
|
[ ::Addable ::Multiplyable ] ::Number inher
|
|
{ } ::Number trait
|
|
|
|
// Implementation
|
|
::Addable { ... } ::i32 impl
|
|
```
|
|
|
|
**Options:**
|
|
|
|
**A) Keep separate `inher` and `impl`** (current)
|
|
- **Pros**:
|
|
- Clear distinction between "is-a" (inheritance) and "implements" relationships
|
|
- Inheritance affects trait definition itself, impl affects types
|
|
- Easier to reason about: traits inherit, types implement
|
|
- Can have different rules and semantics for each
|
|
- **Cons**:
|
|
- Two operators with similar-sounding purposes
|
|
- More language constructs to learn
|
|
|
|
**B) Use `impl` for both**
|
|
```
|
|
// Trait inherits from other traits
|
|
::Addable { } ::Number impl
|
|
::Multiplyable { } ::Number impl
|
|
|
|
// Type implements trait
|
|
::Addable { ... } ::i32 impl
|
|
```
|
|
- **Pros**:
|
|
- Fewer operators
|
|
- Unified concept: "X implements Y"
|
|
- Simpler mental model
|
|
- **Cons**:
|
|
- Ambiguous: does `::Addable { } ::Number impl` mean Number implements Addable or inherits from it?
|
|
- Can't declare multiple inheritance in one statement
|
|
- Would need different semantics based on whether target is a trait or type
|
|
- Loses the clear "combine these traits" semantics
|
|
|
|
**C) Use `impl` with array syntax**
|
|
```
|
|
// Multiple inheritance
|
|
[ ::Addable ::Multiplyable ] { } ::Number impl
|
|
|
|
// Single inheritance
|
|
::Drawable { } ::GameObject impl
|
|
|
|
// Type implementation (unchanged)
|
|
::Addable { ... } ::i32 impl
|
|
```
|
|
- **Pros**:
|
|
- Unified operator, but array syntax distinguishes inheritance
|
|
- Still allows single-statement multiple inheritance
|
|
- Semantics clear from syntax
|
|
- **Cons**:
|
|
- Array prefix is overloaded (sometimes inheritance, sometimes not)
|
|
- Potential ambiguity: is `[::Trait1 ::Trait2]` always inheritance?
|
|
|
|
**D) Different syntax entirely**
|
|
```
|
|
// Inheritance with "extends"
|
|
::Number extends [ ::Addable ::Multiplyable ] { } trait
|
|
|
|
// Keep impl for implementations
|
|
::Addable { ... } ::i32 impl
|
|
```
|
|
- **Pros**:
|
|
- Very explicit and clear
|
|
- Familiar to OOP programmers
|
|
- No ambiguity
|
|
- **Cons**:
|
|
- Breaks postfix notation (extends comes before trait)
|
|
- Adds keyword/operator that's not fully postfix
|
|
|
|
**My Recommendation**: **Option A (keep separate)**
|
|
|
|
Here's why:
|
|
1. **Semantic Clarity**: Inheritance and implementation are fundamentally different:
|
|
- Inheritance: `Number` **is composed of** `Addable` + `Multiplyable` + more
|
|
- Implementation: `i32` **provides behavior for** `Addable` operations
|
|
|
|
2. **Different Use Cases**:
|
|
- `inher`: Declares trait relationships at trait definition time
|
|
- `impl`: Provides implementations for types (or default implementations for traits)
|
|
|
|
3. **Implementation Flexibility**: Keeping them separate allows:
|
|
- Different resolution rules for inherited methods
|
|
- Diamond inheritance handling
|
|
- Multiple inheritance from many traits in one statement
|
|
|
|
4. **Parser Benefits**: The `inher` operator clearly signals "the next trait declaration will inherit from these"
|
|
|
|
---
|
|
|
|
## Summary of Recommendations
|
|
|
|
| TODO | Recommendation | Rationale |
|
|
|------|---------------|-----------|
|
|
| **Variadic arguments** | **Don't add special syntax yet**. Use arrays for now, document `depth` as zero-arg. Consider `T...` syntax only if truly needed later. | Keeps language simple, arrays work for most cases, can add later if needed |
|
|
| **Inheritance before trait?** | **Yes, keep current requirement**. `inher` must come before `trait` definition. | Clear ordering, simpler parser, explicit dependencies |
|
|
| **Is `inher` required?** | **Yes, keep `inher` operator**. It makes inheritance explicit and unambiguous. | Clear intent, allows future extensions, parser can validate separately |
|
|
| **Replace `inher` with `impl`?** | **No, keep them separate**. They represent different relationships with different semantics. | Semantic clarity, different use cases, better tooling support |
|
|
|
|
---
|
|
|
|
## Additional Considerations
|
|
|
|
### For Variadic Arguments
|
|
|
|
If you later decide you *do* need variadic syntax, I'd suggest this progression:
|
|
|
|
**Phase 1 (Current)**: No variadic syntax
|
|
```
|
|
(-- Size) depth: // Just returns depth
|
|
(String [Stringifiable] --) printf: // Use arrays
|
|
```
|
|
|
|
**Phase 2 (If needed)**: Add typed variadics
|
|
```
|
|
(String Stringifiable... --) printf: // Zero or more Stringifiable values
|
|
```
|
|
|
|
This gives you a simple starting point with a clear upgrade path.
|
|
|
|
### For Inheritance Syntax
|
|
|
|
The current design is actually quite elegant:
|
|
|
|
```
|
|
[ ::Trait1 ::Trait2 ::Trait3 ] ::NewTrait inher
|
|
{
|
|
// Additional methods
|
|
} ::NewTrait trait
|
|
```
|
|
|
|
This clearly shows:
|
|
1. What we're inheriting from (the array)
|
|
2. That we're declaring inheritance (the `inher` operator)
|
|
3. The trait being defined (the `trait` operator)
|
|
|
|
It's verbose but crystal clear, which is good for a systems language.
|
|
|
|
---
|
|
|
|
Would you like me to add any of these design discussions to the specification document itself, or would you like to explore any of these options in more detail?
|
|
|
|
---
|
|
|
|
---
|
|
|
|
My choices for 0.6.1:
|
|
Following your suggestions:
|
|
- **Variadic arguments** - Don't add special syntax *yet*
|
|
- **Inheritance before trait?** - Yes, keep current requirement
|
|
- **Replace `inher` with `impl`?** - No, keep them separate
|
|
My own choice:
|
|
- **Is `inher` required?** - No, merge into trait operator
|
|
|
|
And for Variadic arguments do add the array of stuff that will be the current system
|