-
Notifications
You must be signed in to change notification settings - Fork 375
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
Using rustfmt or other formatter #410
Comments
awesome, thanks @ariard . @TheBlueMatt i'm sure you've considered this, any reason we're not using |
Personally I'm generally very much not a fan of formatters in that sometimes you want to do custom things for readability (eg if you want to manually align lines so you can easily see all the lines are the same modulo one or two chars) and they break those...is there a way to apply a formatter to just new code (ie format a commit) as a tool for those who don't want to format their code manually/want to format it their differently and get it auto-changed on checkin. Still, if people feel really strongly here, I wont stand in the way toooo much. |
Good suggestion, I'm even on this but if people less familiar with codebase really like it I think it's worth to find a middle ground |
I could see that leading to some slightly weird-looking situations, like one newly-committed line of code split into 80-character parts by the formatter, surrounded by 200-character lines on both sides 😛 Maybe a middle ground could be running the formatter every few months, so it's not too much of a burden to manually undo some of its changes (i.e. like this one, which as Matt points out, is not ideal)? Idk, it does improve readability a lot (to me) in most places. |
Concept ACK, we can still stop to use formatter if it's too much a burden, or can't we exclude some lines of it, there is no per-line granularity? |
I'm also in favor of using the |
This is blocked on either rust-lang/rustfmt#4306 (maybe) or rust-lang/rustfmt#4146 (hopefully), as we found in 425 that rustfmt just can't generate readable code for lots of things. |
My personal opinion is that it's probably not worth waiting for those issues to be fixed before integrating rustfmt. I've had issues with every code formatter that I've ever used, including rustfmt, but those issues don't outweigh the benefits, which include not having to format code manually, not needing to devote time to style issues in pull requests, enforcing a consistent style, and harmony with community best practices, since the vast majority of Rust projects use rustfmt. |
I don't know if its worth spending a ton of time debating this, but there is a tradeoff here between code readability and formatting overhead. Indeed, formatting overhead sucks, but, at least personally, I'll take code readability 100x over any formatting overhead. Of course good auto-formatting should also result in more legible code (since it is all very uniform), but in this case I think its hard to argue that rustfmt results in more readable code for many parts of our codebase (unless you have a 50-char-wide terminal, I suppose). |
I strongly believe that rust-lightning needs hard The formatting can be done incrementally, of course, but as a newer contributor I've personally found rust-lightning to be needlessly difficult to work with when it comes to code semantics and readability, and would like to tackle this issue early. Here's what I've experienced: Maximum line widthThis is what peer_handler.rs I think there's several things wrong with this:
Overly complex control flows.My personal experience working with the codebase has been:
This codebase is severely lacking intermediate variables. For example, with line 913 above, instead of having a triply nested function/macro call Another result of this extreme nesting is that closing parentheses For example, try visually finding the closing
While opening and closing delimiters can be matched with the help of an IDE, this makes PR reviews via the GitHub UI more difficult. Reducing formatting overhead with cargo watchI disagree that rustfmt adds significant overhead (assuming I'm correctly understanding Matt's usage of the term "formatting overhead"). With cargo watch you can automatically check for code format changes every time you save your changes: cargo watch -x "fmt -- --check" And only when it spits out a diff do you actually run Cargo watch can be combined with automatic clippy checks, running tests, builds etc. I've been using this recently for example: cargo watch -x "clippy --no-deps && cargo test --package lightning-net && cargo fmt -- --check && build --release" Anyways, strict Closing thoughts and suggestionsWhile my "too complex" feedback extends to beyond the scope of what I believe that the Sorry about the length of the post. I just wanted to provide a concrete argument based on actual code, but that required a lot more words than I expected. Cheers! |
I'm totally with you on overly-complex control flow in a number of places in the codebase - indeed, its a known problem and something that is being (very slowly) cleaned up as files are changed and new things are added. Sadly, in your case, the As you point out, complex control flow, too many arguments to functions, too few variables, etc are all issues that However, the specific issues you point out regarding long control flow and things falling off the screen causing you to not be able to match the end of a function call or scope while reading is made worse by rustfmt, not better. Given long functions with complicated args, rustfmt makes an absolute mess of the code and makes these problems substantially worse by placing every argument and method call on its own line, which when run on On the flip side, if large scopes and long functions are cleaned up more aggressively, rustfmt starts to provide substantially less value - now things are readable on their own without rustfmt. Again, here, rustfmt has a tendency to make things worse, not better - if the control flow were more readable to begin with, then rustfmt just makes you lose context, which as you note leads to bugs and missing issues in review quite often. |
Point taken regarding At the same time, I can understand how complicated functions involving a large number of tightly coupled parameters may not be amenable to de-nesting. If I have some extra time on a night or weekend, I'll take a stab at reorganizing the Overall, I think that if done correctly, a strict adherence to |
In general, yes, totally agree. Of course there is a limit - you want to be able to see context, I've seen many critical issues get missed in review because someone was reviewing on GitHub and only had 3 lines of context, or even because someone didn't scroll to the top/bottom of a function and missed something. Just splitting things out into separate functions doesn't always ensure you have more context - function boundaries if well defined are great, but also have substantial loss of context, especially utility functions that are there to split the code up. As with everything, there is a balance to be had.
Take a look at #1023 - parts of the code that you were explicitly pointing to above are already cleaner there, though the focus of that PR isn't just cleaning up the code its also to improve the parallelization. As always, PRs welcome.
Frankly I find that most average rust projects, even with ones that have relatively short functions with 3-4 arguments, rustfmt makes code unreadable. Nearly every time I touch a "normal" Rust project I find myself frustrated by how little context I can see on my screen, even with a vertical 4k monitor with upwards of 150-200 lines in the terminal. I find myself spending substantial amount of time scrolling up and down just to see the top of a really simple function, which makes bugs way more likely than not, in my experience. |
FWIW, for new files and new code where possible, I've been trying to keep within the 100 character limit. For example: https://github.com/lightningdevkit/rust-lightning/blob/main/lightning/src/routing/scoring.rs I loosely followed these conventions for blocks with long parameter lists: https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md That said, I also share the same concern with @TheBlueMatt about vertical code particularly within functions, though I have a higher tolerance lol. I would be curious to see if rustfmt changes any of the above files much or could be configured to match the conventions to some degree. I believe they mostly fit everything within a 100 characters with a few exceptions like recently added logging. So any other formatting may be more opinionated. |
Yeah, and I do agree that this is pretty ugly that I can see the current state of "configurability" with For example, "compressed" function arguments would match what we like and obey the 100 char limit. |
See-also rust-bitcoin/rust-bitcoin#959 (maybe we let them go first, assuming it ever happens?) and the two rustfmt issues linked towards the top of this issue that i think are still blocking this. |
Thanks for pointing me to this. Will also see if we need to open up any rustfmt issues directly / put up some PRs. Just don't want to turn it into an xkcd.com/1319 |
I was like that a long time ago, but after developing a severe case of Repetitive Strain Injury (RSI) now I will readily accept a code that is "just" 90% okay if the formatting overhead is near 0. Just try once to code with voice and you'll understand how an automatic formatter is a godsend. But I agree that this must be done carefully in an existing codebase. It's certainly possible that some code may become unreadable after applying rustfmt and needs to be rewritten/refactored. |
With the same end-goal of refactoring some part of the code base, improving code readability would be great too
Per @valentinewallace idea.
The text was updated successfully, but these errors were encountered: