Skip to content

Instantly share code, notes, and snippets.

@eholk
Created July 18, 2012 23:40
Show Gist options
  • Select an option

  • Save eholk/3139720 to your computer and use it in GitHub Desktop.

Select an option

Save eholk/3139720 to your computer and use it in GitHub Desktop.
Pipe syntax extensions

Here are some ideas to make working with pipes easier.

This one combines the receive and the match with some sugar to handle moving the next state out of the message enum. This also hides the implementation of the message format from the programmer.

fn client_follow(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = switch(bank, follow! {
        ok -> connected { connected }
        invalid -> _next { fail ~"bank closed the connected" }
    });

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    switch(bank, follow! {
        money(m) -> _next {
            io::println(~"Yay! I got money!");
        }
        insufficient_funds -> _next {
            io::println(~"someone stole my money");
        }
    });
}

This is the same thing, but we've pushed the thing we receive on into the macro.

fn client_follow(+bank: bank::client::login) {
    import bank::*;

    let bank = client::login(bank, ~"theincredibleholk", ~"1234");
    let bank = recv_alt! {
        bank {
            ok -> connected { connected }
            invalid -> _next { fail }
        }
    }

    let bank = client::deposit(bank, 100.00);
    let bank = client::withdrawal(bank, 50.00);
    recv_alt! {
        bank {
            money(m) -> _next {
                io::println(~"Yay! I got money!");
            }
            insufficient_funds -> _next {
                io::println(~"someone stole my money");
            }
        }
    }
}

The nice thing about that is that we can combine in with n-ary select.

fn two_clients(+client1: one::client::connected,
               +client2: two::client::connected) {
    recv_alt! {
        client1 {
            one::something(a) -> _next {
                #debug("got %? from one", a);
            }
        }
        client2 {
            two::things(thing1, thing2) -> next {
                #debug("got %? and %? from two", a, b);
                // say thanks
                thank_you(next);
            }
            two::nothing -> next {
                fail ~"two has nothing";
            }
        }
    }
}

These three examples can all live together as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment