4 ms·
Author here. Here's some context [1]: Lua supports cooperative coroutines out of the box, which is great. Unfortunately Lua lacks built-in communication primit
by majke 13y ago
Author here. Here's some context [1]:
Lua supports cooperative coroutines out of the box, which is great. Unfortunately Lua lacks built-in communication primitives. To fill the void I've implemented Go style channels in pure Lua.
Of course abstract channels without any concurrent IO aren't terribly useful, but fortunately the code is pretty straightforward and adapting it to your event loop shouldn't be a problem.
The code is ~400 lines of code + ~200 of tests.
For example, here's [2] Eratosthenes sieve following Russ Cox explanation [3].
[1] http://lua-users.org/lists/lua-l/2013-08/msg00546.html http://lua-users.org/lists/lua-l/2013-08/msg00546.html
[2] https://github.com/majek/lua-channels/blob/master/sieve.lua https://github.com/majek/lua-channels/blob/master/sieve.lua
[3] http://swtch.com/~rsc/thread/ http://swtch.com/~rsc/thread/
- ufo 13y agoBTW, the algorithm used in example 2 is not the true Sieve of Erastosthenes (although there is a long tradition of getting that name wrong...) http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
- corysama 13y agoI'm not familiar enough with Go's channels to understand what I'm looking at. Could you give a brief summary of the functionality this adds over passing/returning values through Lua's built-in resume/yield?
- majke 13y agoI'll do my best, but it's a bit hard to explain. Basically channels are yet-another synchronization paradigm like locking or shared memory, some people like it some don't. Channels are an implementation of Hoare's CSP [0]. Channels can be passed around, the same could be said about Lua coroutines. But with channels you get more flexibility: - you can "block" on many channels at once using the "chanalt" statement. You can "resume" only one lua coroutine at a time. - channels they can buffer messages (ie: channels can queue several values) - many coroutines may "send" a value to a channel at the same time, many coroutines may try to "listen" (receive) a value at the same time. - finally you can pass a channel over a channel I find channels, as opposed to many other synchronization paradigms, to be composable and generally nice in use. It's a "better" alternative to synchronization locking and mutable data. But in Lua, of course, there aren't multiple threads so why synchronization is useful? In the same way that coroutines are useful - they allow you to decompose a program into set of smaller programs. The example given by Russ Cox is the Eratosthenes sieve. You can read about it [1] or watch him talking about it [2], finally my implementation following his talk [3]. [0] https://en.wikipedia.org/wiki/Communicating_sequential_processes https://en.wikipedia.org/wiki/Communicating_sequential_proce... [1] http://swtch.com/~rsc/thread/ http://swtch.com/~rsc/thread/ [2] http://www.youtube.com/watch?feature=player_detailpage&v=hB05UFqOtFA#t=1600s http://www.youtube.com/watch?feature=player_detailpage&v=hB0... [3] https://github.com/majek/lua-channels/blob/master/sieve.lua https://github.com/majek/lua-channels/blob/master/sieve.lua
- JulianMorrison 13y agoresume/yield gives you these features of channels: - time ordering (in both, the send "happens before" the receive, and the next line in the sender "happens after" the receive) - communication - pipelined architecture but not these: - the runtime chooses a goroutine that can proceed and schedules it, you don't need to fear blocking, producers can make headway while consumers are waiting, and you don't need to manually arrange multi-goroutine control flow into some sort of pass-the-buck loop. - nonblocking sends allow a variation of the time ordering (the send "happens before" the receive, but the next line in the sender is not coordinated with the receiver, it may happen immediately) - decoupling sender and recipient: the recipient goroutine doesn't need to know which goroutine to resume such that the sender can pick up where it left off - ability to choose which channel you'll communicate down, --- simultaneously, whichever is ready (listen for "shutdown", "timeout" and "data", for example) and with a default that can be used for the non-blocking alternative --- at different times in one goroutine (read "producer" then write "consumer" then read "status" then write "confirmation", for example - you can do this in stock Lua but the coupling would be awful)
- hisham_hm 13y agoHi, any chance you'll submit a rockspec to LuaRocks?
- majke 13y agoFancy giving me a hand? https://github.com/majek/lua-channels/issues/1 https://github.com/majek/lua-channels/issues/1
- ajacksified 13y agoI've submitted a pull request for your review: https://github.com/majek/lua-channels/pull/3 https://github.com/majek/lua-channels/pull/3