Hi,

Right now we use no delimiter at all to separate multiple trait bounds for a single type variable:

fn foo<T: Ord Eq Hash>(...) {...}

Originally we thought to use commas, but inserting commas into the list creates an ambiguity between the comma that separates type parameters, as illustrated here:

fn foo<T: Ord, Eq, Hash, U: Hash, V>(...) {...}

Marijn and I hashed through all kinds of delimeters and failed to find one, and hence he settled on spaces. It seemed like a good idea at the time.

However, over time, I have found that this syntax is very hard for me to parse, visually speaking. Moreover, Patrick recently observed that there is an ambiguity when the trait names are multi-component paths:

fn foo<T: Ord ::Eq>(...) {...}

Does this indicate one bound `Ord::Eq` or two bounds `Ord` and `::Eq`? The current fix for this is to make the tokenizer treat `id::` differently from `id ::` (note the separating space in the latter example). The first is 1 token. The second is 2 tokens. Actually, I think this behavior already existed, and I can't remember why—I think it had something to do with the flexible treatment of keywords that we used to have. @brson, do you remember?

Anyway, it was proposed on IRC today that we could do something like this instead:

fn foo<T:Eq>(..) {...} // One bound is the same
fn foo<T:(Ord, Eq, Hash)>(...) {...} // Multiple bounds require parentheses

I find this visually appealing. It's easier for my eye to read, particularly if the bounds are complicated.

I know it's a syntax change, and we're trying to avoid those, but I thought I'd throw it out for a wider audience to ponder, particularly as it would eliminate a rather surprising whitespace dependency.



Niko
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to