Skip to content

Poor formatting with combination of arithmetic and dot #3551

Open
@jturner314

Description

@jturner314

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;
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions