
The evolution of Lua - shawndumas
http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/hopl.pdf#
======
bitcracker
One serious thing Lua is still missing is native Unicode support (correct me
if I am wrong).

When I discovered Lua the first time I was enthusiastic. The JIT is so fast,
and everything seems to be fine. But missing Unicode is a big disadvantage for
Lua. Unicode is a must to have for modern languages. It makes things so much
easier when you know you don't have to convert any fonts because they are all
presentable in Unicode.

~~~
jballanc
After having worked with Ruby 1.8 (no unicode support in String) and Ruby 1.9
(added unicode) rather extensively, as well as C/Obj-C and a variety of other
languages with varying ideas on Unicode support, I am of the opinion that Lua
has the right approach. If your built-in string type does not account for
encodings, you can always build one on top of it that does. If, on the other
hand, your built-in type has to carry the constant burden of encoding
information, you'll never get away from that (indeed, I've been talking with
ruby-core about adding back a string-like library with no encoding information
in Ruby 2.0).

~~~
bitcracker
As long as you handle usual letters it is no problem to miss Unicode.

How nice Unicode is I always realize when I copy and paste some foreign text
from somewhere into Emacs or Racket Scheme and everything works just fine.

~~~
groovy2shoes
What he's trying to say is that Lua's strings are capable of storing Unicode
characters (they're "8-bit clean"), but that Lua's string manipulation
functions aren't Unicode-aware. If you want to paste Unicode characters into a
string and print it later, Lua can handle it. If you want to do a pattern
match on a Unicode string, you need to bring your own pattern matcher.

------
haberman
As someone who values simplicity, minimalism, portability, and good
performance, Lua is a constant source of inspiration to me. I frequently look
at its design for ideas.

~~~
gruseom
Please say more. What are some inspiring things you've found in Lua's design?

~~~
haberman
I'm having trouble answering your question eloquently. I'll think about it
more and hopefully write a blog post about it before long.

~~~
gruseom
Please do. I'd like to read it.

It seems to me the outstanding feature of Lua's design history is its
designers' determination to make the core ever simpler and more general. That
takes vision and courage over a long period of time. What emerged is truly
interesting and inspiring (much more so than cobbled languages that grow only
by accretion of features) and is likely to grow in importance.

~~~
haberman
Yes, that is very much how I feel about it. They boil every concept down into
its purest essence, and always avoid having two abstractions when one will do.
Other languages grow when they need new features, Lua refines.

But in a blog entry I'd like to address several of Lua's core abstractions and
how they are cleaner and more general than competing languages. For example,
the Lua thread data structure encapsulates all necessary state for a thread,
but is general enough that it actually allows for multiple thread execution
models. By default only coroutines are provided (which use the thread data
structure). But you can implement lua_lock()/lua_unlock() to have a Python-
like model with preemptive threads and a GIL. Or you can use lua_sethook() to
implement a "green thread" model where multiple pre-emptive Lua threads run
inside a single OS thread.

Three options for threading models (probably more if you dig in), one core
abstraction and implementation. Remarkable!

~~~
gruseom
I wonder what examples one could dream up where manipulating that thread data
structure in an application-specific way would be a win. i.e. some kind of
domain-specific threading model.

~~~
haberman
Manipulating the thread data structure _directly_ would violate the
encapsulation of Lua and prevent you from being portable to eg. LuaJIT. But
there are still lots of opportunities for building custom threading models;
see:

[http://kotisivu.dnainternet.net/askok/bin/lanes/comparison.h...](http://kotisivu.dnainternet.net/askok/bin/lanes/comparison.html)

------
telemachos
If you enjoyed this, you will probably also like the same author's "The
Novelties of Lua 5.2"[1].

[1] <http://www.inf.puc-rio.br/~roberto/talks/novelties-5.2.pdf>

~~~
gruseom
I absolutely love how they are making such major changes as late as version
5.2. I also love that one of them is goto.

Lua is terribly impressive. Someone needs to make a transpiled language
targeting Lua and JS. They're semantically close enough that this might not be
too complex. If it worked well, it would be an interesting alternative to
Node.js, since you could write the server-side for Lua coroutines and so on.
Not to mention its performance.

~~~
catch23
Lua does have lots of metaprogramming that js lacks, and adding into js could
be tricky since you'd essentially have to rewrite existing js code into new
code that allows this.

However, the grammar rules are fairly convertible. I've converted a parser
that normally targeted javascript, to target lua instead (it was for a project
to convert lua code into json).

~~~
gruseom
The easy way would be to make a language that compiles to the semantic
intersection of Lua and JS; that is, don't expose things that you can't easily
generate both Lua and JS for. Such a subset would cover approximately
everything I for one want to do in JS anyway.

You could make it easy to take advantage of Lua-only features like
metaprogramming by denoting them server-side only. You'd have to do that to
get coroutine support anyway.

The idea seems so exciting and obvious that I wish I had time to do it. Lua
doesn't seem to be used much for server apps, though. Why? Are there technical
limitations that make it unsuitable, or is it just that it hasn't been
exploited yet?

Another thing I'd like to know, given how embeddable Lua is, is whether one
could embed it as a browser plugin and then get the power of Lua client-side
as well. Obviously, one wouldn't demand this of users, but it would be a
pretty sweet option to offer: "install this little plugin to make the program
faster and more responsive".

One final thought. I wish Google had gone with Lua instead of making Dart. Lua
is basically JS done right. Seems to me they could have built a compelling
case around it.

~~~
chubot
I had this idea too -- I wanted to share code between command line clients,
web clients and servers. Having a language that compiled to both Lua and
JavaScript seemed eminently doable because their semantics are quite similar
(and even the syntax is pretty similar).

The thing is that Node.js has kind of solved this now, as long as you can put
up with JS. JS is ugly, but Lua is also not without its annoyances (1
indexing, and to me begin/end is a big pain over {}).

v8 probably doesn't perform as well as LuaJIT, but it's by far good enough for
most purposes.

JS is ugly, but it's even uglier to have to worry about the transliteration to
2 different languages. 99% of it will work, but it won't be "write once run
anywhere" -- we all know what a fallacy that is.

But since CoffeeScript became popular, I wonder how easy it would be to port a
subset of CoffeeScript or a slight alteration of CoffeeScript to Lua (or even
Python). I've seen MoonScript (<http://moonscript.org/>)

A third thing is that libraries would be totally different. You would have to
bind the same libraries to JS and Lua to get any kind of portability. In the
end I think that's not worth it for any project.

There's a node.js style API for Lua, but again it won't be "write once run
anywhere".

<https://github.com/luvit/luvit>

A last motivation was the C API of Lua, which is nice and simple and portable.
It seems way easier to work with that extending Node, which is tying your code
to a particular JS implementation.

~~~
gruseom
I knew someone else had to be thinking about this!

 _The thing is that Node.js has kind of solved this now_

The question is whether Lua's advantages over JS (more powerful, faster,
excellent FFI) can be exploited server-side to create significant value beyond
Node.js. If the answer is no, the idea is pointless.

 _Lua is also not without its annoyances (1 indexing, and to me begin/end is a
big pain over {})._

1-indexing is the sort of thing that could screw up cross-compilation. That's
a worry. Begin/end - I agree with you, but don't have to deal with it because
I write my JS in Lisp. Personally what I have in mind is a Lisp that compiles
to JS and Lua.

 _it's even uglier to have to worry about the transliteration to 2 different
languages._

Right. The idea lives or dies on how bad the semantic delta is between Lua and
JS (in some subset of both languages chosen for compatibility). The impedance
mismatch has to be really small to make it worthwhile. It's not obvious if
that's the case.

 _But since CoffeeScript became popular_

I don't see how the impedance mismatch argument is any different for
CoffeeScript/Lua than it is for JS/Lua.

 _A third thing is that libraries would be totally different. You would have
to bind the same libraries to JS and Lua to get any kind of portability. In
the end I think that's not worth it for any project._

Projects that don't depend heavily on client-side JS libraries wouldn't suffer
too much.

 _There's a node.js style API for Lua, but again it won't be "write once run
anywhere"._

I don't find it very interesting, since you can just use Node.js for that
style. The goal here isn't to cross-compile to Lua and Node.js. It's to cross-
compile to Lua on the server and JS in the browser.

 _A last motivation was the C API of Lua_

Right, that's potentially a big deal. For example, you could run your server
app in Lua embedded in Nginx. I know people have been working on this.

~~~
chubot
Yup. For semantics, I'm sure you can find some corner cases where closures
behave differently, and the prototypal inheritance also probably differs in
some significant ways. I haven't thought about it in awhile.

I'm not concerned too much about performance because I don't think Python is
too slow 99% of the time, and node.js is faster than Python.

So personally I don't think there is a strong motivation anymore, but if
anyone tackles it I'll try it out for sure :)

Another motivation I forgot to mention was sandboxing. Actually that was
motivation for the same idea with Python <-> Lua. I have a ton of of Python
code lying around. A lot of it can be extended by the user. I want to expose
some of these things as network services, but it is hilariously insecure to
accept Python code from users in any way. I also have a bunch of coworkers who
already know Python. So it would be cool if I could somehow have a sandboxed
Python interpreter (this has been talked about MANY times on pyhon-dev, etc.;
not doable with CPython).

One way to get that is to try to compile Python to the Lua byte code (not
portable across versions), or to Lua source code. I think the semantic delta
is even higher, so it's probably not going to work very well. You would end up
halfway to writing a Python interpreter in Lua (e.g. semantics of
dictionaries)

PyPy has some sandboxing I hear but it's too heavyweight/early right now.

Lua is really nice. I want to use it, and has advantages over Python and JS,
but I can't seem to justify it for any project. The network effects of
tools/libraries in Python and JS always win out.

------
j4mie
One thing I didn't like after a quick look at Lua is that all variables are
global by default.

    
    
        j = 10         -- global variable
        local i = 1    -- local variable
    

( from <http://www.lua.org/pil/4.2.html> )

Same with functions. To declare a function that is restricted to the local
scope, you must explicitly use "local":

    
    
        local f = function (...)
          ...
        end
    

Can any Lua aficionados explain why this is the case? Surely a better design
would be for variables to have local scope by default, and to require an
explicit "global" prefix to be globally visible? Does this ever cause problems
in real-world code?

~~~
ansible
This discussion comes up on the mailing list occasionally.

Well, the first answer to why we have global by default is history. Lua
started out as a data description where global by default was a convenience.

Local by default doesn't work so well either with nested scopes. Suppose we do
have local by default and then consider this code:

    
    
      x = 0
      function a()
        x = 1
        function b()
          print(x)
        end
      end
    

It is impossible to refer to a's x variable. This makes it harder to return a
simple counter function, for example. This is regular Lua:

    
    
      function create_counter(initial_val)
        local count = initial_val or 0
        local print_count = function() print (count) end
        local increment = function() count = count + 1 end
        return print_count, increment
      end
    

Every time you call make_counter() you get a new pair of functions with their
own internal count variable.

See also PEP 3104 for more: <http://www.python.org/dev/peps/pep-3104/>

~~~
mangodrunk

        Every time you call make_counter() ...  
    

create_counter()

If, local was the default, you would have:

    
    
        function create_counter(initial_val)
          count = initial_val or 0
          print_count = function() print (global count) end
          increment = function() global count = global count + 1 end
          return print_count, increment
        end  
    

Something like that, it doesn't seem that much worse. Also, why wouldn't the
print_count function inherit the scope of the containing context so you
wouldn't even have to have the "global" keyword.

    
    
        function create_counter(initial_val)
          count = initial_val or 0
          print_count = function() print (count) end
          increment = function() count = count + 1 end
          return print_count, increment
        end

~~~
ansible

      ... create_counter() ...
    

That's what I get for writing code on a small phone screen. :-)

    
    
        function create_counter(initial_val)
          count = initial_val or 0
          print_count = function() print (global count) end
          increment = function() global count = global count + 1 end
          return print_count, increment
        end  
    

You might not want to use 'global', because that implies global scope. And in
this case, this is not what was intended. For Python, keywords like 'outer' or
'nonlocal' were proposed.

All in all, I'd be OK with 'nothing by default', but I'm also OK with global
by default as it is now. If accidental creation of globals is a problem I can
use the 'strict' module.

    
    
        function create_counter(initial_val)
          count = initial_val or 0
          print_count = function() print (count) end
          increment = function() count = count + 1 end
          return print_count, increment
        end
    

If local was the default, wouldn't the assignment to count in increment()
create a new local variable (which is then discarded)?

------
anonymoushn
I was surprised to learn that coroutines were new in 5.0 until I also learned
that 5.0 was released in 2003.

------
pacomerh
Interesting for me to know that Lua has been used seriously for game
development. What are the main limitations?, how come people aren't developing
more in Corona rather than straight objectiveC. I'm guessing the Corona
environment itself is the limitation?.

~~~
Derbasti
Lua is pretty minimalistic. There are few batteries included. The standard
library is very basic. There is no native object system, though implementing
one is trivial.

That said, I friggin love Lua for its flexibility and transparency. Once you
grok its few basic mechanisms, everything else just falls in place. In
contrast, understanding Ruby or Python is a lot more difficult since the
languages themselves are a lot more complex.

In fact, if I were to teach programming, I would teach it using Lua.
Implementing your own object system is increadibly instructive. Learning about
coroutines and lambdas is, too. And Lua is still small enough to just read its
source when in doubt. It's bytecode consists of just a few dozen instructions.

Honestly, Lua is a marvellous language and I just love to use it!

~~~
moonchrome
>In fact, if I were to teach programming, I would teach it using Lua.
Implementing your own object system is increadibly instructive. Learning about
coroutines and lambdas is, too. And Lua is still small enough to just read its
source when in doubt. It's bytecode consists of just a few dozen instructions.

If these things appeal to you check out lisp (clojure is my personal
recommendation)

~~~
ansible
If I were using a Lisp these days, I'd really miss the Lua table.

Lisp is built around cons cells and the linked list. But it has seperate
containers of various types.

Lua is built around the Lua table, which can function as a list, array, and
dictionary/hash table. You can then build any other data structure from tables
easily. With a metatable, you then also get read-only tables, objects and
classes, and more.

Now if someone were to design a modern Lisp based around tables...

~~~
moonchrome
>Now if someone were to design a modern Lisp based around tables...

Check out clojure - advanced data structures/primitives +
immutability(functional programming)

~~~
ansible
I don't really want multiple data structure primatives though, just the one.
And have the language built up around it.

I have been mulling over better support for immutable data structures in Lua,
but I haven't figured out a good and clean design yet.

------
Difwif
I have such a strange love for Lua. It was one of the first languages that I
learned and used to program homebrew for the PSP. It's really where my journey
as a programmer began and was the first language that I programmed with for
fun. I don't think you can ever stop loving the first language you got your
hands dirty with.

~~~
vbtemp
Unless of course it's C++

</personalopinionwithouttryingtoinstigatereligouswar>

~~~
Twisol
Technically, my first programming language was C++, and I really don't love
it. ;) But that might not count: I actually started with a _markup_ language,
HTML, which I use daily.

</sameDisclaimer>

------
Angostura
If you want to tinker with Lua, Codea on the iPad lets you code in it and
create little iPad apps (for your own enjoyment).

------
generateui
Warning: this links to a PDF.

~~~
zdw
Usually PDFs get reposted to Scribd or a similar service - it's somewhat
unusual that it wasn't in this case.

~~~
icebraining
Strange but much appreciated!

~~~
pasbesoin
Perhaps the trailing octothorpe (#) threw off the HN functionality that does
this. Noteworthy.

