Hacker News new | ask | show | jobs
by trane_project 1035 days ago
Not sure if I disagree but your example is terrible. Let patterns in if statements greatly simplify things. The alternatives are a lot more convoluted.

See example from code I wrote this week: https://github.com/trane-project/trane/blob/master/src/data/...

Without the let, I'd have to do a match statement followed by an unwrap just to check if a field in an enum is set.

2 comments

You are confusing shortening with simplifying. The `if let` syntax is an unnecessary addition to the language so it is by definition an added complexity. Of course the resulting code is much easier to read and I definitely agree that it's a nice feature but I wouldn't pretend it made the language simpler, just more comfortable once you already know it.
You imply simple = better, complex = worse, but this isn't such a simple relationship.

If you keep removing redundant constructs from languages, you will end up with something pure and minimal like the lambda calculus or turing machine. But these aren't easy to program in!

Languages are an interface for humans. If the code density is too low or too high, it becomes difficult to for people reason about the programs. Concepts like readability and expressiveness are important, but end up requiring some level of complexity.

Exactly, it's a smooth trade off curve from lambda calculus all the way to Haskell with 30 language extensions enabled.

You could learn lambda calculus in an afternoon, but then spend a month writing a single complex algorithm. You could spend 5 years learning Haskell, and then write the most powerful system in a couple minutes.

There's a sweet spot somewhere between those two, and Rust is definitely near it.

Exactly what I had in mind, thank you for explaining it so succinctly!
Just to elaborate on the "just more comfortable once you already know it" part, I think a lot of Rust is optimized (willingly or not) for the "once you know it" use case.

Which, while it might arguably hurt adoption, is a good value proposition, since you spend a lot more time knowing the language than not knowing it.

Now, not everything is always perfect, and I agree that the `if let` is not the most useful part of the language, as it drives pointless discussions about when to use it vs match (some people prefer the esthetics of match even when an if let can be used, others prefer to use a if let whenever possible). This redundancy apart, the construct doesn't eat any mental energy once you know it. The same can't be said of many of C++ quirks (initialization rules, member-initializer list in constructors, the rule of five)

> Without the let, I'd have to do a match statement followed by an unwrap just to check if a field in an enum is set.

You... would not?

An `if let` trivially desugars to a `match`.

    if let <pat> = <expr> {
        ...
    }
becomes

    match <expr> {
        <pat> => {
            ...
        }
        _ => {}
    }
See my example. I am trying to extract the value of an optional field in the enum. That's where the unwrap comes in.
What I wrote up is the spec-defined desugaring of a single-branch `if let`, aside from desugaring bugs there should be no counter-example.

The snippet you link to should be replaceable by something along the lines of

    match &passages.asset {
        TranscriptionAsset::Track {
            artist_name: Some(artist_name),
            ..
        } => {
            metadata
                .entry(ARTIST_METADATA.to_string())
                .or_default()
                .push(artist_name.clone());
        }
        _ => {}
    }
no `unwrap` needed. I don't know where you got that idea.