digitalmars.D.announce - futures and related asynchronous combinators
- Vlad Levenfeld (18/18) Mar 27 2016 https://github.com/evenex/future/
- Eugene Wissner (5/23) Mar 27 2016 Hi Vlad,
- Vlad Levenfeld (7/35) Mar 27 2016 For things like timers, event loops and networking in my current
- maik klein (3/12) Mar 27 2016 What happens when you spawn a future inside a future and call
- Vlad Levenfeld (36/50) Mar 27 2016 I think that you are asking about what happens if you call
https://github.com/evenex/future/ I've been having to do a lot of complicated async work lately (sometimes multithreaded, sometimes not), and I decided to abstract a some patterns out and unify them with a little bit of formalism borrowed from functional languages. I've aimed to keep things as simple as possible while providing a full spread of functionality. This has worked well for me under a variety of use-cases, but YMMV of course. Anyway I've occasionally seen people on IRC asking about futures, so I thought I'd share and make this announcement. This lib depends on another lib of mine (for tagged unions and related things) which might not appeal to some but if there is demand for futures sans dependencies I can always go back and manually inline some of the templates. TL;DR: auto x = async!((y,z) => y + z)(1,2); x.await; assert(x.result.success = 3);
Mar 27 2016
On Sunday, 27 March 2016 at 07:16:53 UTC, Vlad Levenfeld wrote:https://github.com/evenex/future/ I've been having to do a lot of complicated async work lately (sometimes multithreaded, sometimes not), and I decided to abstract a some patterns out and unify them with a little bit of formalism borrowed from functional languages. I've aimed to keep things as simple as possible while providing a full spread of functionality. This has worked well for me under a variety of use-cases, but YMMV of course. Anyway I've occasionally seen people on IRC asking about futures, so I thought I'd share and make this announcement. This lib depends on another lib of mine (for tagged unions and related things) which might not appeal to some but if there is demand for futures sans dependencies I can always go back and manually inline some of the templates. TL;DR: auto x = async!((y,z) => y + z)(1,2); x.await; assert(x.result.success = 3);Hi Vlad, Are you intend to open source other parts of your work? Can I ask what are you using for your async stuff: libasync, vibe, asynchronous or something self written?
Mar 27 2016
On Sunday, 27 March 2016 at 08:16:22 UTC, Eugene Wissner wrote:On Sunday, 27 March 2016 at 07:16:53 UTC, Vlad Levenfeld wrote:For things like timers, event loops and networking in my current project I am using libasync. As for other parts of my work: I've been getting some good mileage out of a small set of generic primitives for operating on serial streams, I will probably pull them out and release them with some documentation soon.https://github.com/evenex/future/ I've been having to do a lot of complicated async work lately (sometimes multithreaded, sometimes not), and I decided to abstract a some patterns out and unify them with a little bit of formalism borrowed from functional languages. I've aimed to keep things as simple as possible while providing a full spread of functionality. This has worked well for me under a variety of use-cases, but YMMV of course. Anyway I've occasionally seen people on IRC asking about futures, so I thought I'd share and make this announcement. This lib depends on another lib of mine (for tagged unions and related things) which might not appeal to some but if there is demand for futures sans dependencies I can always go back and manually inline some of the templates. TL;DR: auto x = async!((y,z) => y + z)(1,2); x.await; assert(x.result.success = 3);Hi Vlad, Are you intend to open source other parts of your work? Can I ask what are you using for your async stuff: libasync, vibe, asynchronous or something self written?
Mar 27 2016
On Sunday, 27 March 2016 at 07:16:53 UTC, Vlad Levenfeld wrote:https://github.com/evenex/future/ I've been having to do a lot of complicated async work lately (sometimes multithreaded, sometimes not), and I decided to abstract a some patterns out and unify them with a little bit of formalism borrowed from functional languages. I've aimed to keep things as simple as possible while providing a full spread of functionality. This has worked well for me under a variety of use-cases, but YMMV of course. [...]What happens when you spawn a future inside a future and call await? Will the 'outer' future be rescheduled?
Mar 27 2016
On Sunday, 27 March 2016 at 15:10:46 UTC, maik klein wrote:On Sunday, 27 March 2016 at 07:16:53 UTC, Vlad Levenfeld wrote:I think that you are asking about what happens if you call "async" from within another "async" call. If that's the case: Short answer: No rescheduling by default. The outer future is ready as soon as the inner future has been spawned. You would still have to await the inner future separately. If you are chaining "async" calls you will want to use "next" and/or "sync" to get the rescheduling behavior you want. Long answer: It depends on how you spawn the future. A future is a passive thing. All it does, by itself, is signify a value yet to be computed. There is no constraint on how the future is to be fulfilled. You could create a future manually with "pending", in which case calling "await" on it would block forever (because the future never has "fulfill" called on it). What a function like "async!f" does is to create a future with an implied promise to fulfill that future from another thread. Let's suppose "f", internally, calls "async" to return a Future!A. Then "async!f" spawns a Future!(Future!A). The outer future is ready once "f" returns, and the inner future will be ready once the async operation launched by "f" completes. To await the final result, you might call "await.result.await", which quickly becomes awkward. To avoid this awkwardness, you should use "sync" to flatten nested futures, or "next" to automatically flatten the futures as you chain them. For example: async!f : Future!(Future!A) async!f.sync : Future!A async!({}).next!f : Future!A If you're familiar with functional design patterns, Future is a monad with "next" as bind, "sync" as join, and "pending!A.fulfill(a)" as return. If not, just remember - "sync" removes a layer of nesting, and "next" chains future calls without nesting them. Hope that helped!https://github.com/evenex/future/ I've been having to do a lot of complicated async work lately (sometimes multithreaded, sometimes not), and I decided to abstract a some patterns out and unify them with a little bit of formalism borrowed from functional languages. I've aimed to keep things as simple as possible while providing a full spread of functionality. This has worked well for me under a variety of use-cases, but YMMV of course. [...]What happens when you spawn a future inside a future and call await? Will the 'outer' future be rescheduled?
Mar 27 2016