Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login
Lua: the world's most infuriating language? (www.slideshare.net) similar stories update story
61 points by jgrahamc | karma 89756 | avg karma 10.41 2013-10-18 04:21:21 | hide | past | favorite | 58 comments



view as:

I felt the same way, but I used MoonScript for a simple hack project and it removed a lot of the Lua annoyances. (http://moonscript.org/)

You get past most of these syntax nitpicks after a while. I wrote plenty of Lua at my previous job, but every once in while would still forget about globals by default. I really would love to know why they went ahead with that design decision, when most languages take a far more conservative approach to variable scoping.

Because the original intention for lua was as a simple extension language for non-professional programmers[1]

[1]: http://www.lua.org/history.html


It is due to the implementation used for lexical scoping. With 5.2, I actually consider it wrong to think Lua code has a global scope and it has no global get or set VM op instructions, there is however an environment. The environment's default name being _ENV and _ENV can also be local. _G is normally, in 5.2, an entry in _ENV that points to back to _ENV.

Store the environment in "global" table. Make a new environment. Point the __index of the new environment at the global table. Make __newindex of the new environment a function that throws an error.

Congradulations, you have metaprogrammed lua to only set globals explicitly. Good job!


I think of it as the C of scripting languages. You have to roll a lot of your own stuff.

I think that a better analogy is the Scheme of script languages.

I always felt that Scheme was the Scheme of scripting languages. Or is Scheme rather the Lisp of scripting languages?

One of my favorite Scheme reads was an e-mail discussion on whether it was possible to add OOP to a functional programming language, and then the author goes on to do so in a trivial amount of code. A cursory search doesn't turn up the exchange I had in mind though, or I would link it.

The video is here, although the sound quality is not great, sorry http://www.youtube.com/watch?v=_pOkOAq5jfM

So why is Lua so much faster than Python? I tried searching about this but primarily people discuss historical context. I'm curious about real language features and whys.

There is some discussion in this thread http://lambda-the-ultimate.org/node/3851 - Python is much more complex than Lua.

Partly because it is a simple language and that simplicity allows some optimisations that are hard in a more featuresome language.

There's also the history of development. Lua has always been an embedded language and the Lua team have always had an eye cocked to size and speed.

Finally, size. The Lua runtime is tiny, these days it fits into an L2 cache. If your program doesn't have a lot of data, the effects of cache locality may give you tremendous speedups.


Ok, so the difference seems 'huge' in size. But the language complexity difference doesn't seem proportionate, so I'm curious what the list of these additional python language features is.

> so I'm curious what the list of these additional python language features is.

http://docs.python.org/2/reference/datamodel.html#special-me...


Lua is a far smaller language than Python. Python's complexity makes it extremely difficult to optimize because feature A conflicts with feature B, while Lua you can make much more specific optimization code.

Python's standard methods of creating new objects off common operations also leads to huge amounts of memory being used compared ('functional programming' to use the term of the moment) to Lua's more c-like mutate-in-place standard behavior.


Ok, these comments is exactly what I hear, but leaves me more curious. What exactly is this complexity? On the surface, Python doesn't seem much more complex. It's data-structures also seem more simple to me.

if __name__ == "__main__"

Just use the dir() function on the repl and start digging.

Python is fairly simple in implementation while being as flexible as possible. Look up the concept of descriptors for something fairly difficult to optimize when you consider __getattr__ or __getattribute__. Consider also that you can directly access the __dict__ of both an instance and of the class of that instance. You can monkey-patch the class extensively or directly into it's __dict__. You can even replace the __class__ reference on instance to make it a subtype of different class (which is insanely flexible). Then there's the stuff about metaclasses, which is fairly advanced and collides with all of the other flexibility.

Basically pretty much anything not from __builtin__ or from a C extension is entirely mutable at any time. Consider one of the problems PyPy had with some packages. PyPy didn't support `locals()[42] = value`, which some packages actually depended upon. Nor does PyPy support `instance.__dict__[42] = value` which even more depended upon. Generally Python used a lot of simple concepts such as mutable dictionaries with heterogeneously-typed keys as the implementation of how classes, modules, etc works, which is flexible but very hard to optimize in any way (especially since they are mutable).


I think understand the complex reality that dynamic features arising from 'everything is a nested dictionary', and I used monkey patching once to save my life, but that seems a lot like Luas use of metatables. Is Lua less mutable?

Lua uses a register based virtual machine. Python is stack based. That is the primary difference.

Mike Pall is behind Luajit.. Get him or Lars Bak to work in a jit compiler and you language will be fast as it can be..

Of course, bad designed language in terms of performance will suffer more to get into the state-of-the-art


But , even the standard lua interpreter is faster then python

Mike Pall has noted design decisions of Python which make it much harder to optimize than Lua in the past: http://lua-users.org/lists/lua-l/2004-11/msg00083.html

Thank you, that's the kind of stuff I was looking for.

Here is one major reason: I have read that Guido van Rossum rejects all CPython patches which simply improve performance, because he thinks Python is "fast enough" and is unwilling to make the code more complex / risk the introduction of new bugs just to make Python faster.

In contrast, the Lua developers always cared a lot about efficiency, not just speed, also memory use, and even GC pause times. They simply have different priorities than the CPython developers.


... that is the strangest collection of complaints I've ever seen about Lua. He obsesses over minor syntactic quibbles like the lack of a += operator and the ~= and "not" instead of C's inexplicable exclamation marks (how does this man stand SQL?) but he doesn't dwell on Lua's bigger flaws.

I mean, 1-based arrays, weird scoping and the pairs/ipairs thing seems far more serious than the lack of a proper conditional operator (how long did Python go before it got a conditional operator?)

Lua is everything it was meant to be - a lightweight, user-friendly, safe language that runs nice and fast in spite of being very hashtable-oriented. There's a good reason it's heavily used as a scripting language for game engines and other platforms that need to let users run code provided by other users - a more "batteries-included" language would have users wiping each other's filesystems.


He does talk about arrays on slide 25 and the last slide is about the problem of global scope.

Ah. I stopped reading when wading through the ocean of performance comparisons.

I had the same initial impression, but he actually goes over and mentions how much he ended up liking Lua.

1 based indices are fine most of the time, they are mostly like 0 based yet start at 1 :) When it does become a problem is when you are reading and using binary formats and offsets, where I seem to always get off by one errors. A ternary function, iff, is soo simple to implement Lua. Scoping is just something you have to understand as with tables there is no problem with them besides a beginners understanding of them.

