3 ms·
> Unfortunately, Lua has statement- rather than expression-oriented semantics (i.e., no "implicit returns"). This is largely irrelevant for anything related to
by davidhollander 15y ago
> Unfortunately, Lua has statement- rather than expression-oriented semantics (i.e., no "implicit returns").
This is largely irrelevant for anything related to developing asynchronous services such as web or servers. Asynchronous web development using callbacks is a form of continuation passing style, where control is often explicitly passed using a callback. Since you are explicitly passing control, you usually never have to return values anyway. The 'return' keyword just becomes a bonus feature for convenient error handling.
Having a language with good closure support just works phenomenally well for asynchronous web development. For instance, sending an entire message asynchronously can be a pain because it can fail at any point in the message and require restarting at that point and keeping track of when it has finished.
It's a piece of cake in Lua though, due to its excellent support for closures:
-- SendAll
-- Start sending a message on connection [c]
-- Close when done.
function SendAll(c, msg)
local n=0
OnWrite(c, function(c)
n=n + c.fd:send(msg, n)
if n>=#msg then
c.fd:close()
return 'close' -- just for kicks
end
end)
end
The variable "n" is a counter for the number of bytes sent to the file descriptor "fd". The write callback lambda assigned with OnWrite can always access the appropriate counter "n" based on its creation location. No extra work was needed to create the closure, unlike in languages such as JavaScript.
- anonymoushn 15y agoIn Lua, unlike in JavaScript, you don't need to use closures for async programming most of the time. -- SendAll -- Start sending a message on connection [c] -- Close when done. function SendAll(c, msg) local n=0 while n<#msg do yield() n=n + c.fd:send(msg, n) end c.fd:close() yield('close') -- just for kicks end
- davidhollander 15y agoCoroutines aren't as flexible as continuation passing style and add significant overhead for the non-vital syntactic sugar they give you. I'd much rather explicitly set an OnWrite event that has a one-to-one correspondence to a socket write event from a poll() system call, than create a ton of coroutines and juggle "resumes". This is especially true if you have a usecase where you want to start sending while you are still reading, this would require the creation of 2 coroutines per each context. While Lua coroutines are significantly better than Python generators by having a more functional than syntactical "yield", I still feel it does more harm than good for structuring asynchronous applications.
- silentbicycle 15y agoCoroutines are less expressive than manually doing CPS, true, but they do make many common cases simpler. They're ultimately as expressive as one-shot continuations.
- silentbicycle 15y agoI never said it did. Of the many complains in-thread about Javascript, it's the main one that also applies to Lua. I'd say Lua's coroutines are a bigger feature for asynch. development, though. I wrote an embedded non-blocking / event-loop webserver in Lua as part of one of my projects (a distributed filesystem). I got sidetracked by other projects, and lost interest in writing non-blocking webservers after I got into Erlang, but plan on getting back to the filesystem soon. If I find time to neaten up that code, are you interested in swapping notes? One tricky part is error handling - I spent a lot of time on that (and was pretty impressed by Erlang's error handling model). I don't know how well node.js does that, beyond managing control flow by hand.
- davidhollander 15y ago>If I find time to neaten up that code, are you interested in swapping notes? Yes, I wrote a coroutine-less one here and tried to include design decisions in readme: https://github.com/davidhollander/ox https://github.com/davidhollander/ox It works for HTTP but has few features so far. I have a bunch of exploratory code lying around though, so I could be adding message passing or better fileserving to it in the future. I will send you an email at some point.