I experimented a bit (my Lua is a bit rusty) and it seems that async
callback styles can be easily wrapped in coroutine styled code:
Taking fs.basic.lua:
---
fs.readFile("README.markdown", function (err, data)
p("on_read_file", {err=err,data=data})
if (err) then return end
fs.writeFile("test", data, function (err)
p("on_write_file", {err=err})
if (err) then return end
fs.unlink("test", function (err)
p("on_unlink2", {err=err})
if (err) then return end
end)
end)
end)
---
converted into coroutine code:
---
local function script()
local err, data = fs.readFileCoro("foo.lua")
p("on_read_file", {err=err,data=data})
if err then return end
local err = fs.writeFileCoro("test", data)
p("on_write_file",{err=err})
if err then return end
local err = fs.unlinkCoro("test")
p("on_unlink2",{err=err})
end
local coro = coroutine.create(script)
coroutine.resume(coro);
---
The wrappers are simple:
---
function fs.writeFileCoro(path, data)
local coro = coroutine.running()
fs.writeFile(path, data, function(err)
coroutine.resume(coro, err)
end)
return coroutine.yield()
end
---
So it's actually really not hard to chose between styles already - so I am
less obnoxious about the direction of Luvit regarding callbacks vs.
coroutines as I can already chose pretty easily my style of writing.
When several tasks need to get spawned at once this isn't too difficult to
achieve as well:
---
local function script2()
local coro = coroutine.running()
local data1, data2
local err1, err2
fs.readFile("foo.lua", function(err, data)
err1, data1 = err, data
coroutine.resume(coro)
end)
fs.readFile("foo.lua", function(err, data)
err2, data2 = err, data
coroutine.resume(coro)
end)
coroutine.yield() -- first
coroutine.yield() -- second
p({err1=err1,err2=err2,data1=data1,data2=data2})
end
local coro = coroutine.create(script2)
coroutine.resume(coro);
---
I find this fairly straight forward and it reduces for me the complexity to
write code just with some basic Lua where frameworks are needed in
javascripts to achieve similar.
And I can always chose what I need.
But the true strength of this is for me that I can adapt my code to my
needs. In node.js when I took the way of "synced" programming, it's pretty
tough to convert this into callback styled code afterwards when it was
needed. It reminds me of "when all you got is a hammer..." in the tone of
"when all you got is a closure, all your code starts looking like a
christmas tree" (the nested indentions really look to me like christmas
trees tilted 90°...).
About memory consumption: LuaJIT's coro library modifies coroutine.create
to allow setting the c stack size (http://coco.luajit.org/api.html) which
you can use when you need more coroutines than just a handful (vanilla Lua
coroutines are very light and you can create thousands if you want to;
LuaJIT requires them to have a c stack size though to allow jitting... when
I tested it several years ago, the default cstacksize was 1mb on my
machine, which isn't exactly tiny ... so you might want to watch out for
this when you start using coroutines in great amounts).
Anyway, I am happy the way Luvit looks like to me :).
(Some more docs would be nice, I am just starting to look into Luvit...)
Cheers,
Eike
2014-11-03 2:05 GMT+01:00 Ross Bencina <[email protected]>:
> On 3/11/2014 7:36 AM, Eike Decker wrote:
>
>> I'd vote for coroutine based programming. The closure based async
>> programing in node.js is driving me nuts. Perfectly simple goals becomes
>> stretched and teared like warm chewing gum when jumping through just a
>> few asnyc hoops.
>>
>
> Being able to use standard control structures across blocking async calls
> is a big advantage of coroutines.
>
> But i'm not sure whether coroutines *always* provide the best solution.
> For example, I'm not sure how you do scatter-gather parallel requests with
> Lua coroutines (i.e. issue a bunch of parallel requests, then receive each
> reply, then continue the coroutine once all replies have been received).
> Would you spawn a coroutine for each request and then join them somehow?
> Maybe it would be desirable to have async callbacks available so that
> people can implement this kind of thing if/when needed.
>
> Cheers,
>
> Ross.
>
>
> --
> 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.