What you consider a minor gripe, compound assignment operator, I personally think is a flaw in the language same goes for bitwise functions instead of operators. Here is an example I posted earlier on twitter.

object = object + other

"object" and "other" here are full userdata and the code is going to malloc a new userdata and also create a new object in C/C++; which is straight away going to over write the original instance. Huh? why? += makes so much sense.

Each to there own, I can fix my issues using patches but it would be nice if I did not have to.


I have started just using iterators for stuff that starts at 0.

Might I ask, how would you implement a ternary function that should retain the lazy evaluation quality of the syntactic ternary operator?

Good points. As I was reading it, I wondered if there was some satire in the complaints. I didn't know the author's context, so I thought, "Maybe these are minor complaints from someone who famously loves the language."

What's bad about pairs/ipairs? They're just iterators, and they make the "generic for" construct much more versatile. The standard library also includes two more iterators, string.gmatch() and io.lines(), which are pretty handy. I've also used iterators to implement streams (or "lazy seqs", if you will) and something akin to Python's range().

I find nothing weird about lexical scope and the 1-based arrays don't bother me at all, but iterators are awesome.

To me, Lua's most annoying feature is that tables are the only data structure. When I was first learning Lua, I thought it was pretty cool to have one and only one very versatile data structure. Nowadays, I find it's more trouble than it's worth. Indeed, the fact that pairs() and ipairs() are separate functions demonstrates that tables are a leaky abstraction: you have to constantly think about whether a table represents a hashmap or an array or both. Luckily, Lua is very extensible and there are several ways around it.

All in all, I find Lua to be an excellent language. I wrote a utility in it at work, and most of the veterans started sweating when I told them it was written in some language they'd never heard of. As soon as I showed them the code, they were visibly relieved. "We can read this and understand it," they said. Lua's readability is a big win.


To me, Lua's most annoying feature is that tables are the only data structure. When I was first learning Lua, I thought it was pretty cool to have one and only one very versatile data structure. Nowadays, I find it's more trouble than it's worth.

To me, this harkens back to the debate about the length of a table if it has nils in it.

The Lua table is not the be-all and end-all of data structures (though it is quite versatile out of the box). However, it can be the basis for any kind of data structure you can imagine. Trees of all varieties, priority queues, etc.. The strength of the language is that there is just one fundamental data structure, and it is implemented well, and it has good syntax support in the language. There is no mental overhead like with Python where you have to use square brackets for lists and curly braces for dictionaries.


> There is no mental overhead like with Python where you have to use square brackets for lists and curly braces for dictionaries.

Seriously?


He forgot to mention objects, which are also almost-dicts in python, but with a ton of magic rules like slots and methods storing their object when assigned and whatnot.

Lua has pretty nice and lightweight prototype OOP, which boils down to a few uses of : instead of . on tables and setting the __index of the metatable to be the parent table.

That's not to say python is not an excellent language, just that lua is a lot simpler.


> I mean, 1-based arrays, weird scoping and the pairs/ipairs thing seems far more serious than the lack of a proper conditional operator (how long did Python go before it got a conditional operator?)

No. Not having a real numeric or array type is serious, '1-based arrays' is just a minor quibble about syntactic sugar.


LuaJIT has real types and arrays, as part of the ffi.

The language seems to ship with an array type and a numeric type. I hear it will soon ship with 2 numeric types instead. If you aren't satisfied with your ability to redefine the numeric type(s) to literally anything by changing 1 line in 1 header file, you can use a userdata that supports "real numeric" operations.

Welcome to HN where the top-rated comment is from someone who admits they didn't read the presentation, doesn't understand what the author was saying and manages to complain.

Brevity.

I dare to say that Lua is everything that javascript is trying to be.

0-based: you're offsetting. In C, you're offsetting a base address by a multiple of sizeof(item).

1-based: you're numbering. In Lua, an array is an optimization of a hash, and the items inserted without explicit keys are numbered one, two, three…


Will you please stop it with the array thing? Lua has no arrays... it has tables. You can use a zero index if you so please, and no one can stop you.

This is a silly thing to say. Here, let's try to write some code using 1-based indexing:

  t = {foo()}
And now with 0-based indexing:

  function capture_values_internal(idx,t,remaining,val,...)
    if remaining == 0 then
      return t
    else
      t[idx]=val
      return capture_values_internal(idx+1,t,remaining-1,...)
    end
  end
  
  function capture_values(...)
    return capture_values_internal(0,{},select("#",...),...)
  end
  
  t = capture_values(foo())
or

  function capture_values(...)
    local n,t=select("#",...),{...}
    for i=0,n do
      t[i]=t[i+1]
    end
    return t
  end
  
  t = capture_values(foo())
Gosh, that was easy, I can't wait to use 0-based indexing throughout my program.

Lua at present has full lexical scoping. Lexical scope is not "weird"; it's correct. All mainstream languages with higher-order functionality that aren't Python use lexical scope, and for good reason. It can be difficult to implement, but it's intuitive.

If you can't get past the initial complaints, try squirrel.

http://www.squirrel-lang.org/

It's basically Lua, with his complaints fixed.


I've heard almost all of the complaints before and had a few of them myself. But before tearing this guy a new one for rattling off a list of trivial-sounding complaints, be aware that the second half of the presentation extols the virtues of Lua and advises you to "get past the initial irritation."

It's weird that I see many people complaining about tables because of pairs/ipairs or trivial stuff like that, which are more nuisances than anything. The flexibility of tables/metatables make them a very powerful data structure (not unlike javascript's prototype). I've been playing a bit with it for game development and you can build some very powerful stuff just using tables.

Maybe instead of trying to use lua as another language, you should totally embrace "the lua way" and then you'll understand why their tables/metatables is the way it is.


Well played. Title intentionally plays off the "question mark in title means answer is no" meme.

I wonder if he knows that he can write a loader to fix all this stuff.

I have to save I've loved using lua recently, in my console mail-client. Being able to apply operations to messages, and do interesting things is great:

http://lumail.org/examples/

Sure there are warts, such as the lack of "+=" or "++", but once you get into the right state of mind it is a pleasure to work with.


Learning Lua reminded me a lot of Javascript. They're both weird languages with a very similar object model, and they're both very practical once you get past the initial hurdles. They both have some issues, but they also have plenty of redeeming features.

Legal | privacy