Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[style] Maximum line length #1785

Merged
merged 8 commits into from
Apr 9, 2019
Merged

[style] Maximum line length #1785

merged 8 commits into from
Apr 9, 2019

Conversation

odow
Copy link
Member

@odow odow commented Jan 16, 2019

This one is going to be contentious (looking at @chriscoey).

Ref issue: #1780
Ref previous PR: #1781

@odow odow mentioned this pull request Jan 16, 2019
40 tasks
@codecov
Copy link

codecov bot commented Jan 16, 2019

Codecov Report

Merging #1785 into master will increase coverage by 13.61%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff             @@
##           master    #1785       +/-   ##
===========================================
+ Coverage   69.57%   83.18%   +13.61%     
===========================================
  Files          30       41       +11     
  Lines        3957     6270     +2313     
===========================================
+ Hits         2753     5216     +2463     
+ Misses       1204     1054      -150
Impacted Files Coverage Δ
src/shapes.jl 40% <0%> (ø)
src/_Derivatives/conversion.jl 98.07% <0%> (ø)
src/_Derivatives/linearity.jl 97.82% <0%> (ø)
src/_Derivatives/sparsity.jl 97.46% <0%> (ø)
src/_Derivatives/types.jl 100% <0%> (ø)
src/_Derivatives/_Derivatives.jl 100% <0%> (ø)
src/_Derivatives/reverse.jl 93.47% <0%> (ø)
src/_Derivatives/coloring.jl 97.97% <0%> (ø)
src/_Derivatives/topological_sort.jl 100% <0%> (ø)
src/_Derivatives/forward.jl 97.61% <0%> (ø)
... and 21 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 350e948...fbf94e2. Read the comment docs.

@chriscoey
Copy link
Contributor

chriscoey commented Jan 16, 2019

IMO harder to read and archaic given modern code viewers and editors (wrapping), but I won't put up a fight.


#### TODO: Line breaks
Following the Google style guide for [line length](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#32-line-length)
in python, keep lines under an 80 character limit.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a contentious point so we need to give our own motivation and not just defer to the google style guide.
My thinking is that for consistency, we need some guideline on line length. 80 characters is a reasonable pre-existing convention.

Copy link
Member Author

@odow odow Jan 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we just make this a recommendation. What about:

Our foremost goal is to maximize code readability. Very long line lengths are hard to read since they either require horizontal scrolling, or are wrapped uncontrollably by a text editor. Thus, where possible, keep line lengths under 80 characters (an arbitrary, but pre-existing convention). We make an exception for lines in which manually breaking the line over multiple lines is worse for readability.

Examples include

  • URLs
  • path names
  • long string constants not containing whitespace

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"wrapped uncontrollably by a text editor" is pretty unconvincing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please just make it a recommendation. I don't plan to start enforcing line lengths in any packages I author. though for packages that aren't mine, I will follow the surrounding style.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mlubin it is also "consistent" to not have line limits at all

@joaquimg
Copy link
Member

Maybe we should consider that we use verbose names for everything. We also have many parametric types. And 4 spaces tabs...
I don't like that limit.
I would like to vote for a larger limit at least.
Why 80? wasn't that chosen in the 1930's with no widescreens?

@chriscoey
Copy link
Contributor

@joaquimg makes a great point I hadn't even thought of.

though I prefer no line limit, I would be OK with a "target/soft maximum line length" of n characters (n = 120 maybe?). if the limit is arbitrary anyway, we may as well be a little soft about it. then n chars is a goal, and clearly a line of 1.5*n chars is too long and should in good conscience be broken up. guidelines like "verbose variable names" require judgment and subjectivity, so why not line lengths too?

the code is littered with ugliness like https://github.com/JuliaOpt/MathOptInterface.jl/blob/f4db9518c49a85b70f72043f01a2bce93d44d981/src/Test/contlinear.jl#L1482 where with a target line length of 80 chars we would be allowed to just keep it on the same line of ~85 chars.

@chriscoey
Copy link
Contributor

chriscoey commented Jan 17, 2019

i want to avoid feeling as though the style guide is too totalitarian. it's not cute. i see no reason to perpetuate old python style doctrines.

finally, i will make another plug for recommending semantic line breaking for long comments and print messages (and the same idea can be applied when breaking up long lines of code into coherent chunks).

@blegat
Copy link
Member

blegat commented Jan 17, 2019

Even on modern screens, it still makes sense to use 80 characters because we might split our screen to edit multiple files at the same time and 80 characters is better for readability.
Note though that PEP-8 allows to use 100 as limit (https://www.python.org/dev/peps/pep-0008/#maximum-line-length)

Some teams strongly prefer a longer line length. For code maintained exclusively or primarily by a team that can reach agreement on this issue, it is okay to increase the nominal line length from 80 to 100 characters (effectively increasing the maximum length to 99 characters), provided that comments and docstrings are still wrapped at 72 characters.

By the way, for this reason, this is the Python limit recorded by wikipedia

@odow
Copy link
Member Author

odow commented Jan 17, 2019

the code is littered with ugliness like

    obj = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0, 1.0], [x, y]),
                                   0.0)

