> Integration with C (and C++ for that matter)
Guile does it better. You can use shared memory threads in guile without any penalty. Atmost you have to allow for the garbage collector to run when inside FFI functions. But that is a small price to pay in case you need to use multiple parallel-concurrent threads with a single heap.
Guile was built with FFI in mind and has an impressive history. Just take a look at guile gnome bindings.
> Speed and Simplicity
Guile 2 is extremely fast. Not as fast as LuaJIT, but it no reason it won't get there. As for simplicity, take a look at the partial evaluator in trunk of guile 2.
> Education
Guile is good old scheme.
> Functional
Can't get more functional than scheme :)
> Everything is a Table
Well, almost everything is a pair in guile. Vectors and hash-tables are trivially available. Though I recommend to sticking to functional programming in scheme style.
> Consistent
As before, can't get more consistent than scheme.
> Portable
Guile is available on n900. So there.
To continue, guile has continuations (delimited or otherwise), and macros (hygienic or otherwise), both of which are effectively missing in lua.
And guile offers all of this while supporting native threading with a single heap. Sweeet.
Compare:
(define memcpy
(let ((this (dynamic-link)))
(pointer->procedure '*
(dynamic-func "memcpy" this)
(list '* '* size_t))))
vs. ffi.cdef [[
void * memcpy ( void * destination, const void * source, size_t num );
]]
You also get the ability to add metamethods and finalizers to returned C objects (so you can use Lua's built-in GC to clean up after, for example, your FILE*).As for the speed, there's no reason that a lot of dynamic languages couldn't be as fast as LuaJIT. But none of them are even close. I wish LuaJIT was still up in the computer language shootout. The LuaJIT interpreter (with JIT turned off) is 3x faster than V8 on the PC, and faster than Java on Android. And that's the interpreter - the JITed code is way faster.
Of course, macros are awesome, and a huge point in Guile's favor. On the plus side, Lua is very easy to understand, especially if you're coming from Javascript.
[Citation Needed]
I know of old benchmarks (pre Crankshaft) that showed the interpreter being faster than V8, but my own tests using the same benchmarks from the computer language shootout show V8 to be about 1.5x faster than luaJIT now.
I did some searching, and the most recent (though still way out of date) comparison I could find was this: http://attractivechaos.github.com/plb/
As for finalizing arbitrary objects, please see http://community.schemewiki.org/?guile-guardian
I agree on the speed part. But guile 2 is getting better. The reason guile cannot be as blazing fast as say gambitc is their need to inter-operate with all sorts of C code. Native threading included.
Rich Hickey: "Functional has been applied, you know, for a whole spectrum of things. I think there’s the haskell meaning of functional, which is sort of, the pure notion of function applied to absolutely everything in the language. And then there’s another notion of functional... lisps claimed to be functional early on, only for the simple reason that functions were first class objects or values that you can pass around. Those are the two ends. Somewhere in the middle, i think, is a style of programming that emphasizes programming with pure functions, in other words functions that are free of side effects, that operate only upon their arguments, which are values, and that only produce values as results. So that’s a pure function. Clojure emphasizes the style of programming using pure functions, where lisps, traditionally, have not. You could do it, but it was a choice. The key thing in forcing you to make that choice, is to have the core data structures be immutable, so they now can be treated as values, in a way that mutable things cannot. So Clojure emphasizes functional programming, by providing a set of immutable core data structures, including those ones that you use to represent code. They’re also persistent, which is a special characteristic we could talk about. Because of that, it encourages the functional style of programming, because you cannot change [the core data structures], so you have to write a function that produces a new value as a result. but there’s no enforcement. if you write a function and that does IO, well that’s not a pure function anymore, and I don’t preclude it, and there’s no type system to preclude it, its a dynamically typed language, which just respects the programmer’s right to do whatever they please." [1]
[1] https://docs.google.com/document/pub?id=1Vgbw3hGCye2rtmnZ6iS...
What is Guile's synchronization model for shared-state multithreading?
> Guile is available on n900. So there.
This appears to be a Linux-based phone, so that's not very surprising or impressive. Lua is straight ANSI C and can compile on much more limited systems than a Linux-based smartphone.
One other data point: Guile is 5x the size of Lua, in both source and binary forms.
> To continue, guile has continuations (delimited or otherwise), and macros (hygienic or otherwise), both of which are effectively missing in lua.
One of the authors of Lua made an interesting point in his slides describing Lua 5.2: if you think "goto" is evil, continuations are much worse. And yet it's considered "cool" to support continuations. http://www.inf.puc-rio.br/~roberto/talks/novelties-5.2.pdf
This. We were considering using Guile before we ended up going with Lua and this was actually a big factor for us.
* Full continuations, with copying.
Great paper: "Revisiting Coroutines" (ftp://ftp.inf.puc-rio.br/pub/docs/techreports/04_15_moura.pdf)
http://dl.dropbox.com/u/7810909/docs/what-does-fp-mean/what-...
http://existentialtype.wordpress.com/2011/03/16/what-is-a-fu...
http://stackoverflow.com/questions/2254368/if-java-people-go...
I'm not taking sides, i like haskell, scala, clojure just fine, I'm sure I would like racket or CL if i picked them up.
Try telling that to the Haskell guys!
So, scheme style these days is all about pure functions, tail calls and continuations. To think about it, that really is setting it apart from common lisp.
* It lacks an easy-to-use symbolic debugger.
* It lacks a first-rate IDE.
* It lacks a standard way for people coming from OO/Java to define objects and interfaces.
* It lacks a GUI toolkit.
* It has a great set of manuals. It lacks an O'Reilly book with a woodcut animal on the cover.
* Arrays indexes start at 1.
Except for the last item, these are all relatively small things that are simply waiting for someone to come along and do them. This is a testament to the great design of the language.
And many of these things do exist, it's just the Lua style seems to be to understate the achievements to the point that folks can't tell the big new stuff from the abandoned projects.
> * It lacks a first-rate IDE.
<plug>This is changing http://eclipse.org/koneki/ldt/</plug>;
> * Array indexes start at 1.
This sounds dangerously similar to "I can't use Python because it has significant whitespaces". Developers might like or dislike it, but if you can't get over _that_, you either lack important cognitive abilities, or you're suffering from a very serious case of Asperger's/OCD. I can't imagine that someone seriously hampered by _that_ could ever digest any large API.
However, I'll admit it's a bit irritating when you're frantically switching between C and Lua.
> the Lua style seems to be to understate the achievements to the point that folks can't tell the big new stuff from the abandoned projects.
You're right, organizing the efforts of the Lua "community" would probably be trickier than herding cats, and the Lua core team doesn't seem very interested in helping that happen. I sometimes suspect that even Lispers form a tighter community than Lua hackers...
> [...]
> However, I'll admit it's a bit irritating when you're frantically switching between C and Lua.
I would imagine it can be confusing when swapping between C and Lua, but when working in a Lua-only environment (e.g. writing addons for World of Warcraft) it very quickly becomes a non-issue.
> * It lacks a first-rate IDE.
>> <plug>This is changing http://eclipse.org/koneki/ldt/ </plug>;
This looks excellent, even for people who don't like Eclipse. Lua sorely lacks an interactive debugger, and your DBGp-based solution is portable beyond Eclipse.
Very nice :-)
If you want to have some fun with Lua, check out LÖVE[2].
[1] http://lua-users.org/wiki/LuaModuleFunctionCritiqued [2] https://love2d.org/
Lua's goal is to be no-fat and customizable to only what you need for your unique situation. It's even common practice for systems to cut out stuff like the standard library file I/O module if it's not appropriate for your situation.
Lua is in dire need of an opinionated killer platform. Unfortunately, unfamiliarity with the language (vis-a-vis javascript) means that the road to mass adoption is a tougher one.
Unfortunate especially given that Lua and JavaScript are extremely similar semantically. The difference between {} vs begin/end really does blind people to the all similarities.
If you ask in IRC or google around you can find this pretty easily. The first result on google for query "lua class" is http://lua-users.org/wiki/SimpleLuaClasses.
That is an interesting claim. What are the first rate IDEs for Javascript, Python, Ruby or C++? That isn't a rhetorical question I mean vim, emacs, textmate all seem equally good for Javascript and Lua. I know people use Eclipse for Javascript but it hardly seems like a killer integration.
I read all the Lua papers, and they are quite fond of "getting it right" (which is refreshing). They will break things to get it right, whereas other languages stick with all their old design warts in the name of compatibility. I like this approach, but it comes at the expense of popularity.
Compare Lua with Python, which has had basically 1 major version for 20 years Python 1.x are all compatible with 2.x -- that was a license change; and Python 3 is having adoption troubles which proves the same point. Python 3 was the chance to "get things right", or fix old design warts, but you can see what a big impact it's having on adoption, fragmentation of libraries, etc.
The other reason is that embedding a language isn't as common a use case as a scripting language. I've tried to write stuff in Lua rather than Python, but really Python's "batteries included" philosophy just kills any advantage Lua has.
The main reason I would like Lua is so you can distribute stable (small) executables... but when you're starting out Python is a lot easier. You don't want to download LuaSocket or whatever and mess with the build system.
I think the major, overwhelming reason is because it has no standard library, much less a package-ecosystem such as RubyGems or Python eggs.
I recall that MS ships with each game the exact version of DirectX it need, so they are free to improve it without being hamstrung by back-compatibility.
TCL is ahead by a nose at this point with Unicode support baked in (vs. using a library) and file system handling built in (again vs. using a library).
Tcl's file system interface is definitely an advantage if you're trying to avoid third party libraries. However, depending on what you need to do with Unicode strings, Lua's strings are "8-bit clean" and have no difficulty storing Unicode characters; Lua's string functions (the pattern-matching functions in particular) aren't Unicode aware.
I don't need speed as I'm doing offline processing and not worried about lambdas at this point. The unicode is important as I am looking to take Greek and Hebrew text and process it.
The bad thing about Tcl is probably its library support. It has an extension mechanism, but for a lot of "contemporary" projects (web etc.), you're actually more likely to find working Lua "Rocks" than tcl modules.
jim: http://jim.tcl.tk/
But as a language, Tcl will allow you to experiment a completely different way of thinking. Lua is neat but not so different from what you already know.
what i do not use tcl for is: web. unfortunate lack of a framework.
it has good support for downloading stuff, ftp, http, bignums and algorithms if needed.
Lua's convenient C API means that wrapping libev, libuv, or libevent is really not hard, if you want to go that route. (I have a libev wrapper on github, FWIW.)
The thing to keep in mind is that if you're writing high-throughput servers, you probably want to avoid parsing the network IO via Lua. While Lua strings are fine with arbitrary binary data (i.e., \0s are fine), it interns all strings; you'll have the overhead of converting every read into an atom/symbol, and it will spend a lot of time garbage collecting. (Lua makes this daring trade-off because it's usually a net win, and when it isn't, you still have the option of doing things in C instead.) Lua's great for handling all the control logic, though. Coroutines are particularly applicable there.
In a nutshell: If you're good with C, and understand the issues involved with performant async IO, Lua can work very well.
Lua seems to be such a good fit for this paradigm that I would bet the community is going to produce some outstanding frameworks. (Was kicking around the idea of implementing something myself.)
I have found that being able to place arbitrary constraints on the way my programs store things in (seemingly simple) data structures has been very, very powerful.
The metatable is more general and conceptually simpler. It doesn't have to be the "class" of an "object", it can implement other patterns to OO without feeling weird, because the assumption that metatable is "Object Oriented" just isn't there.
Do you have python beginners touching metaclasses? I doubt it. Do you have lua beginners touching metatables? Certainly yes.
Another cool thing about Lua, which was mentioned only briefly in the article, is proper tail-call optimization (TCO) like you'd find in Scheme. TCO makes expressing recursive algorithms nicer because you don't have to worry about blowing your stack.
Lua's design philosophy -- giving the programmer a handful of basic yet powerful features -- makes it somewhat Schemy. I suspect that Lua is about as close as you can get to a ball of mud before becoming Lisp.
If you think about it, this is very similar to C where the only composite datatype is a struct (arrays are just sugar on pointer arithmetic). In fact, I think if you wanted to make a scriptable dialect of C, you'd create Lua.
Of course, by being simple, add in dynamic typing and first-class functions, and Lua does feel a bit like Scheme's kid brother. Or, rather, Lua (in my mind) reveals how C and Scheme aren't so far apart after all!
function create()
local a,b,c,d,e,f,g,h,i,j;
return function() print(a,b,c,d,e,f,g,h,i,j); end
end
function array_get(f, index)
local k,v = debug.getupvalue(f, index);
return v;
end
function array_set(f, index, value)
debug.setupvalue(f, index, value);
end
function map_get(f, key)
for i=1,math.huge do
local k,v = debug.getupvalue(f, i);
if k == key then return v; end
if k == nil then return nil; end
end
end
function map_set(f, key, value)
for i=1,math.huge do
local k,v = debug.getupvalue(f, i);
if k == nil then return; end
if k == key then
debug.setupvalue(f, i, value);
return;
end
end
end
function test()
local f = create();
array_set(f, 1, "one")
assert(array_get(f, 1) == "one");
map_set(f, "b", "something");
assert(map_get(f, "b") == "something");
print("Success!")
end
test();
If table creation was disallowed, you could use functions in place of tables. And you could repurpose an existing table as the function type's metatable, allowing syntax like func.x=func[y]Oh, and coroutines probably also fall under composite data structures technically...
lua seems to have more of a relaxed, niche community among game developers and scripting language embedders.
i've been using lua for about a week so far, for a music player i'm building (http://cloudplay.fm/) and i'm writing the song search/ranking system in lua. it's wonderful to be able to prototype it outside the application and not have to deal with the integration until you need to.
i would consider using lua on the server-side (see http://luvit.io/ for a node.js-style interpretation, although i'd prefer coroutines instead of callbacks) but there needs to be more work on the library front.
to help lua grow, i'd fix these things:
- add unicode support
- bring the CLI up to par with node.js (i use node as a calculator, too)
- build a modern distribution that includes frequently used luarocks
This won't happen soon. Lua targets ANSI C and only ANSI C.
C11 includes new character types to support unicode, but I imagine that the Lua implementers will take their time.
Plus there's implications for embedded situations.
If you need unicode (and most do), there are libraries and patches that do a reasonable job.
The C API is easy to use and gives good performance, and yet encapsulates enough of the VM's implementation that C modules are source and binary compatible with both Lua and LuaJIT, two very different implementations of Lua. Note that the C API was designed before LuaJIT was even written, so this API was designed without the benefit of seeing how different implementations of Lua might vary.
The source is very readable for the most part; my only stumbling block is that their naming of types and variables is extremely terse at the cost of readability sometimes, and the extensive use of macros can sometimes can require a lot of jumping around. But Lua is an impressive achievement that I frequently refer to for design inspiration.
Check out http://luajit.org/ext_ffi_tutorial.html
http://stackoverflow.com/a/2102399/222815
Roberto provided a ref to the way Lua implements closures, which is certainly innovative.One things I like about Lua is that it's TCB is small. This matters when you are embedding code.
There are many features of Lua that have caused me more problems (the somewhat inconsistent string conversion, for instance).
When I was doing Lua stuff I ended up writing some FP-style helpers and other functions for iteration. This cut down on the number of times I had to think about the table indexes (and was helpful in general).
My first task in Lua was to build a solid collections library (modeled after Ruby's), so this issue comes up far more infrequently for me now. (e.g. I use :first(), :last(), :push(), etc instead of [1], [#length], [#length + 1])
Why Lua? http://itunes.apple.com/us/app/beat-boxes/id460798042
LuaJIT speeds can rival code written in C. And if you are still not getting the speed you want, see my 1st point above (Integration with C and C++ for that matter).
The simplicity of Lua is, I think, really underrated.
It is a good learning exercise to write some small benchmark / utility / tool in Lua so you can get an idea of how quickly you can develop, and how fast the resulting code will be.
Then read through the Lua source [0] to see just how little code is required to give you that platform for your ideas.
I reserve judgment till I see an actual proof of that.
>>> In Python, you might __import__('...')' some module and then the variables of the return value would be accessed like vars(module)
it makes me wonder if the author is just unfamiliar with Python (and by extension, any language other than Lua) or if they're deliberately misrepresenting other languages to make Lua look good (which it definitely doesn't need).
But this was obviously a poorly written part of the article that could use improvement.
[EDIT] typos [EDIT2] less arrogance :)
For future reference, I'd implement your dynamic module importer like this:
def dynamic_import(name):
import imp
return imp.load_module(name, *import.find_module(name))
os = dynamic_import("os")Other than that, I agree with the other posters here. It's an impressively lightweight and elegant language. It's especially good for embedding: its C integration is next to none, it's easy to sandbox if you want to run untrusted code, and the interpreter doesn't use any global variables.
function nilguard(tbl)
tbl = tbl or {}
local mt = {
__index = function(t,k)
error("Invalid key: " .. tostring(tbl) .. "[" .. k .. "]")
end
}
setmetatable(tbl, mt)
return tbl
end
local myObj = nilguard({foo=10})
myObj.crap -- should raise
For undefined global variables, just require("strict") setmetatable(_G, {__index=function(global_env, name) print("unknown: " .. name) end})Because the Wikimedia Foundation has decided to use it?
"Wikipedia chooses Lua as its new template/macro language" http://news.ycombinator.com/item?id=3534649
"Lua chosen as new template scripting language" http://en.wikipedia.org/wiki/Wikipedia:Wikipedia_Signpost/20...
Disapointed because the author's link to the benchmark website lead me to the wrong impression that Lua would be almost 30 times slower than Java 7. Then I googled around and discovered the awesome LuaJit which seems to be able to compete even with C++ in performance.
What I really like is Lua's code density (see samples in the Shootout's benchmarks). Very impressive!
http://shootout.alioth.debian.org/u32/benchmark.php?test=all...
As an old LISPer and Schemer I would like to know if Lua Macros are really as expressive and powerful as Lisp macros. Some people claim this but I am not convinced (I would like to be convinced). The expressive power may be theoretically equivalent but this is also true for C and Assembler :-) The question is: Are Lua macros as easy to handle as Lisp and Scheme macros?
http://stackoverflow.com/questions/323346/what-can-lisp-do-t...
LUA is just one tool in the tool box - its not the tool box.
No idea what it costs these days, but if you're writing Lua code and it's need to be fast I'd recommend checking it out.