With "placement in" syntax, e.g. as replacement for Vec::new (edit: Vec::push, sorry for the confusion), it's not really possible to avoid new syntax, see this old FAQ
I remain unconvinced that we cannot simply use closures for emplacement, i.e. do this: vec.emplace(|| LargeValue { ... })
The FAQ (A12) claims that this is incompatible with fallible constructors, i.e. the new syntax allows one to write vec <- try!(run_code())
which will bail out from the current function on error, whereas vec.emplace(|| try!(run_code())
form cannot do that, obviously.
The catch here is that in order for run_code()
to be fallible, it must return a Result<T,E>
, which wraps the value we want to emplace. Well, guess where this intermediate value will be stored? That's right, - on the stack. Which defeats the whole purpose of emplacement. The vec <- try!(run_code())
form will appear to work, but will not in fact do what the programmer had intended!
What would work with arrows is this: vec <- run_code(try!(compute_argument()))
.
However computation of arguments is pretty easy to factor out of the construction expression:
let arg = try!(compute_argument());
vec.emplace(|| run_code(arg));
So... do we gain enough by adding all that placement machinery into the language, when a simple solution works nearly as well?