3 ms·
Regarding the futures: These are futures that you only can synchronously wait on (like what is currently available as std::future). However there is no possibi
by Matthias247 12y ago
Regarding the futures:
These are futures that you only can synchronously wait on (like what is currently available as std::future). However there is no possibilty to attach continuations that run when the value of the future is available. E.g. like the C++17 concurrency proposals, C#'s `Task` type or Javas `CompletableFuture`. These all rely on storing some kind of callback or closure inside the Future.
That's not easy in Rust because it leads to situations where ownership is no longer obvious. The continuation might need to capture objects that are still needed locally (so you need something similar to Rc<RefMut<SomeThing>> ). In the most simply example's the continuation needs a mutable reference to the Future itself whereas the Future-producing operation also has one. And if you have possibilities that the continuation could run on another thread/executor than the calling thread (which is possible with the other languages) things get more complicated.
Regarding asio. You don't have to deep dive very much here:
Simply consider boost::asio::async_write(socket, buffer, [](error_code, bytes_transferred) { /* Do something with the result
*/ });
You need some mutable objects (like socket or the object that contains socket) locally AND you need acccess to them in your continuation. This will only work "safely" with garbage-collected or ref-counted types and these do still not seem to work for interfaces.
- ekidd 12y agoInterfaces can sometimes be tricky, especially if you're also working with lifetimes, because there's no way to write "T<'a>" for a generic type. There are are few other gotchas like this. Some of these will get better once associated types land. But yeah, trying to simultaneously manage interfaces, lifetimes and callbacks sometimes requires serious Rust knowledge—and at least for now, you may run into hard barriers. You need some mutable objects (like socket or the object that contains socket) locally AND you need access to them in your continuation. If you're planning on writing to objects from inside a continuation, while you also write to them from your main code as well, you're going to have to think things through pretty carefully in any language, or else the two writers will stomp on each other. Rust has lots of tools for locking and controlling access. This will only work "safely" with garbage-collected or ref-counted types and these do still not seem to work for interfaces. I'm not quite sure if I understand the problem you're describing. I can definitely share mutable objects between threads, and I can do so using abstract traits (aka "interfaces"). Here's a runnable example using Rust's "play" server: http://is.gd/bQOY3o http://is.gd/bQOY3o I had to use a "box" here, because that's the easiest way to store objects of varying size that implement a specific interface. Experienced Rust developers may be able to simplify this a bit. Anyway, is this what you were thinking about? Or did you mean something else?
- ekidd 12y agoThis will only work "safely" with garbage-collected or ref-counted types and these do still not seem to work for interfaces. I'm not quite sure if I understand the problem you're describing. I can definitely share mutable objects between threads, and I can do so using abstract traits (aka "interfaces"). Here's an example: https://gist.github.com/emk/acdf3ab9c79ba1abe6d2 https://gist.github.com/emk/acdf3ab9c79ba1abe6d2 I had to use a "box" here, because that's the easiest way to store objects of varying size that implement a specific interface. Experienced Rust developers may be able to simplify this a bit. Is this what you were thinking about? Or did you mean something else?
- Matthias247 12y agoThe part that your example is missing is that one side uses the trait object (Common) whereas the other side uses the "normal" type (Foo or Bar) or another trait object view of the object. And the be able to cast between such "smart-boxed" types after you acquired one of them. See the disucssion a little bit below for examples with Rc (it's the same problem but within a thread instead of between threads).