Description
In a number of cases, rustfmt
produces poor formatting in code that has a combination of arithmetic infix operators and method calls (using dot). I've collected a few examples that I hope will be helpful.
Example 1
In this case, it's difficult to see what is wrapped in the parentheses starting after 0.5 *
and what the .scalar_sum
applies to:
fn main() {
let dnlml = Array1::from_shape_fn(ln_hyperparams.len(), |i| {
0.5 * (self
.covfunc
.deriv_covariance(ln_hyperparams, train_inputs, i)
* &W)
.scalar_sum()
});
}
It would be much easier to understand with something like this:
fn main() {
let dnlml = Array1::from_shape_fn(ln_hyperparams.len(), |i| {
0.5 * (
self.covfunc.deriv_covariance(ln_hyperparams, train_inputs, i)
* &W
).scalar_sum()
});
}
Example 2
This example is similar. It's quite hard to understand, largely because it's not clear where the corresponding closing parenthesis is for the opening parenthesis after c *
. At first glance, the indentation makes it look like the -
and +
are happening at the same level as the *
, but in fact, they are inside the right-hand-side expression of the *
.
fn main() {
dVdi.slice_mut(s![.., output_index, .., input_index])
.assign(
&(c * (iR
.column(input_index)
.into_column()
.dot(&lb.view().into_row())
- (&t * &tlb_view.into_column()).reversed_axes()
+ tlbdi2)),
);
}
It would be much easier to understand with something like this:
fn main() {
dVdi.slice_mut(s![.., output_index, .., input_index])
.assign(
&(c * (
iR.column(input_index).into_column().dot(&lb.view().into_row())
- (&t * &tlb_view.into_column()).reversed_axes()
+ tlbdi2
)),
);
}
Example 3
This example isn't quite as bad as the others, but it's somewhat difficult to see what the .sum_axis
is being applied to. The indentation suggests that it's at the same level as the *
, but in fact, it's applied to the parenthesized expression containing the *
.
fn main() {
{
let tdX: Array1<_> = -0.5
* t
* (&iR.t()
* test_covariance
* (-2. * &inv_sq_len_scales_i - 2. * &inv_sq_len_scales_i))
.sum_axis(Axis(0));
}
}
It would be clearer with something like this:
fn main() {
{
let tdX: Array1<_> = -0.5
* t
* (&iR.t()
* test_covariance
* (-2. * &inv_sq_len_scales_i - 2. * &inv_sq_len_scales_i))
.sum_axis(Axis(0));
}
}
or this:
fn main() {
{
let tdX: Array1<_> = -0.5
* t
* (
&iR.t()
* test_covariance
* (-2. * &inv_sq_len_scales_i - 2. * &inv_sq_len_scales_i)
)
.sum_axis(Axis(0));
}
}
Example 4
This is another similar example. It's not clear what the .dot
is being applied to. (Is it applied to an expression containing the *
, or is it applied to the expression on the right-hand-side of the *
?)
fn main() {
{
let dSds: Array2<_> = r2
* (2. * i2SpW.dot(&m_minus_z.as_column()).dot(&m_minus_z.as_row())
- Array2::<f64>::eye(D))
.dot(&i2SpW)
- 2. * L * &dLds;
}
}
It would be clearer like this:
fn main() {
{
let dSds: Array2<_> = r2
* (2. * i2SpW.dot(&m_minus_z.as_column()).dot(&m_minus_z.as_row())
- Array2::<f64>::eye(D))
.dot(&i2SpW)
- 2. * L * &dLds;
}
}
or this:
fn main() {
{
let dSds: Array2<_> =
r2 * (
2. * i2SpW.dot(&m_minus_z.as_column()).dot(&m_minus_z.as_row())
- Array2::<f64>::eye(D)
).dot(&i2SpW)
- 2. * L * &dLds;
}
}