Poor formatting with combination of arithmetic and dot
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 1.1k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 24
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;
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No source file or test is named. Start by reproducing the four examples with rustfmt and tracing the formatter entry point that handles arithmetic expressions and method calls; done means the output makes the parenthesized expression and the method-call receiver unambiguous, as shown in the proposed formatting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100