News for hackers. Stuff that matters.
Re:Rust Weird Expressions by iudqnolq on Friday May 14, 2021 @12:06PM (#27155776)
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.

Re:Rust Weird Expressions by Tuna-Fish on Friday May 14, 2021 @03:29PM (#27158707)
> 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.

Re:Rust Weird Expressions by iudqnolq on Friday May 14, 2021 @03:50PM (#27158951)
It'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/136863270144881869...

Re:Rust Weird Expressions by estebank on Friday May 14, 2021 @12:30PM (#27156147)
Result<(), ()> is just a spicy bool.

A lot of people are on board with not using if/else and instead :)

    match x {
        true => {}
        false => {}
    }
Re:Rust Weird Expressions by skrtskrt on Friday May 14, 2021 @12:36PM (#27156236)
> 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

Re:Rust Weird Expressions by iudqnolq on Friday May 14, 2021 @12:46PM (#27156389)
I 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.
Re:Rust Weird Expressions by estebank on Friday May 14, 2021 @12:57PM (#27156535)
I 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),
    };
Re:Rust Weird Expressions by spullara on Friday May 14, 2021 @02:41PM (#27158125)
My favorite thing about internationalization is that some languages have 6 different translations for different amounts.
Re:Rust Weird Expressions by rabidferret on Friday May 14, 2021 @01:11PM (#27156758)

    let plural = match cases.len() {
        1.. => "s",
        0 => "",
    };
;P
Re:Rust Weird Expressions by cyphar on Friday May 14, 2021 @01:17PM (#27156853)
That'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").
Re:Rust Weird Expressions by iudqnolq on Friday May 14, 2021 @01:39PM (#27157228)
And also to be fair you probably don't want to be hardcoding English pluralization rules.
Re:Rust Weird Expressions by rabidferret on Saturday May 15, 2021 @08:01AM (#27164445)
I used to maintain a library which actually tried to implement proper English pluralization rules. I can confirm you don't want to do that.
Re:Rust Weird Expressions by iudqnolq on Friday May 14, 2021 @01:06PM (#27156659)
Interesting. I prefer writing that as an if/else on one line when rufmt lets me, but I see your point.
Re:Rust Weird Expressions by OJFord on Friday May 14, 2021 @01:03PM (#27156632)
Hang 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)!
Re:Rust Weird Expressions by samus on Tuesday May 18, 2021 @05:43AM (#27192768)
Similar 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`.
Re:Rust Weird Expressions by iudqnolq on Tuesday May 18, 2021 @11:42AM (#27196176)
I 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.