Skip to content

Better choose API #28

Description

@ebfull

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions