1

readability...

if !rooms
.get(&name)
.map(|turf| if let Turf::Mine = turf { true } else { false })
.unwrap_or_default()

Comments
  • 3
    After reading this I had the feeling I just finished a sudoku.
  • 2
    if let Some(room) = rooms.get(&name) && !room.is_mine() {

    //...

    }

    At this point you have to actually be trolling
  • 1
    @12bitfloat if it exists but is the wrong turf type

    then set it to the right turf type

    now you gotta also write a is_mine()!

    ---

    I see let chains got added finally, I'm gathering from that. I tried those way before but got an error wheee. happy they added it though

    ---

    also in your case if the room doesn't exist it would fail, and in mine if the room doesn't exist it will go on

    this is an initializer. so if the room doesn't exist or is the wrong type it goes on and initializes
  • 1
    @jestdotty Maybe I misunderstand but I don't think the code you posted does more than what mine does

    It's just an if (with missing body) with a combinator chain which evals to a bool, it doesn't initialize as far as I can see
  • 1
    @jestdotty > now you gotta also write .is_mine()!

    Don't be so allergic to abstractions!
  • 2
    @12bitfloat sorry I was saying it's being used as a initializer

    in mine if there's no room the if will pass as true

    in yours if there's no room the if fails as false

    matters not I guess though. I'm too bad at making sense of anything for whatever reason
  • 1
    @jestdotty If there's no room, your example should evaluate to the default value of bool which is false.

    Before let chains, I'd've done something like this:

    if !rooms.get(&name).map_or(false, |turf| matches!(turf, Turf::Mine))
  • 2
    @lorentz The boolean negation refers to the whole expression so the default gets negated too

    I think she's right on the logic... But come on, there has to be a simpler way to write this
  • 1
    @12bitfloat I didn't notice the damn !
  • 0
    So apparently I instinctively added the top-level negation without noticing that it's actually there, but I think it demonstrates another advantage of the form with an explicit boolean value that I wrote; you can lower the negation into the expression to avoid negating a boolean that you created right here (whether as a literal or via Default). The resulting statement would look something like this:

    if rooms.get(&name).map_or(true, |turf| !matches!(turf, Turf::Mine))
  • 0
    You may prefer to think of the entire expression under the negation as a unit with a distinct semantic meaning corresponding to a positive statement ("$name is a mine"), which would make top-level negation preferable, but I think in that case it's also a good idea to pull it out into a variable. Generally speaking, an expression should represent one concept. Sometimes that concept is inherently complicated to express with the tools available so it gets long, this is especially often the case with iterators, but if it has sub-concepts you want to keep intact, those should be extracted if possible.
  • 1
    idk maybe I'm smartassing over what's really a pretty trivial line by Rust standards. I write, edit, and work around way worse lines than your original every minute and they are not an arbiter of productivity. It's all fine.
  • 0
    @lorentz had me worried there for a sec that I had to actually nitpick this stuff
  • 1
    Why is there not a find function... converting a whole collection to booleans seems inefficient...

    Also I think @lorentz's if the only reasonably readable one
  • 0
    @BordedDev that "map" is probably Option::map or Result::map, the original collection is only being queried here.
  • 1
    @lorentz sooo........ it's a miss-named function? (and it's a zero or one item collection?)
  • 1
    @BordedDev Yeah, option (maybe in Haskell parlance, nullable elsewhere) is a 0..1 arity collection. Rust consistently calls this function `map`; It isn't part of a trait, but it actually corresponds to Haskell's fmap which is defined by Functor. It's used to transform (map) all of the values in a collection without affecting its structure.
  • 0
    @lorentz that's why I'm saying it should be a "find" function, since mapping a whole collection to check if a single condition is true seems highly inefficient.
  • 0
    @BordedDev well, the collection in this case is literally 1 byte larger than its potential element, so mapping it is pretty fast actually. But there's also Option::is_some_and and Option::is_none_or which are a lot more descriptive.
Add Comment