A common pattern in Rust is to use an inner function with fewer generic inputs to contain most of the outer function's implementation without the cost of monomorphization.
fn with_str(s: impl AsRef<str>) {
fn inner(s: &str) {
// lots of code
}
inner(s.as_ref());
}
This pattern feels pretty "noisy" and easy to resist. It adds a level of indentation to the entire function. Long function signatures have to be basically repeated. And the "first" line is (conventionally) moved to the bottom.
My understanding is that using a closure serves the same purpose, but Rust is currently not very efficient at reducing inherited generics in closures. (?) And closures mostly still have the same issues stated above.
My idea is to create a syntactic sugar for this:
fn with_str(s: impl AsRef<str>) {
let s = s.as_ref();
fn_boundary! // (straw man)
dbg!(s);
// lots of code
}
You can put the marker fn_boundary!
anywhere as a statement. The remainder of the block "captures" the environment through a generated function invocation. You're code can be written in normal execution order and you don't have to write a function signature or add indentation. I suppose you could add attributes to the marker and they will be on the generated function.
And it isn't just useful for generics. There are scenarios where the first one or two lines of code are a good candidate to be inlined independently.
Maybe it is equivalent to wrapping the remainder with move || {..}()
. And so maybe this could be a proc macro, but would a compiler feature be significantly faster? I'd like to hear more informed opinions.