namable_closures

Crates.ionamable_closures
lib.rsnamable_closures
version0.2.4
sourcesrc
created_at2018-07-19 02:33:13.754531
updated_at2018-07-26 04:26:27.30296
descriptionProvides types and macros to create namable closure types
homepage
repositoryhttps://github.com/earthengine/namable_closures.git
max_upload_size
id74978
size61,177
(earthengine)

documentation

https://docs.rs/namable_closures

README

Make Rust Closure Types Namable

This crate provides some types and macros that can create closures which type is namable.

Update

2018-07-25 v0.2.2 Add Recursion support (experimential)

Usage

To use, as usual,

#[macro_use] extern crate namable_closures;
use namable_closures::Closure;
fn main() {
    let add_ten:Closure<i32,(i32,),i32> = closure!(state=10 => move |i| i+*state);
    println!("{}",add_ten.stable_call_once(1)); //11
}

There are 5 variants of the types, each of them have 3 type variables. The State variable correspond to the captured environment of a closure. The Input must be a unit or tuple type, correspond to the arguments of the closure. The Output is the return type of the closure.

In additional to letting you name the closure type, the function body cannot capture any variable by default, so all captures must be explicit.

Macro Grammar Struct
closure!(state=exp => |x,y| body(x,y,state)) Closure
closure!(state=exp => move |x,y| body(x,y,state)) ClosureOnce
closure!(mut state=exp => |x,y| body(x,y,state)) ClosureMut
closure!(mut state=exp => move |x,y| body(x,y,state)) ClosureOnce (with mutable state)
closure!(ref state=exp => move |x,y| body(x,y,state)) ClosureRef
closure!(ref mut state=exp => move |x,y| body(x,y,state)) ClosureRefMut

DO NOT USE Closure or ClosureMut unless you know what you are doing

In most cases you will need the move keyword, this will let your closure own the state. If you don't need to own the state, make sure your state expression represents a &T (for Closures) or &mut T (for ClosureMut) types.

Nightly only features

A shadow set of traits was defined to use before fn_traits and unboxed_closures features being stablized. Use of them is a bit ugly:

let myclosure:Closure<i32,(),i32> = closure!(s=&0 => || *s);
fn1_expect_closure(||myclosure.stable_call());
let myclosure:ClosureRef<(),(i32,),i32> = closure!(s=&() => |i| i);
fn2_expect_closure(|i|myclosure.stable_call((i,)));
let myclosure:ClosureRef<(),(i32,i32),i32> = closure!(s=&() => |i,j| i+j);
fn3_expect_closure(|i,j|myclosure.stable_call((i,j)));

If you don't mind having to compile in nightly Rust, you can add the following to cargo.toml:

[dependencies.namable_closures]
features = ["nightly"]

Now you can write the following:

let myclosure:Closure<i32,(),i32> = closure!(s=&0 => || *s);
fn1_expect_closure(||myclosure());
let myclosure:ClosureRef<(),(i32,),i32> = closure!(s=&() => |i| i);
fn2_expect_closure(|i|myclosure(i));
let myclosure:ClosureRef<(),(i32,i32),i32> = closure!(s=&() => |i,j| i+j);
fn3_expect_closure(myclosure);
Commit count: 15

cargo fmt