And at the very least, Tangent has done exceptionally well in its original goal of being a learning experience and a prototype. While it's fresh in my memory, some post-mortem like review:
Good Stuff
Phrases - This has a few parts; infix parameters, explicit identifiers, juxtaposition as application... This is 'what makes your language different?'. It was very powerful, elegant, intuitive. What else do you want?
Order of Operation inference - I personally never encountered woeful mis-inference. It wasn't super slow. It allowed certain syntaxes that were pleasingly unencumbered by decoration.
Multiple Dispatch - Especially with phrases, this had little downside, while freeing programmers from the 'to specialize you must sub-class' bindings.
Structural Typing - Allowed a certain flexibleness when doing design that was unfortunately lessened by free functions. Still, it seems the way to go.
Goose Types - And being able to put a 'normal' class hierarchy ontop of the type system with a mere keyword is elegant and useful.
Multiple Inheritance - No headaches when actually implementing it (beyond constructor vs invariant fights). I still think this will be a boon once more OO is done with the system.
Bad Stuff
No Community - No input, no people actually using the language pushing for quality or certain features, or just debating the utility of some ideas.
The Runtime - it was easy to implement, but took a little time with certain concepts, and the major source of performance issues. Plus there's a few little things I forgot, or did a shortcut with that are awkward now. It should've gone to the CLR (at least indirectly) as the original concept envisioned.
Too much backwards compatibility concerns - Originally, C# was to be more integrated. This provided a few too many constraints on design and too much demand on the naive way about how it should be implemented.
Tuples - Annoying, special case sort of constructs.
Visibility - The language tended towards 'classes are just records' style design, which didn't need or rely on visibility too much. Protected becomes kinda moot once inheritance acts oddly. And visibility mismatches created not a few type-mismatch bugs.
Generic Replacement - The implementation of generics replaces (or actively binds) instances into parameters rather than just referencing them. Big, ugly. Generics themselves are still of dubious utility.
Idealism around certain bits - Types really should know where they are declared. Scopes should be smarter about saying what things should be. A dozen other little things.
Little separation between instance generators, type classes, and type constructors - This one is inherited from C, but it becomes more apparent during implementation just how broken the idea of using a single concept to describe 3 separate purposes.
No 'abstract type' for operations - In the OO world, there's the concept of abstract types. 'This type can do X, Y, and Z'. Functions lack an analogous concept. 'My parameters can do (or must be able to do) these ops.' Dynamic languages kinda get away with it by just doing the operations. Type inference models can do that via that path. Originally, operators were going to be members (ala Java) and thus an abstract class could imply what operators worked. Tangent unfortunately needed that concept, but it was not included in design.
And next week I am on a cruise. Some nice R&R time to consider what I'd like to work on. Maybe more Tangent, maybe a new 'with lessons learned' implementation, maybe another go around at my fantasy 4x game idea. We'll see then.