Hi all,
I have just created a new crate namable_closures This will solve some problems we have with closures right now, without requiring any further language supports:
- Not able to name a family of "compatible" closures. For example
|a| a+captured
should be compatible with|a| a-captured
ifcaptured
is the same type, but in fact they don't have the same type so we cannot put them in the same position. - Traits are unsized, and the
FnXXX
trits are the only thing we know about a specific closure, this makes it hard to put closures in containers that requires its contents to beSized
. - The default closure behavour is to capture all variables appear in the body, and there is no way to control what to be captured.
This crate resolve the above by introducing some types, and use macros to simplify usage. See the following example:
#[macro_use] extern crate namable_closures;
use namable_closures::Closure;
fn main() {
let add_ten:Closure<i32,(i32,),i32> = closure!(state, i, i+*state, 10);
println!("{}",add_ten(1)); //11
}
In the above example the closure have a Sized
type that can be used later. The type Closure<i32,(i32,),i32>
means:
- When called, the state is called by reference
- The type of the state is
i32
(the first type parameter) - It accepts a single parameter typed
i32
(the singleton tuple) - The return type is
i32
(the last type parameter)
The macro closure!
accepts 4 pieces:
- A variable name for the state
- A tupple pattern or single variable name for the input argument
- The body of the closure, can use any variable in the state or arguments, but not from the environment
- An expression to create the (initial) state value. If you have any variable to be captured from the environment, put them here
There are other variants depends on the use case. Check the documents for more information.
Feedback
Please enter the repository and raise an issue if you have anything to tell. Code reviews, advises, features requests and most importantly, bug reports are appreciated.
Future work plans
- Improve the macros
- Improve documentation
- Add recursion support. Use similar technologies this is possible, but I have to find a way to access this feature from the function body easily.