Given the snippet due to @zackw:
let crunched = raw .> |m| m * alpha .> filter(|e| e > 0.01) .> ...;
It is hard to tell whether to interpret this as:
let crunched = raw .> (|m| m * alpha) .> filter(|e| e > 0.01) .> ...;
or:
let crunched = raw .> |m| m * (alpha .> filter(|e| e > 0.01) .> ...);
If you require parenthesis, then it is not an infixl 1 operator (1 is the lowest precedence in Haskell, l means left associative).
UFCS in the form of <Type as Trait>::fun(recv, args..) is itself a rarely used syntax, but Type::fun(recv, args..) is not. The first syntax is included to be consistent and uniform, which I think a language should be. I want to avoid ad-hoc rules. Once you’re in method syntax mode, I think you should be able to stick with it. The edit distance from recv.fun(args..) to recv.Type::fun(args..) is lower than that to Type::fun(recv, args..) and so it disturbs flow less.
Well yes, if you write it like foo.Arc then it is unclear what it means. But when you write foo.Arc::clone()
it is considerably clearer because there is a path separator. Also, if you want to invoke the field of a type as a function, you have to write (val.field)(args..).
It is the same order as normal method application, so I don’t see why it is unintuitive. The normal syntax is foo.clone(), but Arc::clone(&foo) is just used to highlight the fact that this is an Arc being copied.
The syntax iter.flatten() being ambiguous when you have two different traits with the same method name is a problem which manifests all the time when things are added to the standard library traits.
The syntax recv.<path::to::Trait>::method(args..) (if we can make that work…) is also useful because it allows you to call and import in one go, there’s no need to put a use path::to::Trait; in there.