4 ms·
I'd like to nominate anything by Mara Bos (@m_ou_se) on Twitter. For example: > What's your favourite @rustlang boolean? Option<()>, Option<Option<!>>, std::it
by iudqnolq 5y ago
I'd like to nominate anything by Mara Bos (@m_ou_se) on Twitter. For example:
> What's your favourite @rustlang boolean? Option<()>, Option<Option<!>>, std::iter::Once<()>, std::fmt::Result
> tired: u16, wired: BTreeSet<BTreeSet<BTreeSet<BTreeSet<()>>>>
> What's your favourite @rustlang integer? &[()], Enumerate<Repeat<()>>, Poll<File>, *const PhantomData<usize>
@jaaaarwr> How is Vec<()> not in this poll?
> That's just the owning version of &[()], right? Why would you need to own ()s? ;)
Edit: She's also the author of inline_python!, a serious macro for interspersing code that calls python (including local variable interop), and whichever_compiles!, a joke macro that takes multiple expressions, forks the compiler (as in a fork syscall), and compiles the first one that compiles to valid rust.
- estebank 5y agoResult<(), ()> is just a spicy bool. A lot of people are on board with not using if/else and instead :) match x { true => {} false => {} }
- skrtskrt 5y ago> Result<(), ()> is just a spicy bool. EDIT: quoted wrong part of parent, ignore above > match x { true => {} false => {} } I really like this. Pattern matching syntax is great, nice to use in place of if/else as much as possible
- iudqnolq 5y agoI disagree. There's a clippy lint against pattern matching on bool. I also think Result has the connotation of "success or error". Plus it's always annoying when a function returns an error that doesn't implement Error and I have to wrap/replace it to make it integrate with the standard error handling ecosystem. There's a nice alternative though, which is empty struct errors. #[derive(Debug, thiserror::Error, displays of::Display)] /// Frobnicating the foo failed. struct FrobError; The advantage is the standard advantages types use, i.e. if I want to propagate it I know this specific zero sized type has a specific meaning. It'll also show a nice message if you print it.
- estebank 5y agoI like matching on bools on the same cases where someone wouldn't write braces around the body in C: whenever the corresponding expressions keep you under the line length. For example: let plural = match cases.len() > 1 { true => "s", false => "", }; Of course, you'd more likely have something like let prefix = match cases.len() { 0 => "no values".to_string(), 1 => "a value".to_string(), n => format!("{} values", n), };
- iudqnolq 5y agoInteresting. I prefer writing that as an if/else on one line when rufmt lets me, but I see your point.
- rabidferret 5y agolet plural = match cases.len() { 1.. => "s", 0 => "", }; ;P
- cyphar 5y agoThat's not the correct plural rule in English, you'd want let plural = match cases.len() { 0 | 2.. => "s", 1 => "", }; or something (though to be fair the original code snippet also handled "0" incorrectly -- should be "cases.len() != 1").
- iudqnolq 5y agoAnd also to be fair you probably don't want to be hardcoding English pluralization rules.
- rabidferret 5y agoI used to maintain a library which actually tried to implement proper English pluralization rules. I can confirm you don't want to do that.
- 5y ago
- OJFord 5y agoHang on aren't we conflating two things in this thread? Or you quoted the wrong half of GP's comment perhaps? You can pattern match on an actual `bool`; if you use `Result<(), ()>` instead you'll have to match on `Ok(_)`/`Err(_)`, which is bad because one of your Boolean values is an 'error' now, and also because which one is is up to you (to remember)!
- Tuna-Fish 5y ago> whichever_compiles!, a joke macro that takes multiple expressions, forks the compiler (as in a fork syscall), and compiles the first one that compiles to valid rust. This is inspired.
- iudqnolq 5y agoIt's definitely worth reading the full thread if you haven't > Did you know you can just fork() the @rustlang compiler from your proc_macro? :D > This is, of course, a horrible idea. > Unfortunately rustc is multithreaded and fork() only forks one thread. We'll just assume the other threads weren't doing anything important. > In today's rustc, this means we're only missing the main thread in the fork. But that one was only going to call exit() after joining our thread anyway, so not very important. It just means the process always exits with a success status. So instead we grep the output for "error". Any my favorite reply: > Is this a rust implementation of autoconf? https://mobile.twitter.com/m_ou_se/status/1368632701448818691 https://mobile.twitter.com/m_ou_se/status/136863270144881869...
- samus 5y agoSimilar debates exist in all programming languages with algebraic data types. `Either<(), a>` vs. `Maybe a` and stuff. Category-theoretically, they are the same of course. But in non-strict languages `Either<(), a>` allows another opportunity to hide an `undefined`: `Left undefined`.
- iudqnolq 5y agoI find it beautiful that HashSet<T> in Rust is a thin wrapper around HashMap<T, ()>. I'm glad it's a wrapper, though. I wouldn't like it if everyone had to write `HashMap<u16, ()>` and so on and know which methods still made sense.