I saw this and for a while I thought "Oh yeah, that's pretty cool, but why isn't the lua community into it?"
Then I really looked into luasocket[1], which uses a this api called ltn12, based around dataflow programming concepts. In most respects this is a much much more elegant way of doing network programming than the node.js way. This is the sort of thing you would want to implement on top of node.js to make the callback hell easier to deal with- and compared to luasocket, luvit is a step backward. But this is the standard way of doing networking in lua.
Any good open-source (or closed) examples of web apps built on this?
The idea sounds neat, but I'm wary of concepts that aren't seeing real-world use. Node.js has momentum, Luvit has a little bit of momentum, this? In the web development community, I've never heard of the approach, which suggests using it might be more DIY than I'd like. Also the copyright date is 2004-2007. Abandoned?
Forgive me for being a bit ignorant about this, since I'm quite a bit outside the lua community myself. (and didn't quite expect to get voted to the top here) I've done some googling around, and It's hard to say if luasocket is abandoned as such- but there are several forks of it. Regardless, it's the standard library that pretty much anyone and everyone uses for networking. There are a number of forks on github of luasocket- maintained presumably to add features needed for specific projects.
There is the Kepler project http://www.keplerproject.org/ , which appears to be much like the commonJS project for javascript- with luasocket at its core. Kepler project lists http://slimfastclinic.com/ and http://www.bestjuicer.biz/ as websites that were built with lua. (though they may be out of date since the slimfastclinic.com says it's wordpress)
We're working on splitting this out into a reusable platform for writing lightweight host-based agents. Luvit works out fairly well for this - our monitoring agent runs in around 5mb resident memory, works on Windows (although we haven't released that yet) and is relatively easy to code on.
Shameless plug: if this sort of stuff interests you, hit me up, my email is in my profile.
We use Node.js on our backend, were involved in some of the work that led to libuv being split out from node core, and were already planning to use Lua based on our experience with the Cloudkick agent. All told, when we saw what Tim was doing with luvit it seemed like a natural fit.
how does the stack copying technique (as used in lthread) compare to segmented stacks (as used in go)? The swap technique is very simple but I would assume that the stack copy shows up in profiles and is significantly slower than the segmented stack technique... Are there any benchmarks?
Segmented stacks will take much more space. One of the reasons I went with stack copy is because it allows me to create a million lthreads if I wanted without worrying about memory.
Lthread is in C, an environment where you control/manage your memory. Using slab allocators and high performance malloc like jemalloc, you can avoid allocating a lot of your variables on the stack and the stack copy will become minimal. In most of the production code I have running using lthread, stack copying is on the average of 300 bytes.
Lthread is a cool experiment but coroutines in C is a dubious ideal. If you're writing a program in C/C++, presumably you want ultimate control and the fastest possible execution. You wouldn't introduce extra runtime complexity and a speed hit for easier to use APIs (blocking I/O functions). You'd just use epoll and non-blocking sockets (or libuv). That's not to say that coroutines/green threads/goroutines in high-level languages where you've already decided to take a speed hit for easier use isn't useful. Said another way: if your concern is about easy to read code, C is not the right choice; if your concern is speed: copying a stack on every i/o function is not the right choice.
When you said segmented stack, It registered stack per lthread for me. Ignore my previous reply.
Segmented stacks aren't possible in C, because you don't have control over the stack's growth and the MMU when a function is running.
Coroutines simplifies your code a lot compared to callbacks(via libuv, epoll) and with lthread, you barely have any performance hit if you don't have sizable variables on the stack. I've written web servers and proxies in lthread that performs as fast as nginx (and sometimes faster). I think that's a pretty good deal.
> You wouldn't introduce extra runtime complexity and a speed hit for easier to use APIs (blocking I/O functions).
Your program is running in a kernel. You already have lost a lot of performance, and the complexity got introduced. Kernel does a gazillion thing while running your program, so if you really want raw performance, make sure to run your code on a bare metal CPU without kernel intervention. But that's not convenient, hence you compromise, pay a penalty, and run your program in a kernel. But does that mean you might as well use a high level language because you compromised on performance? no.
> if your concern is about easy to read code, C is not the right choice
I disagree. They aren't mutually exclusive.
> if your concern is speed: copying a stack on every i/o function is not the right choice.
lthread doesn't copy a stack on every IO function call. The lthread stack is copied only after the socket blocks or it reached its fair share. Sometimes this means an lthread can do 2 to 5 calls before it yields. And when it yields, depending on how deep you are in your call, the stack gets copied from there. If you don't have big variables on your stack, the stack copy can be just few bytes. Note that it's not the whole scheduler stack that's copied (4MB by default), but only what was consumed by lthread (usually from few bytes to 300 bytes, it varies based on the code).
You are over-simplifying your choices to this: if you want performance, use C & callbacks otherwise use a high level language. There's a wide spectrum that you are missing out in this over simplification.
Not sure exactly how duped this is for HN... For those that don't know.. Lua is a scripting language, perhaps a bit more structured than it's more popular counterparts (JavaScript and Python), having very good performance characteristics. It's very popular in terms of Game development.
Luvit is essentially a lua interpreter with bindings to libuv (the same core IO library used in NodeJS). And could mainly be considered an alternative to NodeJS, which it most closely resembles.
Some, who don't like JS syntax may wish to consider Luvit, as it will perform close to, and sometimes better than NodeJS, with some similar gotchas.
> Lua is a scripting language, perhaps a bit more structured than it's more popular counterparts (JavaScript and Python)
I wouldn't say it has more structure than Python or JavaScript. Lua has only these types: number, string, boolean, table, function, nil, userdata and thread. Table acts as a hybrid between list and map, just like Array/Object in JavaScript. And users rarely are exposed directly to userdata/thread, that's more something you'd use when you write a library (use userdata to emulate classes etc). The Lua VM is also much simpler than the other two, it's a simple stack machine. There are no tuples like in python, no first-class support for classes.
Lua IS a register based machine. The white paper done by the Lua authors is the reason most of the industry has moved to register based machines. (Apple SquirrelFish for Safari was the first to read it and implement it and everybody followed suit to compete.)
http://www.lua.org/doc/jucs05.pdf
Lua has true multiple return value support. The overall usefulness of tuples in light of this feature is not clear.
Lua has first class support for functions and actually supports functional programming unlike Python which cripples many techniques and where Javascript has broken lexical scoping. Lua uses metamethod programming to allow you to build functionality like classes; Javascript has prototype inheritance which is different than Python's classical inheritance. Each is just different; not necessarily more or less structured.
Also, never confuse simple for being primitive. Lua IS incredibly simple and elegant. But all the simple things in the language work together elegantly to allow for amazingly sophisticated things.
Lua has a register-based VM. You're probably thinking of Lua's C API, which is stack-based.
EDIT: Also, I just remembered that Lua started as a stack-based VM, but moved to register-based at around version 5. So you could be thinking of the old Lua, too.
You're both right. It has a stack that it uses for callframes and local variables, but the opcodes have operands to directly reference variables on it by index. In other words, it treats all of the stack for a given callframe as a set of registers.
For a while, I thought that luvit is completely undocumented. But then, I found out that one just goes to nodejs.org ...
So far, I mostly like it. Recently, I used it to build a PoC for an in-house testing tool for embedded devices and decided to slap a web interface onto it for fun (just like Twisted provokes you to add an NNTP and an SSH interface just for fun).
What I'm a bit unhappy with is the decision to be incompatible with the rest of the Lua world. From what I read in the mailing list, it's not just "sorry, that rock uses blocking file IO" but rather "Lua is Lua, and luvit is luvit".
[1]: http://w3.impa.br/~diego/software/luasocket/