On 19 Dec 2013, at 1:26 am, Benjamin Striegel <[email protected]> wrote:

> Hello rusties, I was reading a blog post by Joe Armstrong recently in which 
> he shows off his favorite tiny Erlang program, called the Universal Server:
> 
> http://joearms.github.io/2013/11/21/My-favorite-erlang-program.html
> 
> I know that Rust doesn't have quite the same task communication primitives as 
> Erlang, but I'd be interested to see what the Rust equivalent of this program 
> would look like if anyone's up to the task of translating it.
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev

Universal server... done! https://gist.github.com/bjz/e4d536c63900960c9e15

Here’s the code:

> extern mod extra;
> use extra::comm::DuplexStream;
> 
> enum Request<T, U> {
>     Request(T),
>     Become(extern fn(T) -> U),
> }
> 
> struct Client<T, U> {
>     priv stream: DuplexStream<Request<T, U>, U>
> }
> 
> impl<T: Send, U: Send> Client<T, U> {
>     fn request(&self, x: T) -> U {
>         self.stream.send(Request(x));
>         self.stream.recv()
>     }
> 
>     fn become(&self, f: extern fn(T) -> U) {
>         self.stream.send(Become(f));
>     }
> }
> 
> fn start_server<T: Send, U: Send>() -> Client<T, U> {
>     fn failing<T, U>(_: T) -> U {
>         fail!("Server not yet initialised.")
>     }
> 
>     let (client, server) = DuplexStream::<Request<T, U>, U>::new();
>     spawn(proc() {
>         let mut f = failing::<T, U>;
>         loop {  // Need iterators for DuplexStreams!
>             match server.recv_opt() {
>                 Some(Request(x)) => server.send(f(x)),
>                 Some(Become(g)) => f = g,
>                 None => break,
>             }
>         }
>     });
>     Client { stream: client }
> }
> 
> fn factorial(n: u64) -> u64 {
>     match n {
>         0 => 1,
>         n => n * factorial(n - 1),
>     }
> }
> 
> fn main() {
>     let client = start_server();
>     client.become(factorial);
>     println!("{}", client.request(50));
> }

This was isn’t as elegant the Erlang example due to Rust’s static type system 
and/or lack of local type inference.

You might be interested in my port of Erlang’s `gen_server` that I’ve been 
working on[1]. It needs to be fixed up to work with the new updates to 
std::comm though, so it won’t compile.

~Brendan

[1] https://gist.github.com/bjz/c2b0ce9362cf748b4193

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to