rust-lang / rustfmt

Format Rust code
https://rust-lang.github.io/rustfmt/
Apache License 2.0
6.02k stars 889 forks source link

A configuration option for code golfing #4876

Closed wooster0 closed 3 years ago

wooster0 commented 3 years ago

I think it'd be nice if rustfmt had one simple compressed or similarly named configuration option that basically squeezes Rust code together as much as anyhow possible for code golfing where you need to achieve the smallest possible size of source code. This means no newlines, no spaces, no nothing wherever possible. Currently I pretty much need to do this manually by hand for all my https://code.golf solutions. Things like rustfmt solution.rs --config tab_spaces=0 do help but the output is not optimal. Here's an example:

fn main() {
    for i in 1..101 {
        let s = if i % 15 == 0 {
            "FizzBuzz"
        } else if i % 5 == 0 {
            "Buzz"
        } else if i % 3 == 0 {
            "Fizz"
        } else {
            println!("{}", i);
            continue;
        };
        println!("{}", s);
    }
}
rustfmt fizz.rs --config compressed=true

The result should be:

fn main(){for i in 1..101{let s=if i%15==0{"FizzBuzz"}else if i%5==0{"Buzz"}else if i%3==0{"Fizz"}else{println!("{}",i);continue;};println!("{}",s);}}

I believe apart from code golfing there are other use cases too.

I'm however not talking about things like turning println!("{}", "hello"); into println!("hello");. Such optimizations are out of scope.

ayazhafiz commented 3 years ago

I would be interested to know what other use cases you have in mind.

I think from a formatter implementation's perspective, like that of rustfmt, this is relatively tedious (if not difficult) to implement because you have to handle all of the cases where the usual (hence default) case is starkly different.

I wonder if it may easier to develop a processing tool that does this for you. Indeed it seems to me that all whitespace can be removed except a space that follows an ident and a character admissible as a character in an identifier.

wooster0 commented 3 years ago

I would be interested to know what other use cases you have in mind.

As another use case this could be one quick way of improving transmission speed of .rs files in general. They can then be decompressed by running the formatter with the default configuration. Indeed, I think there can be cases like this where some developer sends some possibly big .rs to another developer and to improve transmission speed this configuration option could be integrated into an automated process. There is many ways of compression and this can be one of them. Now you might say this is negligible but it depends and also I believe there should be this goal of really making Rust available everywhere, even in places with very poor transmission speeds. It might sound niche but I believe if this exists there will be some infrastructure, somewhere, in some place where people have found this to be a useful addition into their workflow. The compressed version is always going to transmit faster and performance is performance. Things add up.

I think from a formatter implementation's perspective, like that of rustfmt, this is relatively tedious (if not difficult) to implement because you have to handle all of the cases where the usual (hence default) case is starkly different.

I expected it to be rather easy to do seeing that there's already a pretty good foundation like tab_spaces=0 which then basically just needs to be tweaked here and there to omit things like newlines. I might try it myself some time. I could be wrong.

ayazhafiz commented 3 years ago

Fwiw, here is a simple program that performs this golfing-like compression: https://gist.github.com/ayazhafiz/d56ff8334b83d2ddbe91104251f6ddc8. Maybe it will be of some use to you if rustfmt does not support this.

calebcartwright commented 3 years ago

Thanks for sharing your idea! I can certainly appreciate the desire and benefit for automated tooling to support your use case. However, that doesn't fit within rustfmt's goals and objectives, and would be best suited to a separate tool/script so I'm going to close this accordingly.

As for why:

rustfmt's purpose is to reformat code according to the Rust Style Guide, and the rustfmt config options are to give folks some flexibility for individual pieces of the Style Guide they really dislike (e.g. spaces vs tabs). rustfmt is not intended to be an open ended formatting platform to apply the rewrite/pretty-printed formatting approach with completely different style paradigms. We also can't justify the increased maintenance and support burden on the rustfmt team for such things that are sharply outside our scope.

I could definitely envision other users benefiting from your ask though, so it might make for a fun little community tool that could be distributed through crates.io!