Yep, this is basically the style I'm using in luvit's new package manager
(luvit/lit).  It's gets a little tricky around error handling, but most
that can be handled in the spawn and parallel helpers.
On Feb 12, 2015 2:50 AM, "Connor McKay" <[email protected]> wrote:

> I discovered Luvit about a month ago, and have become very excited about
> the possibilities it holds. I had never used Lua before, but I am quickly
> falling in love with its clean, minimalist design (what Javascript
> could/should have been), and its coroutines. I've read a few posts on this
> list discussing alternate ideas for an API that would break away from the
> callback-hell of Node, and I wanted to see if it was possible to create an
> API that would perfectly mimic synchronous operations, while still allowing
> asynchronous parallelism and background work. Below is a minimal example
> (that doesn't actually use Luvit itself):
>
> callbacks = {}
>
> function event_loop()
>   while (#callbacks > 0) do
>     time = os.time()
>     for i, v in ipairs(callbacks) do
>       if time >= v[1] then
>         table.remove(callbacks, i)
>         v[2]()
>         break
>       end
>     end
>   end
> end
>
> -- Callback style functions
>
> function set_timeout(seconds, cb)
>   table.insert(callbacks, {os.time() + seconds, cb})
> end
>
> function load_name(cb)
>   set_timeout(3, function() cb("Bob") end)
> end
>
> -- Synchronous style functions
>
> function pause(seconds)
>   local co = coroutine.running()
>   set_timeout(seconds, function()
>     assert(coroutine.resume(co))
>   end)
>   coroutine.yield()
> end
>
> function get_name()
>   local co = coroutine.running()
>   load_name(function(name)
>     assert(coroutine.resume(co, name))
>   end)
>   return coroutine.yield()
> end
>
> -- Parallelization functions
>
> function spawn(func)
>   coroutine.wrap(func)()
> end
>
> function parallel(...)
>   local args = {...}
>   local done = 0
>   local co = coroutine.running()
>   function task_done()
>     done = done + 1
>     if done == #args then
>       assert(coroutine.resume(co))
>     end
>   end
>   for i, func in ipairs(args) do
>     coroutine.wrap(function()
>       func()
>       task_done()
>     end)()
>   end
>   coroutine.yield()
> end
>
> -- The main program itself
>
> function main()
>   print("Hello main, pause 2")
>   pause(2)
>
>   print("Getting name...")
>   local name = get_name()
>   print("Name was " .. name)
>
>   parallel(function()
>     print("Parallel 1, pause 3")
>     pause(3)
>     print("Done parallel 1")
>   end,
>   function()
>     print("Parallel 2, pause 3")
>     pause(3)
>     print("Done parallel 2")
>   end)
>
>   print("Done parallel, in main")
>
>   spawn(function()
>     print("In spawn 1, pause for 5 seconds")
>     pause(5)
>     print("Done with spawn 1")
>   end)
>
>   spawn(function()
>     print("In spawn 2, pause for 5 seconds")
>     pause(5)
>     print("Done with spawn 2")
>   end)
>
>   print("Main pause 2")
>   pause(2)
>
>   print("Done main")
> end
>
> coroutine.wrap(main)()
>
> event_loop()
>
> This is little more than a proof of concept at the moment, but I thought
> it might be useful in the API design discussion.
>
> Thanks,
> Connor McKay
>
> --
> You received this message because you are subscribed to the Google Groups
> "luvit" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"luvit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to