Right now the path down a Choose style decision tree is formed by signaling with booleans over the channel, which is not (space) efficient. Further, you must use macros to avoid having to do a bunch of annoying compositions to select the branches you want.
Here's an alternative API which unfortunately requires Rust nightly, but (somehow) works:
#![feature(optin_builtin_traits)]use std::marker::PhantomData;traitChooseFrom{}impl<Q>ChooseFromforFinally<Q>{}impl<P,Q:ChooseFrom>ChooseFromforChoose<P,Q>{}structFinally<Q>(PhantomData<Q>);structChoose<P,Q:ChooseFrom>(PhantomData<(P,Q)>);structCompound<A,B>(PhantomData<(A,B)>);traitNotSame{}implNotSamefor .. {}impl<A> !NotSameforCompound<A,A>{}traitChooser<T>{fnnum() -> usize;}impl<P,Q:ChooseFrom>Chooser<P>forChoose<P,Q>{fnnum() -> usize{0}}impl<P>Chooser<P>forFinally<P>{fnnum() -> usize{0}}impl<P,S,Q:ChooseFrom + Chooser<S>>Chooser<S>forChoose<P,Q>whereCompound<S,P>:NotSame{fnnum() -> usize{1 + Q::num()}}impl<P,Q:ChooseFrom>Choose<P,Q>{fnchoose<S>(&self) -> usizewhereSelf:Chooser<S>{Self::num()}}fnmain(){let a:Choose<usize,Choose<isize,Choose<String,Finally<()>>>> = Choose(PhantomData);println!("{:?}", a.choose::<String>());}Basically, in theory you can just call chan.choose::<Protocol>() and it will signal over the channel that you're switching to that protocol using a single number. Perhaps if there's a monomorphization recursion limit anyway, we could use u8 or u16 instead of usize to make the discriminant as small as possible. (Safety note: if the number wraps around it will cause memory safety violations. Perhaps we can use peano numbers to encode a maximum limit here.)
Also, I believe with inlining LLVM will completely optimize this away.
Right now the path down a
Choosestyle decision tree is formed by signaling with booleans over the channel, which is not (space) efficient. Further, you must use macros to avoid having to do a bunch of annoying compositions to select the branches you want.Here's an alternative API which unfortunately requires Rust nightly, but (somehow) works:
Basically, in theory you can just call
chan.choose::<Protocol>()and it will signal over the channel that you're switching to that protocol using a single number. Perhaps if there's a monomorphization recursion limit anyway, we could use u8 or u16 instead of usize to make the discriminant as small as possible. (Safety note: if the number wraps around it will cause memory safety violations. Perhaps we can use peano numbers to encode a maximum limit here.)Also, I believe with inlining LLVM will completely optimize this away.