True, that's not very nice. A better way (to my eyes) is:

    obj = MOI.ScalarAffineFunction(
        MOI.ScalarAffineTerm.([2.0, 1.0], [x, y]), 
        0.0)

Breaking things up into smaller lines makes each statement easier to read. Consider:

    obj = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0, 1.0], [x, y]), 0.0)
    obj = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0, 1.0], [x, y], 0.0))

@mlubin
Copy link
Member

mlubin commented Jan 17, 2019

@chriscoey the reference on semantic line breaks is specifically for text. What do semantic line breaks mean for code?

@chriscoey
Copy link
Contributor

chriscoey commented Jan 18, 2019

the code is littered with ugliness like

    obj = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0, 1.0], [x, y]),
                                   0.0)

True, that's not very nice. A better way (to my eyes) is:

    obj = MOI.ScalarAffineFunction(
        MOI.ScalarAffineTerm.([2.0, 1.0], [x, y]), 
        0.0)

agreed with @odow, that looks nicer. so why don't we recommend how to break up lines, so that this outcome results? in particular, 4 spaces indenting only.

all throughout the code we have things like:

function Base.copy(set::Union{Reals, Zeros, Nonnegatives, Nonpositives,
                              GreaterThan, LessThan, EqualTo, Interval,
                              SecondOrderCone, RotatedSecondOrderCone,
                              GeometricMeanCone, ExponentialCone,
                              DualExponentialCone, PowerCone, DualPowerCone,
                              PositiveSemidefiniteConeTriangle,
                              PositiveSemidefiniteConeSquare,
                              LogDetConeTriangle, LogDetConeSquare,
                              RootDetConeTriangle, RootDetConeSquare,
                              Integer, ZeroOne, Semicontinuous, Semiinteger})
    return set
end

whereas it would be more consistent to use 4 spaces indenting and write

function Base.copy(set::Union{
    Reals, Zeros, Nonnegatives, Nonpositives,
    GreaterThan, LessThan, EqualTo, Interval,
    SecondOrderCone, RotatedSecondOrderCone,
    GeometricMeanCone, ExponentialCone,
    DualExponentialCone, PowerCone, DualPowerCone,
    PositiveSemidefiniteConeTriangle,
    PositiveSemidefiniteConeSquare,
    LogDetConeTriangle, LogDetConeSquare,
    RootDetConeTriangle, RootDetConeSquare,
    Integer, ZeroOne, Semicontinuous, Semiinteger
    })
    return set
end

I'm fine with soft line length limits if it is accompanied by consistent indenting practices. though i agree with @joaquimg and think 80 chars is too small given that variable and function names etc have to be verbose now.

@mlubin
Copy link
Member

mlubin commented Jan 18, 2019

so why don't we recommend how to break up lines, so that this outcome results?

That's a good point. We don't do this consistently now. I would look to a few code autoformatting tools autopep8, gofmt, and clang-format for how they align function calls and other lists of things that overflow a line.

@joaquimg
Copy link
Member

Recommendations on how to break lines would be great!
Softer limit in 80 might be good also, allowing to go to 100 sometimes. (Of course I’d like more columns ;D )

Copy link
Member

@mlubin mlubin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been putting off looking at this because I don't enjoy debating about line lengths, but the suggestions are pretty reasonable. If we cite an existing autoformatter for people to experiment with if they're unsure then I think we're covered.

@odow
Copy link
Member Author

odow commented Apr 8, 2019

Okay, I've removed the contentious points. I'm in favour of merging this so we can move past the discussion.

@mlubin
Copy link
Member

mlubin commented Apr 9, 2019

@joaquimg @blegat PTAL.

@chriscoey Your major objection of not having providing guidelines for how to break a line is now mostly addressed. https://yapf.now.sh/ seems to provide a reasonable point of reference to the extent that julia syntax overlaps with python syntax. What do you think?

@joaquimg
Copy link
Member

joaquimg commented Apr 9, 2019

Looks good.

@chriscoey
Copy link
Contributor

looks good.

aside: would be nice to have a Julia version of YAPF

@odow odow merged commit 903821b into master Apr 9, 2019
@odow odow deleted the od/line_length branch April 9, 2019 15:50
@odow
Copy link
Member Author

odow commented Apr 9, 2019

Merged. Anyone wanting to re-ignite the debate can make a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants