Recommendations around "undesirable" extra turbofish arguments

I'm writing a library with a function whose signature could be expressed as:

fn parse_file<T, P: AsRef<Path>>(path: P) -> Result<T>

I would prefer it if users of the library could invoke this function as just parse_file::<TypeOfT>(path), but, with the signature above, they'd have to at minimum include an additional underscore argument for the type of path.

One alternative would be to rewrite the signature as:

fn parse_file<T>(path: impl AsRef<Path>) -> Result<T>

This enables single-argument turbofishes, but it also (I believe) makes it impossible to use the turbofish to disambiguate the path type; moreover, this only works in Rust 1.63 and up.

Which option is more convenient for users? Is either approach recommended over the other? Is there possibly another approach to consider? Help me decide.

But isn't it exactly what you are looking for? To be clear, you can't have optional generic arguments: you either have to always include or always omit the second one.

I personally avoid impl Trait in argument position: I find it unnecessary and inconsistent. I would go with solution #1, the function with two type parameters.

1 Like

But isn't it exactly what you are looking for? To be clear, you can't have optional generic arguments: you either have to always include or always omit the second one.

Fair, but I was holding out hope that optional generic arguments may be an option somehow. It's not easy learning a language without a comprehensive spec.

1 Like

If it were me, I would avoid making people use turbofish altogether.

use std::{io::Result, path::Path};

fn parse_file<T, P: AsRef<Path>>(path: P) -> Result<T> {
    todo!()
}

fn main() {
    let x: Vec<u8> = parse_file("path/to/file.txt").unwrap();
}

This way you, you have less line noise (something like parse_file::<Vec<u8>>(...) is pretty syntax-heavy), and half the time type inference will make it so you don't even need to write the Vec<u8> annotation.

Otherwise, the fn parse_file<T>(path: impl AsRef<Path>) option is your only real choice if you want to still have turbofish. Most developers use rustup, so keeping up with stable or lagging 1-2 releases behind is fairly painless.

Somehow I doubt there is a correlation between how "comprehensive" a language's specification is and the quality of their learning material. Otherwise, weighing in with over 1800 pages and being a full ISO standard, C++20 would have some of the best trained programmers in the world.

Newbies learning the language would be much better served by something like The Book or The Rust Reference.

4 Likes