4 ms·
So we now have |&:| |&mut:| |:| at declaration-site and an optional move at use-site, in addition to obfuscating hashfn: |&String| -> uint to ei
by frowaway001 12y ago
So we now have
|&:|
|&mut:|
|:|
at declaration-site and an optional
move
at use-site, in addition to obfuscating
hashfn: |&String| -> uint
to either
<F>(hashfn: F) where F : FnMut(&String) -> uint
// "FnMut(&String) -> uint" is "syntactic sugar for "<'a> FnMut<(&'a String,), uint>"
or
hashfn: &mut FnMut(&String) -> uint
I really want to believe that this is a great success at the technical level, because from a UI point of view this is a disaster.
- wycats 12y agoSo for what it's worth, this blog post is mostly a technical deep dive for people who are very interested in the full details. From a UI perspective, I (and many others, including core team member Aaron Turon) have argued successfully that the vast majority of these details should be inferred from usage. So if you try to mutate something in a closure, the closure will adopt that requirement. If you want to capture a value by reference, you won't also be allowed to move the closure off of the stack. In other words, the rules for closures will follow intuitively from the regular ownership rules, and you will never, in normal usage, have to be explicit about any of this. This blog post was intended to explain in excruciating technical detail how it all works under the hood, and could have been clearer about the intended usage.
- kibwen 12y agoAs mentioned in the blog post, I'm hopeful that the awful |&mut:| and |&:| and |:| can be completely removed with greater inference capabilities. I'll be speaking with nmatsakis soon about exactly what needs to be done to make this a priority for 1.0. Likewise, the `move` keyword should be possible to infer in many cases (though I honestly don't mind it very much). Finally, I'm actually not bothered about the type of a closure being written as `FnMut(blah)` instead of `|blah|`, because that syntax was always a bit line-noisy in type position anyway. The bottom line is simply that closures in a low-level systems programming language present a daunting design challenge that is hard to appreciate until you've wrestled with the domain. There is no one-size-fits all here that does not result in compromises that make closures essentially useless for this niche. The best that we can do is reduce down to as few knobs as possible (Rust closures are still a bit less expressive than C++ lambdas) and lean on inference to have the compiler Do What I Mean.