4 ms·
I've the feeling that Lua became popular mostly based on its implementation, fast, small and self-contained portable C code, and not for the merits of the langu
by antirez 8y ago
I've the feeling that Lua became popular mostly based on its implementation, fast, small and self-contained portable C code, and not for the merits of the language itself. Certain things are addressed in Lua 5.3, but in general Lua has several flaws:
- Before Lua 5.3 there was no integer type, this makes a lot of things harder than needed in programming, unless you just write high level code.
- Lua trivially departs from standard syntax like ==, !=, zero-based indexes, without good reasons, creating a general feeling of confusion.
- There was an odd idea about what to include by default and what was optional. The lack by default of bit operations makes the language always in need of a trivial library.
- Tables as a single data structure are not ideal for many tasks. Especially the dualism between tables that are indexed by sequential numbers and tables acting as maps. It's a lot more kind to your users to give up with the solely academical ideal of "just one data structure", and give programmers at least an ordered and a map data type, or at least come up with something better than that. Lisp attempt at doing most things with lists was much more successful and clean.
- The stack-based C API is not comfortable to use.
I could continue to be honest, for instance by default you can't type an expression in the REPL and see the value returned. However when the task at hand is to write small scripts for a larger system, the implementation of Lua offers big enough advantages to make it a worthy choice.
- enriquto 8y ago> I've the feeling that Lua became popular mostly based on its implementation, fast, small and self-contained portable C code, and not for the merits of the language itself. And this is quite fair. Those are fundamental qualities of a new programming language.
- patrec 8y agoI don't think that's a completely fair assessment. It's true that the language has some gratuitous feeling warts (not being zero based is a very severe flaw where embedding into C/C++ apps is a primary use case; it also messes up luajit and terra's UX no end, global by default is another problem, albeit one that can be mitigated with tooling). But what other language packs so much punch for so little weight? Despite being quite simple, the syntax still is expressive enough for a lot of DSL uses. Lua has proper tail recursion and an elegant co-routine design and it's slightly idiosyncratic lpeg library is worlds better than the regexp offerings of most languages. It has serious meta-programming power based on a much simpler model than e.g. python or ruby. Despite its warts lua still feels like a better (imperative, statement-based) scheme than scheme to me. What scheme offers a similar combination of speed and expressiveness for the same conceptual and file-size weight as lua(jit)? Wrt to repl: the torch7 repl is quite serviceable, so it's worth giving it a try even if you're not into deep learning.
- antirez 8y agoI agree on the value/codebase-size ratio to be great, it's why I chosen it for Redis for instance. But yet most of the things I expressed in my comment were not competing factors, since the code base would be enlarged very slightly. In fact the bigger addition that is the integer type was added in 5.3.
- patrec 8y agoI'm not disagreeing with your assessment that lua has serious warts (that have basically no upside, unlike say no "true" integer type, which has pros and cons). I'm just saying your portrayal is a bit lopsided, there are various aspects in which lua is a more elegant design than other dynamically typed languages like python, ruby, perl, scheme etc. I.e. small footprint and good embedding story are not the only merits of the language.
- antirez 8y agoI've problems at recognizing any significant part of Lua that is better designed than Ruby, from the POV of the language itself, pretending implementations do not exist. But this is just a personal POV so we could argue forever. I also bet that a very good subset of Ruby could be implemented with a similar-sized code base than Lua (but not at the same speed probably).
- ModernMech 8y ago> a very good subset of Ruby could be implemented with a similar-sized code base than Lua That would have to be quite the subset. The Ruby parser alone is almost 12kLOC. I've implemented entire languages in 1/10th that. https://github.com/ruby/ruby/blob/trunk/parse.y https://github.com/ruby/ruby/blob/trunk/parse.y
- roi 8y agomruby (http://mruby.org/ http://mruby.org/, https://github.com/mruby/mruby https://github.com/mruby/mruby) is the official attempt to do just that. Depending on what you count it's around 30-60kLOC. It has a standalone bytecode compiler, so the parser (which is "only" 6kLOC) doesn't have to be a part of the runtime.
- acqq 8y agoThat is very one sided. First it was designed to be embedded, so small size was a priority, not every imaginable feature. Second, the fact is that the language was always running faster than all “favorite” scripting language. It was also much better suited for Jit. The minimalism demonstrated obvious advantages to the competition.
- lukego 8y agoI can see where you are coming from. Just $0.02 these issues don't bother me so much in my day-to-day usage over many years (though this is with LuaJIT/RaptorJIT so YMMV.) The default numeric type (double float) can precisely represent integers up to 2^53. That's ample for most of my purposes. You can even fit x86-64 pointers into them. Syntax doesn't match C but that doesn't bother me because I'm used to other languages already e.g. Erlang that uses different operators and one-based indexing. Bit operations are always there in LuaJIT. The C API does seem awkward to me too but it's superceded by the lovely FFI in LuaJIT.
- tomlu 8y agoFair points overall, except: > The stack-based C API is not comfortable to use. What is so uncomfortable about it? I think it's absolutely fantastic. There's nothing you can't do with it, and if you really want a heavyweight "magic" binding library you can do that on top of it. But you'll find even then you occasionally need to fall back to the "raw" API.
- antirez 8y agoThe problem I've with the Lua stack API is that you have to make all the mental gym about the current stack layout. And consider that I'm a fan of FORTH and Joy and other stack based languages... But when you have N parameters on the stack, you call a function from Lua, and then you have a different layout based on what such function yields, and so forth, you basically need to comment the state of the stack in order to be able to quickly understand what's going on six months later. An example is the Redis scripting.c code where we call a Lua function to sort the Lua array result. Another problem I've with the stack API is that it's insecure by default. If you push too many things it will result in a C stack overflow. I'm not sure how much performance this gives, I mean, the inability to grow the stack automatically looks like an optimization matter... But at least, panic when we reach the max stack instead of smashing the C stack.
- akavel 8y agoI believe the Lua creators' claim on this is not that it's necessarily a good API, but rather that it's "just" a better one than any other they know of :) (Or at least knew of at the time when they created Lua. But I think if they learnt of a better one in the meantime, there's a high probability they would try it, given that they're not afraid to break backwards compatibility when they see value in a change.)
- cmsj 8y agofor Hammerspoon, we ended up building a fairly large abstraction layer that takes care of all of the repetitive/fragile stack operations for us, and it's improved our productivity significantly. Wiring up new Objective C objects to Lua is now very simple, but we can still fall back to the Lua C API when we need it. There are still quite a few places in the code though, where some complex stack operation is happening and each line of C/ObjC is surrounded by a lot of comments that describe the expected state of the stack at each step, and there have been a lot of situations where I've ended up having to sketch the stack on paper as I'm reading code, to figure out why something isn't working. So, I think I'd say that the C API is not comfortable to use, but it's also not very complicated. It's somehow managed to be simple, but hard, if that makes any sense. Edit: If anyone cares, our Lua abstraction is all written in ObjC and is called LuaSkin. It lives in the Hammerspoon git repo, but doesn't actually depend on Hammerspoon at all, so could be extracted and used by others (it's MIT licensed). The API docs are: http://www.hammerspoon.org/docs/LuaSkin/Classes/LuaSkin/index.html#//apple_ref/occ/cl/LuaSkin http://www.hammerspoon.org/docs/LuaSkin/Classes/LuaSkin/inde...
- ModernMech 8y ago> Lua trivially departs from standard syntax like ==, !=, zero-based indexes, without good reasons Having taught programming to many people outside of the programming field, one of the biggest sticking points I have found they face early on is calling the 1st thing the 0th thing, instead of just the 1st thing which is what they've been doing their whole lives. This leaves them with the general feeling that programming as a practice is nonsensical and arbitrary (and they're not wrong). It can turn off a lot of people as they grow frustrated by constant off-by-one errors, which tooling doesn't do much to catch. If Lua wants to be a language for non programmers, 1 based indexing is a good choice imo.
- heavenlyblue 8y agoThose people should not be dealing with indexing in arrays then. But frankly - I think your point is invalid as much. You call the ground floor a ground floor in English, which is different from calling it a first floor in many other languages. So it isn’t as unnatural.
- ModernMech 8y ago> I think your point is invalid as much. I'm just telling you what hundreds of people have told me. They expect the first thing to be #1. Their words. I dont see how you can call their own experiences invalid. Your dismissive attitude is another reason why so many non programmers have trouble learning programming.
- heavenlyblue 8y agoMy dismissive attitude is due to me being professional enough to tell someone to either get some proper training or stop trying to do something they are not good at in the first place. >> "They expect the first thing to be #1". I expect the laws to be easily understandable by a layman. Should I become a law-making advisor, then?
- ModernMech 8y ago
- ansible 8y ago> Tables as a single data structure are not ideal for many tasks. Especially the dualism between tables that are indexed by sequential numbers and tables acting as maps. It's a lot more kind to your users to give up with the solely academical ideal of "just one data structure", and give programmers at least an ordered and a map data type, or at least come up with something better than that. Lisp attempt at doing most things with lists was much more successful and clean. I have a different view. Lua tables are the foundation for just about any conceivable data structure in CS. While you can do a lot with raw tables in Lua, you can also use them to build all kinds of things on top of them, like b-trees. Or an object system (which is a popular hobby among Lua aficionados). There's a limit to what can and should be built into any base language. Trying to wedge in more container types can cause a bit of difficulty, in my opinion. Python is the classic example here, where you have tuples using parens, arrays using square brackets, and dictionaries using curly brackets. At some level that is clever, but at another level it is a cause of confusion.
- sulam 8y agoSorry, but tables are awful in practice. I have to iterate all the elements to get a count? This is especially egregious when I’m using one like a list/array and need to know how far to iterate. Maybe there’s a better way I don’t know?
- Twisol 8y agoIf you need something quick-and-dirty, you can maintain an extra `["length"]` field on your table to cache that information. If you want something more polished, use a proxy table with custom methods/metamethods mediating access to your array so that the length is properly kept up to date. This isn't terribly different from the situation in C with arrays. Tables are a basic mechanism for implementing any data structure. That is a qualitatively different statement from saying that tables can replace any data structure. If you need semantics different from what tables immediately provide, you'll need to implement the desired data structure yourself -- but Lua gives you good tools to do that. > Maybe there’s a better way I don’t know? You can use `for i, v in ipairs(arr) do ... end` to iterate over an array without worrying about "how far" to iterate. The `ipairs` iterator will determine when it hits the end of the array.
- smichel17 8y ago> Before Lua 5.3 there was no integer type, this makes a lot of things harder than needed in programming, unless you just write high level code. Wasn't the idea to only use lua as a high level scripting language, and drop down into C(++) if you needed to go low level?
- jpfed 8y agoExceedingly minor correction: Lua does use == in the way you'd expect it to.
- skybrian 8y agoIt's not very popular, but Wren seems like a better alternative if you'd like a straightforward object-oriented language with a small C implementation.