this post was submitted on 01 Feb 2024
65 points (91.1% liked)

Programmer Humor

18255 readers
480 users here now

Welcome to Programmer Humor!

This is a place where you can post jokes, memes, humor, etc. related to programming!

For sharing awful code theres also Programming Horror.

Rules

founded 1 year ago
MODERATORS
 

signal-2024-02-01-19-47-41-855

all 17 comments
sorted by: hot top controversial new old
[–] [email protected] 45 points 5 months ago* (last edited 5 months ago) (2 children)

The collect's in the middle aren't necessary, neither is splitting by ": ". Here's a simpler version

fn main() {
    let text = "seeds: 79 14 55 13\nwhatever";
    let seeds: Vec<_> = text
        .lines()
        .next()
        .unwrap()
        .split_whitespace()
        .skip(1)
        .map(|x| x.parse::().unwrap())
        .collect();
    println!("seeds: {:?}", seeds);
}

It is simpler to bang out a [int(num) for num in text.splitlines()[0].split(' ')[1:]] in Python, but that just shows the happy path with no error handling, and does a bunch of allocations that the Rust version doesn't. You can also get slightly fancier in the Rust version by collecting into a Result for more succinct error handling if you'd like.

EDIT: Here's also a version using anyhow for error handling, and the aforementioned Result collecting:

use anyhow::{anyhow, Result};

fn main() -> Result<()> {
    let text = "seeds: 79 14 55 13\nwhatever";
    let seeds: Vec = text
        .lines()
        .next()
        .ok_or(anyhow!("No first line!"))?
        .split_whitespace()
        .skip(1)
        .map(str::parse)
        .collect::>()?;
    println!("seeds: {:?}", seeds);
    Ok(())
}
[–] [email protected] 6 points 5 months ago

Yeah I was trying to do something like reading the first line by getting an iterator and just looping through the other lines normally, since first line was kind of a special case but it got messy quick. I realized halfway that my collects were redundant but couldn't really simplify it. Thanks

[–] [email protected] 2 points 4 months ago* (last edited 4 months ago)

Also, anyhow::Context provides a convenient way to turn Option and Result> into anyhow::Result

Like this:

use anyhow::Context;

// to my understanding it's better to 
// specify the types when their names 
// are the same as in prelude to improve
// readability and reduce name clashing
fn main() -> anyhow::Result<()> {
    let text = "seeds: 79 14 55 13\nwhatever";
    let seeds: Vec = text
        .lines()
        .next()
        .context("No first line!")?     // This line has changed
        .split_whitespace()
        .skip(1)
        .map(str::parse)
        .collect::>()?;
    println!("seeds: {:?}", seeds);
    Ok(())
}

Edit: line breaks

[–] Schmeckinger 18 points 5 months ago (1 children)

You can't really blame that on rust.

[–] [email protected] 0 points 5 months ago (1 children)

Yeah ngl it's very ugly. But hey as long as it works it's not stupid amirite?

[–] [email protected] 6 points 5 months ago

Rust borrows a lot of it's design from functional programming languages like Haskell, which has its good and bad. You could also choose to implement this behavior iteratively like typical C programs, but that tends to be ugly in other ways.

Personally, I've grown fond of the functional style. You see it in other places too, like the higher order functions in JavaScript. What's good about them in Rust is you still get amazing performance due to zero-cost abstraction. Trying to implement it yourself would likely be slower, so use them any chance you get.

[–] GeniusIsme 2 points 5 months ago (1 children)

Show the alternative, I'll have a good laugh.

[–] [email protected] 2 points 4 months ago* (last edited 4 months ago) (1 children)

It's Nim, but I have no idea why you can't do this in Rust:

var seeds = lines[0].split(": ")[1].splitWhitespace().mapIt(it.parseInt)

Full solution: https://codeberg.org/Archargelod/aoc23-nim/src/branch/master/day_05/solution.nim

[–] GeniusIsme 1 points 4 months ago

Ahh, it is the same thing. Rust example surely has some cruft, but mostly for the better. I'm sure not all of it is needed.