Nice to see a "brain dump" as someone who learned many languages and can easily relate with most of the issues the author faced.
But I take issue with this:
// Obviously good and easy to read
return a*(1.0-t) + b*t;
// Obviously bad and hard to read
return add(mul(a, 1.0 - t), mul(b, t));
Sorry, but the first one is not obviously good, it's just what you're used to (the second one is indeed bad).
Here's what I would consider obviously good :) for the objective reason that it does not require difficult to track implicit rules about operator precedence:
1, - t, * a, + (t, * b)
I invented this syntax myself :) but it's extremely obvious once you know how it works.
It should be clear that this is similar to concatenative languages, where you push values onto a stack then apply operations on the stack. The `,` is used for pushing to the stack, basically. But then, it also allows you to "mix" more standard function notation into it... so when you write `a b` that means calling the `a` function with `b` as an argument (think LISP).
Now putting everything together
1, - t
Should read as `1 minus t` as `- t` is the function `-` being called with one value from the stack, `1`, and one from the "function call" (as if it was LISP `(- 1 t)`).
Next:
1, - t, * a
Reads as "1 minus t times a" and has no ambiguity: the result of `1, - t` is the first argument to `
`, the second argument is `a`, so you get LISP's `( (- 1 t) a)` but reads much more naturally.
Finally, at the end, for readability, we use parens to group the final part of the equation:
1, - t, * a, + (t, * b)
Hopefully it's obvious what happens now?
Does anyone like this form of expression or is just me? I tried to mix the best of LISP with the best of FORTH :) and I really like this.