Oh yeah, and I just realized: if traits aren't restricted to functions, you can use them to define new data, just like Racket's structs:
$deftrait foo?
new foo? 1 2 3 4 5
Here we've defined a new "struct" called foo? which has a variable number of "fields". You can then destructure it like so:
(foo? A B C D E)
This gives a much more flexible and simpler alternative to Racket's struct system, but combines it with the full power of trait inheritance. Thus, this trait system solves a huge number of problems:
You can use it to define new data. You can use it to define new behavior for data. You can use it to specify interfaces and protocols that data must conform to. You can use it as a flat/transparent wrapper to tag data...
And it's all handled in a very simple and straightforward and flexible way. And traits work extremely well with immutability too: you can "extend" a trait with more behavior and "extend" some data with more traits, simply by adding them in an immutable fashion, just like a dictionary/list/etc.
---
Also, I didn't cover "meta-traits", which are traits that can be applied to traits, since traits are first-class data like everything else. Unfortunately, I haven't yet thought of any use for such a meta-trait system...
And another thing I just realized... if I got rid of "new" and instead said that simply calling the trait defines something of that trait... then this solves the dichotomy between [] pattern matching and the type system.
To explain, [1 2 3] is expanded by the parser into (%seq 1 2 3). That is, it is a concrete implementation of the sequence trait. But I can actually combine those two... by having it instead expand to (seq? 1 2 3). And then seq? would be defined something like this:
That is, it's an abstract trait that accepts 0 or more arguments, is immutable? and orderable? and ordered?. Now, calling (seq? 1 2 3) will create a new "instance" of the trait seq? and using (seq? A B C) with pattern matching will destructure it...
Oh yeah, and I didn't mention before, but I want to provide a pattern-matchable? trait. This lets you define custom behavior when pattern matching. So then the dictionary trait could be defined like so...
While it seems fine to get rid of 'new, your reason for doing so doesn't make sense. Can't (%seq 1 2 3) be implemented as a procedure that calls (new seq? 1 2 3)?