3 ms·
With syntax questions, it can help to get very concrete. There's a few different bits of syntax in this post, what is it you find clunky?
by steveklabnik 1y ago
With syntax questions, it can help to get very concrete. There's a few different bits of syntax in this post, what is it you find clunky?
- kstrauser 1y agoNot the person you were replying to, but for (auto l : logger) { l.log(data); } bent my brain for a moment. `logger` is a list of loggers to send data do? Oh, no, it's either 0 or 1 loggers. Rust's `if let` syntax maps much more closely to how I think about it. I guess if this becomes idiomatic C++ then it'd start looking perfectly normal to everyone, but it still seems odd. For instance, I don't think I could ever bring myself to write Python like this, even if it worked: def do_something(data, logger=None): for l in logger: l.log(data)
- steveklabnik 1y agoThat makes sense! What's funny is, I went to go write the equivalent Rust code: struct Logger; impl Logger { fn log(&self, _: &str) {} } fn do_something(data: &str, logger: Option<Logger>) { for l in logger { l.log(data) } } fn main() { let logger = Some(Logger); let data = "foo"; do_something(data, logger); } and rustc actually warns about this: warning: for loop over an `Option`. This is more readably written as an `if let` statement --> src/main.rs:8:14 | 8 | for l in logger { | ^^^^^^ | = note: `#[warn(for_loops_over_fallibles)]` on by default help: to check pattern in a loop use `while let` | 8 - for l in logger { 8 + while let Some(l) = logger { | help: consider using `if let` to clear intent | 8 - for l in logger { 8 + if let Some(l) = logger { | I was actually going to say "I've never seen folks in Rust write out for loops this way, even though you can" and I suspect this lint has something to do with that! I think this is most useful in generic contexts, I agree that I would not write this exact code this way because it does feel weird, if you know you have an Option, if let is the way to go. But if you're writing code over generic iterators, it can be nice that it exists.
- masklinn 1y ago> I think this is most useful in generic contexts And to build other iterators e.g. std::iter::once is a trivial wrapper around an Option::Some.
- kstrauser 1y agoHah! I've internalized rustc and Clippy. Good job, team! Yeah, I don't hate it. The semantics aren't wrong, either: an Option has 0 payload items or 1. It still feels wrong to me in ways I can't fully explain.
- PaulDavisThe1st 1y agoAll true but consider writing templates/generic code, where "logger" might be a std::optional or a std::list/vector/whatever. Same syntax, different types. Pre-C++26 you'd need a specialization for std::optional, now you don't.
- kstrauser 1y agoFair point, but my imagination’s failing me at the moment. What kind of function would accept something where Optional makes sense and also a list/etc.? I’m not asking to dispute. I want to be enlightened!
- PaulDavisThe1st 1y agoAnything that might accept either (0 or 1 of something) or (0 to N of something).