Advises needed to improve namable_closures


#1

I am implementing the recursion feature for nameable closures. In development I passed the following test:

    #[test]
    fn test_fac() {
        let fac:ClosureRec<(),(i32,),i32> = 
            closure_rec!(me.state=() => ref |i| 
                if i==0 {1} else {me.stable_call((i-1,)) * i}
            );
        assert_eq!(fac.stable_call((10,)),3628800);
    }
    #[test]
    fn test_fib() {
        let fib:ClosureRec<(i32,i32),(i32,),i32> = 
            closure_rec!(me.state=(1,1) => ref |i| {
                let (i0,i1) = me.state;
                match i {
                    0 => i0,
                    1 => i1,
                    n => me.call_with_state((i1,i0+i1), (i-1,))
                }                
            });        
        assert_eq!(fib.stable_call((10,)),89);
        assert_eq!(fib.state, (1,1));
    }

Things to note:

  • me is a variable name only, not a special word. It can be any legal identifiers.
  • state is a fixed field name, and is public to allow access from the body.
  • The ref keyword in front of the closure parameter block indicate that the self referencing variable me in the body is a reference to the closure itself. Without this the value will be moved to the body. Alternatively you can use ref mut to indicate mutable reference, or just mut to indicate it is a mutable value.
  • call_with_state is an insteresting API on the namable closures. It allows you to “mutate” the state without actually mutating anything. The above code demostrates it.

Now I need advises on the above. Do you thing I can do better?

The naming and grammar issue

Right now there are 5 different namable closure types you can use:

function accepts state in struct type name
&state &state Closure
&mut state &mut state ClosureMut
&state state ClosureRef
&mut state state ClosureRefMut
state state ClosureOnce

They are named under the usage of the closure! macro. However, I can now see that at least one of them (Closure, unfortunately the easiest one) is redundent: it didn’t add functionality to a ClosureOnce that have a reference State value. Yes, you can implement Fn and FnMut to it; but as references are Copy, you can do the same thing for ClosureOnce.

The other type ClosureMut is not the case. I have a post in the internals forum about this, but before any language changes we are not able to colapse ClosureMut with ClosureOnce, as there is no way to implement FnMut on top of a ClosureOnce when the State is not Copy.

So, we have 4 different cases to handle. But I am not very happy with there name right now. How would you like to name them and what grammar would you prefer? My dear user, I want to hear from you!


#2

You need to make use of the functionality yourself.

Most want stable so have no use for your crate. Your then competing with custom written function-objects, these will always be able to offer more. So you only have convenience and simplicity to temp someone not to use their own function-object.


#3

Good advise.

Actually I am working on an rewrite of tokio_socks5, once it is good enough I will publish as an pratical code example.