I agree that the style that is currently in the style guide is not very good. It makes it very difficult to distinguish between type parameters and function arguments.
I much prefer this style, which is just a subtle change over the original:
fn foo<T: This,
U: That>
(a: Bar,
b: Bar)
-> Baz {
...
}
This makes it easier to see the difference between type parameters and normal parameters by placing the parenthesis in the ‘margin’ to act as a separator. It still retains the problem of having to re-indent everything each time the function name is updated, but function names are very rarely updated in any case.
I dislike the style of indenting the arguments by 4 spaces regardless of the length of the function. That places the function arguments on the same level as the function body, which can make it confusing to distinguish between the two (especially when there are no return values, or the return value appears on the same line). Example:
fn frobnicate(
a: Bar, b: Bar,
c: Bar, d: Bar) {
a.bizbaz(c.to_foobar());
d.frob(d).qux();
}
Placing the ) on its own (dedented) line does help, but it still can’t change the fact that the parameters and body are on the same line.
Niko’s example with my proposed style (and some other clean up):
fn set_var_to_merged_bounds<T: Clone + InferStr + LatticeValue,
V: Clone + Eq + ToStr + Vid
+ UnifyVid<Bounds<T>>>
(&self,
v_id: V,
a: &Bounds<T>,
b: &Bounds<T>,
rank: uint)
-> ures;
Looking at that, all one has to do to see where the type parameters, arguments, and return value start is look at the whitespace ‘margin’ on the right.