5 ms·
My understanding of the issue (which is shallow at best) is that it's a battle between a prefixing keyword or sigil which has the problem of causing the reader
by kbenson 7y ago
My understanding of the issue (which is shallow at best) is that it's a battle between a prefixing keyword or sigil which has the problem of causing the reader to scan back and forth in the statement when chaining multiple items, which sucks), or a postfixing keyword or sigil, with dot notation for a keyword to help parsing (and everyone seems to dislike the overloading of the dot notation for this). Ignoring sigils, I think the chosen solution is the lesser of two evils.
That said, I think a postfixing sigil would have been much better. It seems an important enough thing to denote that a bit of special syntax is called for, and the more unique the better.
- 0815test 7y ago> That said, I think a postfixing sigil would he been much better. It seems an important enough thing to denote that a bit of special syntax is called for They can still introduce a sigil later, if the .await syntax turns out to be common enough in code that the long keyword hinders readability. This is how it was done with the try!(...) feature, which now uses ? as a sigil. But as the article points out, pure sigils are a scarce resource so .await might well be the best way to go anyway.
- Nican 7y agoFor example, on C#, I sometimes have to do: var value = (await (await startRequest()).GetBody()).Root; While the Rust syntax would make this a little more clear, I do not think it is a dealbreaker.
- jcelerier 7y agothis makes my eyes bleed
- zeroDivisible 7y agoWhy?
- entropicdrifter 7y agoBecause you have to read from the inside-out instead of left to right or right to left, most likely.
- kibwen 7y agoFor ease of comparison, here's how that would look with syntax akin to Rust's choice: var value = startRequest().await.getBody().await.Root;
- mdpopescu 7y agoPlease don't do that. I had to look several times to rewrite it as var temp1 = await StartRequest(); var temp2 = await temp1.GetBody(); var value = temp2.Root; which is instantly grokked.
- steveklabnik 7y agoThis is a great example of why syntax and semantics can't be separated. This works great in GC'd languages, but in Rust, these two things may not be equivalent. With the distinction between owned and temporary values, this may change the lifetime of what stuff is in scope and when. This is reduced a bit with non-lexical lifetimes, but it's not, strictly speaking, actually equivalent.
- nemothekid 7y agoI think this is a good example to show people who are on the fence about postfix then. I haven't felt strongly about postfix, but this is an eye opener for me.
- hombre_fatal 7y agoIt's a better case for showing how to use .map().
- steveklabnik 7y agoYeah, I think the trick is that the theory and practice might be the same. And usually, it's the other way around; spreading it out makes it work, whereas it may not otherwise. For example: fn main() { let world = gives_string().split(" ").next(); println!("{:?}", world); } fn gives_string() -> String { String::from("hello world") } This will fail because the String is temporary, and we're trying to get a reference to it (via split), and so it would be deallocated at the end of the line, being a use-after-free. This, however, compiles: fn main() { let world = gives_string(); let world = world.split(" ").next(); println!("{:?}", world); } fn gives_string() -> String { String::from("hello world") } We're shadowing 'world', but the underlying String now lives to the end of main, so everything works, no more use-after free. I think before I'd want a good real-world example of where doing the multi-line thing goes wrong before I'd want to make an argument that this is why postfix is better.