A minor issue that trips me up regularly is the fact that unary operators (except @) will bind to an entire expression, even if they're directly in front of a bracketed subexpression. That is, I expect $(input.type).toUpper to parse as `$`(input.type).toUpper, but instead it seems to be parsed as `$`(input.type.toUpper). It's easy to work around (($input.type).toUpper works), but I get it wrong pretty much every time.
I doubt it's worth changing since it would probably break things, but I'm curious if other folks run into this, and if there's a reason for the behavior.
Many programming tutorials would say that it's better to use parentheses when needed than to try to remember the operator precedence. And, as we have UFCS, you may invoke it as input.type.`$`.toUpper() or toUpper($input.type), to prevent this problem.
And as I can remember, type is a reserved word, so maybe it shouldn't be used as a name.
If you don't like the dollar, use a wrapper:
template toStr(x: untyped): untyped = $x
toStr(input.type).toUpper
You need to use additional brackets.
(($input.type).toUpper)