Comment

Comment by tomjakubowski

> Whereas in the functional world, you’ll have to 4 different ‘.read’ function calls with an if statement.

A good language for functional programming provides parametric polymorphism via traits or typeclasses:

    pub trait Read {
      fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>;
    }
    impl Read for std::fs::File { /* ... */ }
    impl Read for String { /* ... */ }
Then you can write a generic function like this:

    pub fn read_kilobyte<R>(r: R) -> io::Result<Vec<u8>>
        where R: std::io::Read {
      let mut buf = vec![0u8; 1024]; // vector of 1024 0s
      let nbytes = r.read(&mut buf[..])?;
      buf.truncate(nbytes);
      Ok(buf)
    }
And call it like this:

    let kb1 = read_kilobyte(File::open(...)?)?;
    let kb2 = read_kilobyte("foo bar baz quux".to_string())?;
No ifs in sight.

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton