ivandardi / RustbotPython

A Discord bot for the Community Rust Language server, written in Python.
MIT License
16 stars 9 forks source link

Consider formatting Iterator specially in `?eval`? #29

Open kangalio opened 3 years ago

kangalio commented 3 years ago

The situation often comes up that you want to demonstrate some iterator chain using ?eval. Directly writing the iterator yields bad results: Screenshot_20210128_113723

The obvious workaround is to collect into a vector: Screenshot_20210128_113756

However, this workaround is slightly problematic:

Perhaps there is a way to special-case the return value formatting for iterators? In the above example, the bot output could look like this:

1, 3, 5, 7, 9

Advantages:

Potential difficulties:

kangalio commented 3 years ago

In hindsight, I'm thinking this is way too much effort and too brittle for little benefit.

kangalio commented 3 years ago

Dtolnay had discovered a clever trick to emulate specialization using autoref. This trick can be applied here to provide a specialization output format for Iterators.

The final generated code looks like this:

struct Wrap<T>(T);

trait Output {
    fn output(self);
}

impl<T: Iterator> Output for Wrap<T> where T::Item: std::fmt::Debug {
    fn output(mut self) {
        if let Some(item) = self.0.next() {
            print!("{:?}", item);
            for item in self.0 {
                print!(", {:?}", item);
            }
            println!();
        }
    }
}

impl<T: std::fmt::Debug> Output for &Wrap<T> {
    fn output(self) {
        println!("{:?}", &self.0);
    }
}

fn main() { Wrap({
    // USER CODE HERE
}).output(); }

This code can presumably be minified considerably. The utility structs and traits might also have to be wrapped in a macro for hygiene, so that the user doesn't accidentally use Output or Wrap in their own code and is confused about the result.

Now, I tested this code with a few types and it yielded the correct results each time. It seems robust enough, so the "tricky to implement" concern from above is dealt with I think.

The "magic" concern is definitely still valid though, in two aspects:

  1. it may be hard to understand for bot users where the special iterator formatting is coming from
  2. users may be confused when the bot redirects them to the playground and they're greeted with a wall of funky glue code
    • this aspect could be alleviated by falling back to the simple old formatting mechanism only when sharing the playground to the user. However, this is another hack on top of a hack. Objectively speaking, it seems viable, though it kinda feels wrong

Remaining questions: