15 ms·
Lua, a Misunderstood Language (2021)
- rurban 4y agoHe completely missed the luajit criticism, on the new int data type. So Lua lost its most important implementation.
- pipeline_peak 4y agoLua doesn’t really solve anything fundamental. It’s popular because it’s small and easy to embed. But embeddable interpreters, while fun pet projects, they’re redundant and trivial. Jonathan Blow has a great explanation of this https://youtu.be/y2Wmz15aXk0 https://youtu.be/y2Wmz15aXk0 Write reusable libraries first, let people embed them into whatever scripting language/GUI app they want. Scripting languages, Linux distros, it’s all Pokémon cards.
- nonplus 4y agoI guess I don't see any misconception as the title implies. Most people I know see Lua like a toolkit. A toolkit that is cavernous, and if you use it say, as a way to manage your UI in a popular MMORPG, you could risk it's misuse compared to something more domain specific, (as we've seen with WOW RCEs over the years). To be clear, I'm not making a case against using Lua, just sharing that the developers I know see Lua as a toolkit as the author describes (outside of the title irking me a tad I found the details insightful and enjoyed hearing someone's perspective of using it for projects).
- epage 4y ago> Complaints about 1-based indexing for arrays ... > Using 1 as the initial position for an array makes sense when you’re talking like a human. If the target audience for the scrips is non-programmers, then sure. The place where I found Lua's 1-based indexing unacceptable was when Lua was being introduced at a past job as a secondary language. The problem here is that many different programmers would be infrequently modifying the Lua code. In those cases, you need as few gotchas as possible to make sure people are successful and deviating from what everyone is used to in that environment for indexing does not lead to success.
- wsc981 4y agoSometimes I port some other language code to Lua and in such cases the 1-based indexing can be tricky. Though recently I discovered using a metatable to convert the index from 1-based to 0-based and vice versa can make the porting a bit smoother wrt this issue.
- kgeist 4y agoIndeed, since one of Lua's primary use cases is bindings to C/C++/etc., whenever you have C<=>interop you have to adjust indices.
- astrobe_ 4y ago> If the target audience for the scrips is non-programmers, then sure. It kind of is. Lua was developed as a configuration language "on steroids" for Petrobrass programs. The target users were non-programmers. Nowadays, Lua allows mildly tech-savvy persons to create or modify scripts. That includes high-school kids, who typically don't give a huck about Djikstra's arguments [1] ;-) The only way to avoid language "collisions" when you program in different languages in parallel is to choose languages vastly different in syntax. 1-based indexing is not "unacceptable", it is a drop in the ocean when you use together with C or C++. Typically you forget semicolons in C because Lua doesn't mandate it, or you forget that in Lua, zero is not "false" for if, etc. Personally I write some Forth on the side too, and as both Forth and Lua have the "then" keyword but used in a different way, I often misplace it. Blaming C, Lua or Forth for any of these difficulties doesn't make sense. The only answer, really, is "deal with it, it won't be the last time unless you quit programming". [1] https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...
- epage 4y agoI'm not blaming Lua. I'm saying that the context where it is used is important and can effect whether things are problems or not. Semi-colons are a bad example, you are generally not going to have subtle bugs from those. Off-by-one bugs are already bad enough in programming, having people switch their base index between tasks will not help.
- azangru 4y agoAlso came here to comment about 1-based arrays :-) It's not about which convention is "right" and which is "wrong" — they are all conventions, after all. It's about context switching, and the additional cognitive load that a programmer coming from a language where arrays start at 0 will have. An entirely unnecessary chore.
- Jyaif 4y ago> they are all conventions, after all If we discovered aliens and learned their programming languages, which is more likely: That they use 0-based arrays, or 1-based arrays?
- lasfter 4y agoWith no prior knowledge of these aliens, neither. Why is 0 more special than 1 in your head?
- klodolph 4y agoWe've seen a lot of "drift" of different languages towards zero-based indexing, probably because it lets the compiler generate slightly simpler code. For the same reason, we've seen architectures "drift" towards little-endian, even though it's undeniably more inconvenient to read hex dumps from little endian machines.
- ModernMech 4y ago> probably because it lets the compiler generate slightly simpler code. A compiler can generate the same code either way by shifting by 1 at compile time. You might have a point if you were to say "it lets the compiler be a little simpler" but in the grand scheme of things, it doesn't really simplify the compiler all that much.
- klodolph 4y ago> A compiler can generate the same code either way by shifting by 1 at compile time. Shifting what by 1? Array address aren't always known at compile time. Neither are array indexes. I don't see how this could be done at compile time, in general, without a magically powerful compiler. I think you may be imagining that in some specific scenarios, the code generation will be the same. I'm speaking about general cases--in general, in order to generate code for array access starting at 1, you have to do a little extra computation--either to subtract an offset from the pointer to the array or to subtract an offset from the index.
- bowsamic 4y agoLua is simply too flexible for me. I don't like languages with that much "power". Paradoxically at the same time it feels verbose and unexpressive...
- bawolff 4y agoI know this is silly, but my biggest complaint is lack of shorthand ++ and += operators. I can get over 1-based, but i want my ++.
- exac 4y agoFYI These operators are being removed from modern languages now, via style guides, linters, or the language itself (eg: Swift). Personally I actually like the increment and decrement operators, but I understand how they can be confusing (especially ++x vs x++).
- bawolff 4y agoi like x++, but relying on the return value usually tends to be evil.
- Alupis 4y agoThis trope needs to die. If you cannot understand ++x vs x++ then you fundamentally do not understand the language - or programming in the more general sense. Let's stop stupifying our languages for beginners. Beginners are only beginners for a short while, and increasing verbosity with zero gain is annoying at best for everyone else.
- mynameisash 4y ago> If you cannot understand ++x vs x++ then you fundamentally do not understand the language I hardly think this is the issue. The problem is this kind of thing becomes so easy to write but not consciously notice that it causes disproportionately costly mistakes, and I don't think the benefit is worth it. Python and other languages don't have the increment operator (pre or postfix), but never has this been a problem for productivity in any of my teams. On the contrary, I've encountered several instances where a senior engineer with 20+ years in the industry can't for the life of them figure out why some particular value is off-by-one. It wastes hours of time and often takes a fresh set of eyes to figure it out. I know a senior principal engineer who wasted an entire day of his time because a comma at the end of the line turned his Python scalar into a unary tuple and was incredibly difficult to notice. "5," is semantically equivalent to "(5,)" but Python isn't strict enough in this instance. It should be strict, though, not for stupifying but for protecting against errors that we all make.
- pkulak 4y ago> When a baby completes its first roundtrip around the Sun, they’re one year old, not zero years old. Lol, well that's a terrible point to make. When a baby is born, it's 0 zero years old. Human beings literally start at zero...
- noSyncCloud 4y agoTo be fair, this is also a matter of culture and convention. > - In Korea, you are already one year old when you are born. > - In Korea, you "age" a year every New Year rather than on your birthday https://www.omnicalculator.com/everyday-life/korean-age#:~:text=In%20Korea%2C%20you%20%22age%22,to%20your%20Western%2Dsystem%20age https://www.omnicalculator.com/everyday-life/korean-age#:~:t....
- claudiawerner 4y agoSo if you're born on the 31st of January, you're two years old one day later?
- hotdamnson 4y agoDecember* and yes
- deleted 4y ago[deleted]
- hotdamnson 4y agoIf the Korean child is born on the 31st of December at 23:59 it will be 2 years old and 2 minutes old at the same time.
- colinb 4y agothat's interesting. How do they figure out school cohorts with such a system?
- Tomte 4y ago
- intrepidhero 4y agoI use Lua a fair bit in my day job. The comment about it being a minimalist toolkit that allows you add scripting on top of domain specific tools is spot on. That is exactly the use case that Lua shines in. My favorite feature is the way that tables and closures allow you build up just as much of OOP as you need for the application. It feels very empowering. I'm working mostly solo, so I've been able to establish my own conventions and stick to them. Doing this as a large team would be fraught with peril and require strict standard practices to maintain an intelligible code base. I was surprised the author didn't mention my #1 complaint, variables default to global scope AND initialized. If you misspell a variable name Lua will happily initialize it to nil and run with it. This almost always results in subtle incorrect behavior instead of an error.
- klysm 4y agoAre there any static analyzers that help with that or is it too dynamic?
- edflsafoiewq 4y agoYes, luacheck for example.
- kbruner 4y agoI always add a "__newindex" meta method to the globals table before running any code to notify when unwanted globals are accidentally created.
- kemayo 4y agoAmusingly, in a sense, your complaint about global variables is because of what you like about how generally simple Lua is plus how powerful its tables can be. i.e. The global scope is a table, and variables are keys on that table, so of course the value of any variable is `nil` because that's how tables work and Lua isn't going to special case a table just because it's a magic part of the environment. ...but, naturally, since the global environment is a table, you can set a metatable on it and require that variables be declared before you use them. :D See: https://www.lua.org/pil/14.2.html https://www.lua.org/pil/14.2.html
- tom_ 4y agoThe first item can be at any index - it just has to be the first one. Some like 0. Some prefer 1. I think my suggestion of 7, more easily reached by the right index finger from the home row, has merit.
- wtetzner 4y ago"Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration." - Stan Kelly-Bootle
- tom_ 4y agoThat sounds familiar, now you mention it. Fascinating. I wonder what percentage of my thoughts are actually original.
- 83457 4y agoCan I index by 100s so there is plenty of room between them to add more indexes later?
- Avshalom 4y agoIn Ada yes. It will work in Lua too but iterators aren't guaranteed to go in order if you do.
- Jtsummers 4y agoAda indexes have to be continuous ranges. So you'd need a type that was only every 100th number in order to use them as indexes, which I don't think can be made (I've never seen it, and looking it up I'm not seeing any way to make it). But you can select any arbitrary range as your array index, very handy as it neatly resolves the 0-/1-based issue: Choose the natural range for your situation.
- shagie 4y agoI tend to think that for a "this is a useful way to use them", that pascal did it right. Type LatLonTemp = array[-180..180] of array[-90..90] of Real Arrays may start and end at any value of an ordinal type. There are other problems with arrays in pascal (hinted at the type definition), but that the first element of the array doesn't have to be 0 or 1 or even a positive number can make some code easier to work with.
- klodolph 4y agoRegarding tables--I just don't want to deal with tables any more. You get some extra flexibility, but the cost is just too damn steep--it's like going to a restaurant and getting escorted to the kitchen so you can design your own menu. I just want to eat, damn it. > Many people don’t realise that Lua is extremely nimble. Lua can be built by compilers using the c89 standard (even though the default is c99 IIRC), using very little assumptions about the hardware it is running on. There are other languages with similar size and complexity to Lua, which are also made in C.
- abeisgreat 4y agoI highly recommend if you're interested in Lua checking out a few of my favorite Lua projects... 1. Moonscript (https://moonscript.org/ https://moonscript.org/) the compile-to-lua language powering Itch.io, it's amazingly pleasant to work with and I was amazed porting a JavaScript tool to Moonscript that the moon version was more readable despite my lack of familiarity with the language. 2. Redbean (https://redbean.dev/ https://redbean.dev/) the single-file, cross-platform binary magic web server that's been all the rage lately. Super fun to embed Lua apps into a single binary and build small web apps. 3. Pico-8 (https://www.lexaloffle.com/pico-8.php https://www.lexaloffle.com/pico-8.php) the famed "fantasy console" a fake old computer with fake old requirements that forces you to get creative as you write games and apps with the limited resources, of course, all apps for Pico-8 are written in Lua. I think the moral here (especially with the last two projects listed) if you like when computers get weird you'll like Lua. I also recently compiled the Lua runtime into wasm to make some of my scripts portable to the browser, it was simple and easy, including modifying the language code just a bit. Lua is a little wacky, but there's something so fun it brings me back to the early days of writing code when everything was simple and just a little off.
- unsafecast 4y ago> simple and just a little off. Great way to put it. It's a very charming language. Once you learn the (very few) things that are off and can trip you up, it's really pleasant too.
- confident_inept 4y agoI'll add LOVE (https://love2d.org https://love2d.org) to that list as well. Very powerful and flexible game framework, Currently working on developing a game in Minetest (https://www.minetest.net/ https://www.minetest.net/), it is also scripted in Lua.
- bckr 4y agoI'll add LOVR (https://lovr.org/ https://lovr.org/), the 3D analog to LOVE. Haven't used it personally so ymmv.
- falcolas 4y agoIf all the users barring the evangelists misunderstands something, perhaps it's not the users? My opinion is that Lua's OK, but it's certainly not my first choice when I have a choice.
- kemayo 4y agoYou'd need to define "all the users". I read this article as talking to people who're (professional?) programmers, who're evaluating Lua as a programming language that they might want to use and are comparing it to things like C / C++ / Python / etc. But I would be willing to bet money that the vast majority of people who write code in Lua are scripters. Roblox users alone probably outnumber people who're doing general-programming in Lua. For them, things like 1-indexed arrays are a particularly good idea.
- elpocko 4y agoI love Lua, it's one of my favorite languages to write code in. It's small and simple, but you can do so much with the few things it offers. Really well designed imho. I also like MoonScript[1] a lot, a language that compiles to Lua. I use it even more than Lua because I prefer its brevity and it solves one design problem that I (and many others) see in Lua: in Lua variables are global by default, but local by default in MoonScript. [1] https://moonscript.org https://moonscript.org
- synergy20 4y agomoonscript seems not under active development since 2017, last release 0.5.0 was 2016 and never reached 1.0, which is very unfortunate.
- ehnto 4y agoMy first introduction to Lua was with an online game called Tibia when I was a teenager. One of my childhood friends was really good at scripting in Lua, but was otherwise quite computer apathetic. He didn't really care for them, it was a tool to achieve what he wanted in the game. He went on to become a tradie. I sometimes reflect on that. I think it illustrates that there could be value in exposing DSLs for lots of aspects of everyday life, and that we could potentially take coding off it's pedestal so that it doesn't have a stigma of being very hard. Very hard problems are hard to solve in code, and we build complex pieces of software which are difficult, but. The core building blocks of code are really quite easy, and you can use those to achieve all kinds of things. Sometimes a power-user could utilize a DSL with ease and enable otherwise impossible use-cases if they had only a UI to use.
- AndyMcConachie 4y agoOne of the best ways to get people coding is to not tell them they're coding. Look at all the people who excel at Excel. I've seen some amazingly clever things done in Excel by people who claim to not be 'computer people'.
- f1shy 4y agoI first came across LUA as the extension language for a measurement instrument from Keithley. It was very fast to learn, pretty easy to do everything I needed (was not just a one-liner). I can attest, at least for that use case, I found it wonderful.
- habibur 4y agoA list of things that I disliked when I used lua some long time back: - No break or continue in loops. Had to move those code blocks to a separate functions simply to put a "return" mimicking break. - No ternary operator ? : or unary ++ -- - No way to count(table) which was a frequent requirement. As basic data structure for lua had been its table. And for counting you need to write a function that iterates over the elements and counts them every time. - Need to put "local" before every variable declared inside a function, otherwise by default it will turn into a global variable. - And this 1 based index. Had to put a lot of -1 in code.
- kemayo 4y agoCan't speak to whether some of this is just things that've become more convenient since you used the language, but some of these aren't the case. Ternary: you can use logical operators for it (`[condition] and [if-true] or [if false]`) in most cases. Counting arrays: the # operator returns the size of an array. (But only a table used as an array. If it's being used as a hash then you're right and you're on your own for counting it.)
- pull_my_finger 4y ago> Counting arrays: the # operator returns the size of an array. (But only a table used as an array. If it's being used as a hash then you're right and you're on your own for counting it.) Lua doesn't have arrays. The # operator will give you the length of a "sequence"
- kemayo 4y agoI was using the terminology of the parent comment. :D
- pull_my_finger 4y agoI know, but the difference is important because a lot of the gotchas related to the # operator make a lot more sense and are well defined in the manual. > A table with exactly one border is called a sequence. For instance, the table {10, 20, 30, 40, 50} is a sequence, as it has only one border (5). The table {10, 20, 30, nil, 50} has two borders (3 and 5), and therefore it is not a sequence. (The nil at index 4 is called a hole.) The table {nil, 20, 30, nil, nil, 60, nil} has three borders (0, 3, and 6) and three holes (at indices 1, 4, and 5), so it is not a sequence, too. The table {} is a sequence with border 0. Note that non-natural keys do not interfere with whether a table is a sequence. > When t is a sequence, #t returns its only border, which corresponds to the intuitive notion of the length of the sequence. When t is not a sequence, #t can return any of its borders. (The exact one depends on details of the internal representation of the table, which in turn can depend on how the table was populated and the memory addresses of its non-numeric keys.)
- tluyben2 4y agoI really like Lua, but it is not so practical in my daily work. I have two strange loves from an earlier life; Lua and Prolog (actually Mercury), but not sure how to make living with either of them. I tried with Lua and made a game/app services company with it and it went well, however around that time (2011 or so), companies here started to worry about ‘the stack’ and did not want weird things they never heard of (which is very understandable). So it worked for smaller clients who wanted solutions but not for bigger who wanted solutions that were maintainable for anyone.
- epivosism 4y agoAfter using plain lua on Roblox for about 5 years I used the new Luau with type hints and found it made a huge difference. Similar to the js => typescript transition. https://luau-lang.org/typecheck https://luau-lang.org/typecheck
- epivosism 4y agoDemo of how lua/luau profiling works in Roblox https://www.youtube.com/watch?v=BbIPalpAfaI https://www.youtube.com/watch?v=BbIPalpAfaI
- j0hnyl 4y agohttps://en.wikipedia.org/wiki/List_of_applications_using_Lua https://en.wikipedia.org/wiki/List_of_applications_using_Lua
- lizardactivist 4y agoLua doesn't stand well entirely on its own. You could write command-line utilities with it, but if you're finally leaving the traditional masochism of using C and C++ for that, then you might as well go all the way to Python or Ruby. I think Lua was always intended to be used for making other software programmable, at least that's where it seems it works best. Something to do: count and compare the number of applications written in Lua to the number of applications using Lua.
- outworlder 4y ago> Lua doesn't stand well entirely on its own. That is addressed in the article.
- Fred27 4y ago
- sdwr 4y agoI'm using Lua for a game right now (sdwr.itch.io/underlod), and it's grown on me significantly. Using tables is a bit clunky, but the flexibility is insanely powerful. The codebase I'm using has multiple inheritance, and it's implemented right out in the open, in 40 lines of code using metatables. Been dabbling with runtime function binding as well.
- fdr 4y agoSurprised nobody has mentioned LuaJIT. The engineering is very impressive; Mike Pall may know more about writing just in time compilers than any one person. It seemed to have more prominence many moons ago when it supported the latest Lua language definitions, and it is still actively maintained, but the author I suppose decided that Lua would routinely do things that made it a moving target, and version 5.1 would suffice.
- scythe 4y agoMike Pall complained that the introduction of the _ENV scope layer would make LuaJIT slower and therefore less interesting, so he let it diverge. But also, since LuaJIT is heavier and less portable, it kind of makes sense that it should have a more stable syntax, since that tilts the use cases towards more standalone projects.
- JonChesterfield 4y agoLua 5.2 + luajit with the 5.2 compat flag seems fine to me, don't feel like I'm missing anything post-divergence
- wruza 4y agoDoes it? I remember JIT issues imposed by Apple Store restrictions, but otherwise it’s just a small so/dll/dylib which is around hundreds of kilobytes in size, iirc. It can’t run on 8-16 bit cpus, but realistically would you run vanilla Lua there? ESP8266/NodeMCU comes to mind, not sure if one could target LuaJIT without JIT compiled in to it.
- ianthehenry 4y agoThis article mentions Janet as a possible "Lua replacement," which is unrealistic. It's hard to overcome Lua's inertia and familiarity. But! If you're in the market for an embeddable-or-not scripting language, and you are turned off by Lua's various idiosyncrasies, I would encourage you to give Janet a closer look. It quickly became my favorite scripting language after I discovered it about a year ago. It's great for embedding in a larger app -- it has a simple C API, and it's distributed as a single .h/.c file pair. It has a small standard library (the core composite types are immutable and mutable maps and vectors, rather than linked lists). Its first-class support for PEGs makes it a great choice for text-manipulation scripts. It can also compile statically-linked binaries (linking in the interpreter/runtime/gc) so it's easy to distribute Janet programs, unlike most interpreted languages. Binaries that only use the stdlib weigh about 1mb, if memory serves. The language is sane: zero-indexed arrays, simple module/import system, variables are block-scoped by default (the language even distinguishes between bindings and reassignable variables). And it has non-hygienic "classic" lisp macros, so you can write helpers to do anything you can think of -- great for making a little embedded DSL. No LuaJIT, though, and no metatables. And an extremely sparse package ecosystem. But it's pretty easy to interop with C/C++ libraries, so your "ecosystem" is actually broader than it looks (if you're willing to generate some bindings).
- outworlder 4y agoIf it's a C program, I like to embed Chicken Scheme (alternatively, one could embed Gambit, or Guile). They are all pretty easy to embed with simple FFI and C APIs.
- sidlls 4y agoLua is pretty terrible as an embedded language. I’ve worked on numerous applications in both gaming and outside that industry in which lua was heavily utilized to “provide flexibility.” I’ve never liked it, and I probably never will. It has too many “weird” behaviors, ranging from the not-so-bad 1-based indexing to the absolutely absurd “everything is a table, but even tables are mixed metaphors between arrays and hashtables.”
- tromp 4y ago> We usually start to count from one. When a baby completes its first roundtrip around the Sun, they’re one year old, not zero years old. And before they complete the first trip, they're 0 years old, showing that you start from a count of 0. The one is the result from the first increment. If I ask you to count the number of red balls in a bag with only 3 yellow balls, then the initial count in your head is 0, you inspect the balls one by one, never encountering a red ball, and thus never incrementing the count. And then you pronounce your final count of 0. So that's counting starting from 0. What you call "starting at 1" is not so much the start as it is the first increment, which need not arise. For arrays, the first element is the difference between a size 0 array and a size 1 array. So the choice between 0-indexed and 1-indexed is like the difference between pre-increment and post-increment. Do we associate the element with the array size up to the element, or to the array size up to and including the element? The choice seems arbitrary (personally I prefer using the same range of non-negative numbers for both, but language has a bias for associating "first" with index 1).
- ghosty141 4y agoWhile I agree about the points you made, you cant take the zeroth element out of your shopping bag, you take the first one. The array indexing operator gives you access to the nth element of your data store. IMO OPs point is valid.
- smaudet 4y agoThe point is valid, but the rationale is not, let me explain: Caring about 0 based or 1 based indexing is, to me, a sign of someone who struggles with programming in general, or is stuck doing a lot of finicky conversion between the two. Most modern, higher level languages have generally abandoned using indexing, instead (even c++) they have something like: "for x in y do z" 1-based indexing is a bit more readable, but in the end, you have hardly any benefit. There are better paradigms, algorithms, which don't require indexing at all, which IMO is the majority of what programmers are doing anyways. Even if you need to process two same-size collections at once (the majority of the remaining legitimate uses for index based looping), you are likely working pre-sorted data and should consider using a zip or pair which eliminates the need for managing indexes. You say "but aren't you just imposing your own style on others"? Not really, if we want clean, minimal code, there should be as few references to the underlying architecture as possible, even the fact that we are dealing with a list is an implementation detail (is it actually a list, a linked list, a stream, a dictionary, an event, etc...), so in the context of implementing a higher-level language, this point is not only irrelevant, but shortsighted. If you are creating and looping over lists, you are likely not doing anything interesting, which is the whole point of programming in higher level languages, to do interesting things simply, right? As for the remaining use case when we do actually want array based access, typically you find this in high-performance, architecture aware applications - then we actually want random memory access. We may even want to deal with explicit memory offset, which is what 0-based arrays are good at doing (often times the array is syntax sugar and we are literally assigning to/from pointer offsets). To bring this around to my previous statement: "Caring about 0 based or 1 based indexing is, to me, a sign of someone who struggles with programming in general, or is stuck doing a lot of finicky conversion between the two." The reason this comes up in the first place is that there is a divide. 0-based arrays are arguably much better for low level activities, and higher level languages generally left them in as a familiarity. Translating from 1 to 0 based arrays is not any easier than translating from 0 based to 1 based arrays, 1-based arrays provide just as much confusion and less familiarity in these cases. This is not a good thing. Now I suppose Lua is trying to be something weird, a "high level" low-level language. Maybe that's fine, but it is weird, and people are right to be put-off by the change. If you are looping over bananas in lua, maybe you're not really using it the way it was intended, if you are doing memory-level access then its unnecessary language cruft.
- tombert 4y agoI've only played with Lua a bit in Pico-8. At first I hated it, but I've grown a bit of a begrudging love for it. The language is absurdly flexible, and that's a good and bad thing, but I'd say the language is, overall, more good than bad.
- yuvalr1 4y agoAs someone who is yet to have the chance to use Lua but heard about it a lot, I'm very happy to read this article. It's so useful to hear how a programming language should be used. Understanding the philosophy behind the language and what are the use cases for it are super helpful when you want to select the right language for the job. Unfortunately it is so common today to skip these important details when describing a language. Even the official lua.org website doesn't include the "toolkit" description, and puts the focus on the language's traits, which are only half helpful. Thank you so much for the article!
- diffxx 4y agoLua is misunderstood because it looks like superficially similar to a number of other languages but has a unique value proposition that is rarely well explained. The frustration that ensues from trying to use lua as though it is javascript or python or c is real. Because the value proposition isn't well explained, one has to use it and gain experience with it to appreciate it. One of the key differentiators for lua is that it has multiple implementations that are both rock solid and will work on essentially any computer that you are likely to ever work with. Luajit is api compatible lua 5.1 (with a few 5.2 features backported). Lua 5.1 came out in 2006, which is to say that when writing lua 5.1 code, you are targeting a language that hasn't really changed in 15 years. This is incredibly liberating because you can trust that any code that you write in luajit or lua 5.1 is likely to work essentially forever (modulo security issues of course). Lua is also one of the most simple languages out there. Pretty much everything that you need to know is in the reference documentation, which is a single file that you can easily download and store for offline use. It also hasn't changed in a decade and there is no reason to expect it will in the future. Simplicity begets simplicity. As simple as lua is, you can make it even simpler by restricting yourself to a limited subset of the language. The more you restrict yourself, paradoxically the more liberated you are. You eventually realize that you can express any computational problem in lua. Lua provides an implicit vm that serves as an idealized model of a computer. It has numbers, strings, arrays and associative arrays (with a uniform syntax for both types of arrays). This is enough to do pretty much anything without too much pain. The lua runtime itself is fast enough to do most programming tasks faster than you can perceive. For the remaining tasks, you can just implement them in c and call them from lua. But you won't be writing normal c, you will be writing your own dialect of c that itself reflects lua. Many of the problems of c, particularly around memory management, are avoidable when the c code is explicitly designed to be embedded inside of a lua program. Continuing on the theme of simplicity, lua is also one of the fastest scripting languages with respect to startup time (EDIT apologies for the poor formatting below but console output doesn't work great with HN): bash-5.1$ time lua -e 'print "Hello, world!"' Hello, world! real 0m0.004s user 0m0.002s sys 0m0.002s bash-5.1$ time python3 -c 'print("Hello, world!")' Hello, world! real 0m0.034s user 0m0.024s sys 0m0.007s bash-5.1$ time node -e 'console.log("Hello, world!")' Hello, world! real 0m0.062s user 0m0.049s sys 0m0.011s bash-5.1$ time ruby -e 'puts "Hello, world!"' Hello, world! real 0m0.086s user 0m0.062s sys 0m0.021s The lua startup time is actually comparable to a standalone c executable: bash-5.1$ time printf '#include <stdio.h>\nint main() { puts("Hello, world!"); return 0; }' | gcc -x c -o a.out - && ./a.out "on mac os, there are some checks that are run the first time a new exectuable is called so do one dry run before timing the results" > /dev/null; time ./a.out real 0m0.074s user 0m0.050s sys 0m0.021s Hello, world! real 0m0.002s user 0m0.001s sys 0m0.001s Comparing startup time may seem silly, but it raises the question how exactly you are benefiting from the excess complexity relative to lua that those other language runtimes have. You also can exploit the fast startup time to create a low latency development experience with minimal tooling. Configure your editor to save lua files with every keystroke. Then in a shell window, run something like: > ls foo.lua | entr -c time lua foo.lua You might be amazed by how much you can do in a lua script before the the latency becomes noticeable. By timing the results, you are also immediately aware of the impact on performance that any change to the script might have. This enables you to have an entirely different kind of development experience in which you are always fully aware of the state of your program because you are never waiting for compilation. The program either does what you expect it to, or it doesn't. No time is spent in the liminal state where one suspects the code may be correct (or incorrect), but you aren't really sure. You start realizing that if you organize your code in a certain way, you almost never have to wait more than say 100ms to get feedback. On top of all that, if you don't like the syntax of lua, you can write a parser for another language in pure lua. Your new language, which will transpile to lua, will automatically inherit the good properties of the lua runtime. Mastering lua will completely change the way that you think as a programmer and has the potentially to radically improve your experience of programming. Of course, once you have mastered lua the next step is to go beyond lua...
- newobj 4y agoImportant to call out the TypeScriptToLua project (https://typescripttolua.github.io/ https://typescripttolua.github.io/) which is incredibly robust. This is a best of both-worlds situation -- extremely robust typing, but able to drop down to raw Lua when needed (or integrate with a blended Lua codebase), and if you're running on LuaJIT, still performant as hell. (People tend to overlook how sophisticated LuaJIT is - in many benchmarks it can keep close pace to v8)
- SuperV1234 4y agoI would love to use this in my C++ game engine. Can I somehow embed it in my C++ application without having to use Node?
- newobj 4y agoYou just compile TypeScript to Lua at build time. Then run in the Lua in your Lua VM which you've presumably embedded in your game. If you wanna do this at runtime, well, I suspect a node-like environment would be required at runtime.
- ir193 4y agooff the topic, how is the "Mentions" secion in that page implemented?
- soapdog 4y agoIt uses WebMentions. Some sites send it directly to my site, in other cases I use a SaaS such as brid.gy to implement it.
- SuperV1234 4y ago> Using 1 as the initial position for an array makes sense when you’re talking like a human. I don't care. Every other popular language uses 0-based arrays. Using Lua is a massive pain because I have to change my mental model for a basic computer science structure compared to all other languages I use.
- cjohnson318 4y agoI don't know, I'm used to zero-based semantics, but I've used MATLAB and R a bit, and it's not that hard to switch gears. My biggest problem is usually figuring out which library to use in a given ecosystem, and how to use it.
- JonChesterfield 4y agoMassive pain is overstating it I think. Plus there's almost certainly a patch out there that changes it to zero based.
- squarefoot 4y agoTaking the opportunity of this thread to suggest a look at TekUI, a self contained Lua GUI toolkit. It's quite old but full featured and multiplatform. Years ago I played with it also on embedded boards (Allwinner A10 if memory serves) using both X and the framebuffer. Looks like it is unmaintained, which is a shame because it has great potential. http://tekui.neoscientists.org/ http://tekui.neoscientists.org/
- fasteo 4y ago>>> Lua should be considered a toolkit Spot on. I don't see myself writing a complete app using Lua, but there are quite a few powerful examples of Lua as a DSL, running embedded in a larger app. Openresty (nginx + Lua + LuaJIT) is probably the most popular example. I have been using it for heavy network applications with great success. Heavily opinionated, but I am yet to see a data structure more flexible and powerful than Lua tables. And I have seen a lot ... started programming with the Sinclair ZX81 ... [1] https://openresty.org/en/ https://openresty.org/en/
- dang 4y agoDiscussed at the time: Lua, a Misunderstood Language - https://news.ycombinator.com/item?id=25796852 https://news.ycombinator.com/item?id=25796852 - Jan 2021 (134 comments)
- outworlder 4y agoHaving heard _insane_ crap like "Noone uses Lua in production" at a Fortune company (while the genius who uttered that sentence had a device in his pocket that was _definitely_ running Lua), I agree that it's a misunderstood language. However, if anyone went as far as learning about things like arrays indexed at 1, they are far more aware than the average software engineer. They actually spent time looking at it. Lua is a victim of its own success. It's small(the runtime is tiny and can be made even smaller by shedding features), it's mostly uncontroversial, it does the job, it's fast. It can be easily sandboxed so you don't hear much about vulnerabilities. It's just there, invisible, in almost every modern computing device. The games industry is an exception. They have readily embraced it, for very good reasons. Browsers should have used it from the get go, but that ship has sailed. Next time you think about having scripting abilities in your application, consider Lua. Same way someone should consider Sqlite if they are contemplating creating a new file format for their application. It's a pretty good tool.
- hajile 4y agoLua's problem is that JavaScript exists. They are fairly similar, but there are a lot more JS devs. QuickJS is about the same speed and size, so a lot of teams seem to be gravitating in that direction.
- PaulDavisThe1st 4y agoThe Lua scripting interface for Ardour, the cross-platform GPL'ed DAW: https://manual.ardour.org/lua-scripting/class_reference/ https://manual.ardour.org/lua-scripting/class_reference/ We bind the majority of the backend (written in C++) to Lua, and provide access to GUI actions also. It is magic, and wonderful, and we probably should written more of the application itself using Lua.
- aeturnum 4y agoMy first real job was mostly working in Lua and, to me, the real warts are the weird edge-cases in how Lua behaves. It's been a while, but IIRC I remember getting caught by how Lua will not insert nil into the array values of a table, but it will skip the index, so you end up with gaps in your tables' values unexpectedly. example: a = {1, 2, 3, nil, 4} for i in pairs(a) do print(string.format("%i -> %i", i, a[i])) end [...] 1 -> 1 2 -> 2 3 -> 3 5 -> 4 There are just tons of little quirks like that in the language. They don't matter if you are doing light work, but they come to be really important for more developed things. I still love it, but compared to other dynamic languages you needed to be super careful about types and values and data consistency in a way that caused development to slow.
- haunter 4y agoI learned Lua in the summer of ~2010 with the WoW addon book from the creator of Deadly Boss Mods https://www.amazon.com/Beginning-Lua-World-Warcraft-Add-ons/dp/1430223715 https://www.amazon.com/Beginning-Lua-World-Warcraft-Add-ons/... It's a bit outdated now but WoW still supports Lua addons. And it was a useful experience, still today. Not just the language itself but how to build mods for games
- tayistay 4y agoI use Lua as a user-facing extension language to write modules in my music synth app [1]. Though I'm used to zero-indexing, the one-indexing never bothered me much. None of my beta testers have complained about it. I think it's a good language for beginner programmers, which most of the users are. [1] http://audulus.com http://audulus.com (the Lua-based modules are in version 4, now in beta)
- Zamiel_Snawley 4y agoEmbedding Lua instead inventing your own DSL is often the right choice. Two projects that come to mind in this respect are Neovim/Vim and AwesomeWM/i3. Neovim and AwesomeWM use Lua for configuration and scripting instead of inventing their own language/format. Vim and i3 do have their own languages. I really like having the same basic tools for scripting in multiple programs.
- mdbauman 4y agoAs a fan of Lua, one complaint not mentioned in the article but that I think is relevant if you're starting to learn the language is that minor releases often contain breaking changes. This is fine - the maintainers can number things however they want I guess - but can be a bit annoying if you're expecting to read the latest 5.4 reference manual and then write an embedded script for something using a different 5.x runtime. This is mostly relevant because when people talk about Lua's speed, they're usually talking about LuaJIT [1] which (iirc) was based on 5.1 and backported many 5.2 features. So, if you're someone who's decided to use Lua for a specific use case, you may want to see if your target specifies a specific Lua version (ex. Roblox, LÖVE, PICO-8, OpenResty are mentioned in this thread and all use either LuaJIT or a subset of 5.1), or if you expect to need the performance of LuaJIT in the future. Edit: formatting [1]: https://luajit.org/luajit.html https://luajit.org/luajit.html
- soapdog 4y agoLua versions are thoroughly explained in their documentation page which includes a page on versioning: https://www.lua.org/versions.html https://www.lua.org/versions.html The very first section in that page is explaining how the versioning works: The releases of Lua are numbered x.y.z, where x.y is the version and z is the release. Different releases of the same version correspond to bug fixes. Different releases of the same version have the same reference manual, the same virtual machine, and are binary compatible (ABI compatible). Different versions are really different. The API is likely to be a little different (but with compatibility switches), and there is no ABI compatibility: applications that embed Lua and C libraries for Lua must be recompiled. The virtual machine is also very likely to be different in a new version: Lua programs that have been precompiled for one version will not load in a different version. LuaJIT is fast but that doesn't mean that PUC Lua is slow. A lot of people say that Lua is fast when comparing it with other languages which are perceived as slow such as Python or Ruby, they might be talking about PUC Lua. Others are saying Lua is fast and comparing it to JS, C, and other fast languages, there is a great chance they're talking about LuaJIT. Anyway, I just wanted to say that PUC Lua while slower than LuaJIT and slower than many other languages is still speedy enough for most use cases it was designed for.
- soapdog 4y agoAuthor here, thanks for linking my article. It is a bit of a curse that every time this article ends up anywhere, the discussion quickly devolves onto the merits of 0-based indexing. I have a very strong opinion on this which is that "it doesn't matter". You use whatever paradigm is real in the language you're working. The context switch is not larger than the context switch between languages anyway. Lua is not the single 1-based indexing language out there, it used to be much more prevalent. I bet if JS had used 1-based indexing, half the people on this comment threads would just be praising the benefits of 1-based indexing. Sorry for the rant, but the reason I wrote that article in the first place is because I of such threads. One thing I agree with many people here is that my baby example is not the best example. It is not wrong, but it is phrased in a confusing way. I'm tempted to edit the article and fix it or replace the example with something better. After all, the example is not important, it was just an example. One aspect that many people don't realise, one that I couldn't really dive into in the article, is how simple and small the Lua source-code actually is. IIRC it is about 70 files of plain old C that can be compiled by any C99 compiler. That is very refreshing. The amount of power and flexibility you have with Lua when paired with the simplicity and maintainability of the Lua source-code itself is something we should all cherish and praise. Lua is small and nimble, it is small enough that you can vendor all of it in your project if you so want. Anyway, I like 1-based indexing, they make my loops prettier. And yes, it was just a joke, I'm using iterators like everyone else and indexing hardly matter.
- topaz0 4y agoOof. I feel your pain on the indexing arguments. Thanks for the post, I found it informative.
- kangalioo 4y agoI think the reason is that the indexing paragraph comes across as quite misinformed. The age of the baby would be 1 year even in 0 based indexing (age is a duration, not an index). And pointers are only one of many places where 0 based indexing is more natural.
- bsder 4y agoDidn't Adobe(?) post a full presentation about what they learned doing Lua for a full application (Lightroom maybe?)? Overall, it wasn't great. Unfortunately, I can't seem to find it anymore. I wonder if the HN hivemind can cough it up.
- imbnwa 4y agoPretty sure everything about OOP in here also applies to JavaScript
- ordiel 4y agoThe saddest of all this is the fact that "it is a lean platform that allows you to build what you want" (basically 'no bateries included') is considered as something to be praised, like "Look how small and simple its source code is"... Well of course it will be small and simple and there are few files that needed to be compiled for the whole thing, but in the "remote case" that you want to build anything meaningful with it you will need to write the other 1500 files (most certainly with "not as clean code") that many other more mature languages already have Just don't be a hipster... In deed most languages created past C++ have added very little innovation, its just "my own vanilla flavor" (yet it is still vanilla) some, very few indeed, have added valuable syntactic sugar, yet how I wish new languages stopped being created pretending to excel at a corner case that gives you "huge benefits" (which of course are all thrown to waste when you realize most of your application cycles and latency actually comes from other places rather than such corner case. This is not an argument for "new* languages are bad" , rather one of "until trully needed reinvent the wheel" and I think that will happen when we finally get to use qbits and new paradigms of coding/logic arise (basically an architecture change)
- JonChesterfield 4y agoThere are loads of libraries for lua. You can either get them from luarocks in modern fashion or as more ad hoc source code in the old school. They're either written in C, against a stable language API, or in lua. Or a mix, doesn't make much difference. Also you can splice them directly into lua itself, e.g. the interpreter I use has libuv and sqlite built in. The argument against shipping everything with the language is that the standard library is where code goes to die. Once shipped, fear of breaking users tends to block all progress. See mature languages like python and c++. And regarding lack of innovation, lua has coroutines in the base language. Real ones that don't need co_await written near them. It has a module system built on dictionaries. It ships the compiler, so writing source code that you eval on the fly works out of the box. Lua is spectacularly good. We are blessed to have it available.
- alwillis 4y agoThanks to Lua, there’s been many new plugins written for Neovim, which has a ton of momentum behind it as a modern fork of the venerable Vim editor. Neovim comes with Lua 5.1 and LuaJIT, so these plugins are fast. And while Lua isn’t without its issues (no language is perfect after all), the majority of Neovim’s users have taken to Lua instead of VimL, which is essentially a DSL for Vim. Neovim runs virtually all of the old configurations and plugins, since version 0.5, Neovim can be configured almost entirely using Lua. What’s also interesting is Neovim attracting lots of new users and creating lots of new Lua programmers. Many of the core contributors aren’t your typical grey-beard types, which is refreshing to say the least. They’re not hung-up on 0-based indexing and all of the other crap people often bring up regarding Lua. Some of them are on YouTube and Twitch live streaming sessions of them configuring and creating plugins for Neovim, all in Lua. This alone is introducing tens of thousands of viewers to Lua programming. It’s been quite something to watch a new generation bringing new life to the Vim/Neovim ecosystem and role Lua is playing.
- amai 4y agoThe world would be better if we had Lua in our browsers instead of Javascript.
- deorder 4y agoThey are both prototype-based languages influenced by Self.
- atemerev 4y agoLua is one of the best looking programming languages from the aesthetic point of view. Two languages have achieved the perfect syntax, in my opinion: Lua and Standard ML (maybe also Inform 7, but this is a work of art, not a general-purpose programming language). All others have some compromises.
- wscott 4y agoSo Lua is the new Tcl. A lightweight scripting language designed to be embedded in other programs. Then I went and looked at http://tcl.tk http://tcl.tk and it appears the current maintainers of Tcl forgot why it exists as well. ;-) Everyone hated Tcl back in the day for similar reasons. Too lightweight, no serious language features, etc... Maybe we should just use Scheme.
- cmacleod4 4y agoNot to mention that Tcl also has an article about how it's been misunderstood, see https://news.ycombinator.com/item?id=4920831 https://news.ycombinator.com/item?id=4920831 and https://news.ycombinator.com/item?id=31129936 https://news.ycombinator.com/item?id=31129936 :-)
- picsao 4y ago