[HN Gopher] Lua, a Misunderstood Language
       ___________________________________________________________________
        
       Lua, a Misunderstood Language
        
       Author : todsacerdoti
       Score  : 76 points
       Date   : 2021-01-15 21:35 UTC (1 hours ago)
        
 (HTM) web link (andregarzia.com)
 (TXT) w3m dump (andregarzia.com)
        
       | virtue3 wrote:
       | As someone that worked on LuaJIT for embeded devices (IE phones),
       | I have some strong opinions / context.
       | 
       | Lua is designed to be small and portable and highly embeddable.
       | It's not the greatest language in the world, but understanding
       | it's interpreter and how to use it from your system side is
       | pretty easy as these things go.
       | 
       | It's really REALLY well suited to be embedded into whatever
       | system you need it in. The whole runtime is like nothing.
       | 
       | And it runs damn fast for an embedded language, there's like 10
       | opcodes or something? compared to pythons 100+ (at the time we
       | did the comparison like 10 years ago).
       | 
       | Further context, I think we ported our android luaJIT to windows
       | phone 7 in like, a day? It was super trivial.
        
         | monocasa wrote:
         | I count around 100 opcodes for luajit as well.
         | 
         | http://wiki.luajit.org/Bytecode-2.0
         | 
         | Not sure why reducing the number of ops by an under of
         | magnitude would make it go faster.
        
           | lrossi wrote:
           | Empirically, it is much faster than Python, but I don't know
           | either if the opcodes have anything to do with it.
        
             | monocasa wrote:
             | Right, but reducing the number of ops wouldn't get you
             | there, that just adds more branches in the critical path as
             | the same amount of functionality needs to be overloaded.
        
         | mobilio wrote:
         | Lua it's very popular on routers because it's using on some
         | device vendors like Linksys and some opensource distributions
         | like OpenWRT
        
       | [deleted]
        
       | noizejoy wrote:
       | I've discovered Lua only very recently as it has a good presence
       | in some music making applications for scripting e.g. for the
       | Steinberg HALion sampler/synth and for Native Instruments Creator
       | Tools.
       | 
       | And more recently I bumped into the interesting VST/AU plugin
       | called protoplug[1], which makes it easy to experiment with
       | coding audio and midi event processing inside a DAW.
       | 
       | [1] https://www.osar.fr/protoplug/
        
       | austinl wrote:
       | Oddly enough, Lua was my first introduction to programming. I was
       | into Valve's Half Life games and Garry's Mod, and Lua was
       | typically the way that you'd make modifications to things (e.g.
       | increase player movement speed). That would interact with the
       | Source engine, which was in C++, but you could do a lot of stuff
       | without ever touching C++ [1].
       | 
       | I didn't even really think of it as programming at the time. You
       | start by just changing constants, like what if we make gravity =
       | 2 instead of 9.8 m/s2? And then build up from there. I think is
       | what a lot of these educational programming games try to
       | replicate today.
       | 
       | After a while, I got confident enough to the point of trying to
       | do things in LOVE, which is a free and open-source 2D game engine
       | that uses Lua [2]. What I learned there is the reason why I
       | eventually studied computer science in college. That said, when I
       | return to Lua, it feels a bit limited, but I suppose that's the
       | point! I never really questioned it at the time.
       | 
       | "Lua is not object-oriented. That is it." Laughed out loud when I
       | read this. It was funny to learn programming without the concept
       | of classes, and then realize that Lua is the exception, not the
       | rule.
       | 
       | [1]
       | https://developer.valvesoftware.com/wiki/Embedding_Lua_in_th...
       | [2] https://love2d.org/
        
         | deergomoo wrote:
         | Lua was mine too, also via games. I'd installed custom firmware
         | on my PSP and after getting my fill of emulators and rampant
         | piracy, I wanted to see if I could make a game. Getting the
         | C-based toolchain working was far beyond 12yo me at the time,
         | but there was a "Lua Player" homebrew application that would
         | load scripts off the memory stick.
         | 
         | I didn't get far with it and to be honest I remember very
         | little, but it did set me off down the rabbit hole of learning
         | to program, and now it's both my career and a big passion.
        
         | andrewmcwatters wrote:
         | Thanks for linking my article. I went on to go build Half-Life
         | 2: Sandbox as an open-source competitor to Garry's Mod, and
         | later Planimeter's Grid Engine, which is also based on LOVE.[1]
         | 
         | [1]: https://www.planimeter.org/grid-sdk/
        
       | d--b wrote:
       | As a dev who's only tried Lua for a small dev project, I have to
       | agree with the no-batteries argument. It is so bare that i ended
       | up implementing tons of function that i wished were there in the
       | first place.
       | 
       | Not asking for lua to become the new javascript but a library
       | like "lodash for lua" would be appreciated...
        
         | dividuum wrote:
         | There's https://github.com/danielmgmi/lodash.lua :-)
         | 
         | And also https://luafun.github.io, which probably has
         | overlapping functionality and is optimized with regards to
         | LuaJIT.
        
       | epage wrote:
       | > Complaints about 1-based indexing for arrays
       | 
       | I think this misses the point, at least for my case. It doesn't
       | matter which is technically better. What makes more sense for
       | humans is a matter of application (and even "non-dev" stuff
       | varies as to which is better).
       | 
       | For me, my big concern about using Lua in my products is
       | 
       | - I expect other developers to be writing the Lua scripts
       | 
       | - I expect the developers to be frequently using 0-indexed
       | languages
       | 
       | In this scenario, "being different" means you are likely to run
       | into off-by-one errors. Think of that crufty Perl script you
       | might have around at work where people avoid touching it because
       | no one is comfortable enough with Perl. Having predictable
       | semantics helps a lot in scenarios like this.
        
         | phaedryx wrote:
         | There are only two hard things.
         | 
         | This is an aside, but I think that "index" is the wrong name. I
         | wish that "index" meant you start counting at 1 (which everyone
         | outside of CS does) and "offset" was the name for starting at
         | 0.
        
           | nvader wrote:
           | 1ndex and 0ffset. I like it.
        
             | d3ckard wrote:
             | I _love_ what you did here. Great mnemonic!
        
           | Pet_Ant wrote:
           | I think I will intentionally start using this usage. Maybe we
           | can make it a thing. I mean we already have argument &
           | parameter for similar things to make a distinction.
        
           | zajio1am wrote:
           | > (which everyone outside of CS does)
           | 
           | In set theory (math foundations), ordinals also start at 0.
        
         | mumblemumble wrote:
         | So, I don't do a lot of Lua programming - basically just having
         | fun with Pico-8 on occasion - so I can't say I have a _lot_ of
         | experience with this. Every single other language I use starts
         | at 0.
         | 
         | But what I have seen is that, starting from 1 felt weird to me
         | for approximately 1 hour, tops. After that, it was no more or
         | less of a switching challenge than switching between semicolon
         | languages and non-semicolon languages. In other words, no big
         | deal. And, once I got over it, I was pleasantly surprised to
         | find out that I actually have _fewer_ off-by-one errors in Lua
         | than I do in other languages. Because the author is right: No
         | matter how much professional experience I have starting with 0,
         | starting with 1 is still the more innate way of thinking.
         | 
         | Also, my single biggest all time source of off by one errors is
         | translating between mathematical notation and code in a 0-based
         | language. That fact alone is cause for me to hope that Julia
         | might one day supplant Python for data work.
        
           | bsder wrote:
           | I'm glad that's true for you, but my personal experience
           | suggests otherwise. Dijkstra also mentions the Mesa
           | programming language which had all four of the conventions
           | and that other than 0-based, half-open leads to errors. See: 
           | https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E.
           | ..
           | 
           | And for those claiming the world is 1-based, they're full of
           | it. Machining measurement, for example, is _ALL_ 0-based. And
           | we 're talking a field that has multiple standards for
           | _everything_ and yet they converged on 0-based measurement.
           | 
           | The bigger problem, though, is that I even have to use array-
           | based indexing to iterate something. That's just asking for
           | bugs.
           | 
           | And, my favorite question for people who like 1-based is
           | "Given index n, how do I create index n-1?"
           | 
           | The answer, of course, is newindex = index - 1 % N.
           | 
           | The question is, of course, a trick because the answer is
           | _really_ : newindex = (index - 1) % N.
           | 
           | Yeah, no. I'll stay in my 0-based languages thanks.
           | 
           | Side Note: I have other objections to Lua. The big one being
           | that it's not _really_ compatible between Lua installations.
           | Everybody compiles different modules so Lua becomes neither
           | small nor is it the same language between any two
           | implementations.
        
         | brundolf wrote:
         | Agreed. 1-indexing may be more intuitive for humans broadly,
         | and this may have been a good argument before C became
         | ubiquitous, but when it comes to programmers 0-indexing is a
         | deeply ingrained habit and the landscape of what's intuitive is
         | different. Very few norms are so universal across programming
         | languages as 0-indexing
        
           | d3ckard wrote:
           | That's more dependent on language syntax IMO. When you have
           | traditional C-style loops, maybe. When you use ranges,
           | iterators etc. it doesn't make any difference.
        
         | berkut wrote:
         | Yep, I think consistency is key here...
         | 
         | Especially when it's used as an embedded language in a C/C++
         | app, or an additional Lua API alongside other APIs that exist
         | already.
         | 
         | Having to convert back and forth between 0 and 1 based indices
         | is very annoying, and error-prone. You can make helper methods
         | to abstract _some_ of it, but that only gets you so far, and it
         | 's annoying (at least I found it that way) having to context
         | switch your brain depending on what part of the call stack
         | you're looking at.
        
         | noizejoy wrote:
         | It doesn't miss the point, because the point was that non-
         | developer humans will do better with 1 based indexing.
         | 
         | Side note: As a former developer, turned regular human being
         | who scripts from time to time, I don't find switching between 0
         | based and 1 based indexing particularly intellectually taxing.
        
           | TulliusCicero wrote:
           | Yeah I have a bunch of complaints about the language that I
           | developed while learning it and simultaneously teaching my 9
           | year old kid, but the 1-based indexing isn't one of them.
           | That's totally fine, and certainly easier to grasp for a
           | beginner.
           | 
           | But there's certainly other stuff that's just weird and bad,
           | and I think just the fact that it's dynamically typed made it
           | harder for him to build an accurate mental model -- sometimes
           | he didn't even realize that an identifier that he had typed
           | in earlier was a variable, let alone what kind of value it'd
           | be holding.
        
           | billfruit wrote:
           | Wait till you need to use a formula which has somewhat
           | complex uses of indexes like 2^(2n+1) and see how having deal
           | with them in 1-base indexing in addition to 0 based indexing
           | makes it add bit of unnecessary confusion.
        
           | craftinator wrote:
           | It's not an intellectually challenging context switch, which
           | is actually what makes it such a problem. You don't have to
           | think about it, because it's so simple and easy, so sometimes
           | you won't even think to do it.
        
           | zajio1am wrote:
           | Well, i started programming in Pascal (with 1-based indexing)
           | and later switched to C. I remember that after switching to C
           | off-by-one errors magically disappeared.
        
         | remram wrote:
         | Doesn't it bother _you_ as the person writing both the
         | application and the original scripts, to be using both styles
         | at once in the same product (sometimes to refer to the same
         | data)? Nevermind the end-users ' additions.
        
       | TulliusCicero wrote:
       | Sounds like the author is talking about me.
       | 
       | I'm a programmer who recently started teaching his 9 year old son
       | Lua, so that he can use the Undertale fan game platform Create
       | Your Frisk. It's gone okay, but there are things about the
       | language that just seem weird and annoying and counterproductive.
       | 
       | For example, tables are very important in Lua as a sort of all-
       | purpose data structure, that's cool and all, but why is there no
       | built-in copy function? The author of this article seems to be
       | hinting that this anti-batteries-included style grants some sort
       | of freedom to do it myself, which is just kind of silly. I don't
       | want to do it myself -- and there's a good chance I'd cock it up
       | if I tried -- my son certainly isn't going to do it himself, and
       | even if they had provided such a function, that doesn't actually
       | stop anyone from doing it themselves anyway, if they want to.
       | 
       | Or, why are there not only no increment operators like ++, but
       | even no operators like +=? "counter = counter + 1" isn't only
       | longer to type, it's harder to quickly parse. Why is the standard
       | style for multiword identifiers neither camelCase nor
       | underscore_case (or whatever it's called), but instead just
       | runthemalltogetherit'stotallyfine? Why is the default for the
       | random number generator using the same seed every time you run
       | the program, and why does os.time() provide time not in
       | nanoseconds, or milliseconds, but solely in _whole_ seconds? Why
       | doesn 't the runtime complain if I pass in a completely non-
       | existent variable as an argument into a function?
       | 
       | While the teaching has gone fine overall, the language actually
       | works against our purposes by making it harder for my son to
       | build a mental model of what's happening. The last point in the
       | previous paragraph, for example: it's much more confusing for a
       | newbie coder to have to deal with a 'sudden' nil value that they
       | weren't expecting, than to have a compiler or runtime just crash
       | and say "hey, I don't recognize this variable at this line
       | number". And yes, this isn't hypothetical, this actually happened
       | while I was teaching him.
       | 
       | Same thing for the dynamic typing, and default global status of
       | variables. The lack of 'declaring' variable types, or even that a
       | thing is a variable at all, has meant that it's been more
       | confusing for him to identify what kind of value a variable is
       | holding, or even that an identifier is actually a variable at
       | all. That variables are by default global has made it harder to
       | teach him about passing in arguments -- he'll happily pass in
       | some variable as an argument, and then use _that_ variable name
       | within the function, rather than the argument name defined in the
       | function signature. These are the kinds of beginner-level
       | problems that you forget about as an experienced programmer, but
       | when you teach a kid, suddenly become very real.
       | 
       | As I was using the language and teaching with it, I just couldn't
       | help but feel that more modern statically typed languages like
       | Swift or Kotlin would be flatly superior for the task of
       | instructing a young mind on the the most fundamental task of
       | beginner programming: getting them to build an accurate mental
       | model of "how this actually works, how does everything relate to
       | each other". You would get the enforced structure of older static
       | languages, but with more modern syntax and ease of use. To me,
       | it's hard to see what Lua would offer as an advantage, really.
       | But then again, I'm an Android developer, so maybe it's just my
       | own experience biasing me.
        
         | rstupek wrote:
         | A lot of those issues relate to the fact lua is dynamic and
         | typeless. It can for sure be a pita when you have a simple typo
         | in your variable and you don't find out until you run the app
         | and hit that code path.
        
           | TulliusCicero wrote:
           | Yes, I agree. Though I don't remember python behaving this
           | way, exactly, in terms of ignoring attempted use of non-
           | existent variables.
           | 
           | > you don't find out until you run the app and hit that code
           | path.
           | 
           | The real problem was that we didn't -- or rather, he didn't
           | -- even find out then, since it just looked like the variable
           | was somehow holding nil, instead of the variable not actually
           | existing. It looked like there was some other reason for the
           | variable accidentally being nil -- and when you're a total
           | beginner, it could be nearly anything.
           | 
           | This setup is just...it's plainly more beginner-hostile than
           | a compiler/runtime simply telling the coder that there's a
           | problem, what the problem is, and what line it's at. So I
           | don't understand the people talking up Lua like it's great
           | for beginners.
           | 
           | But yeah, I definitely dislike dynamically typed languages in
           | general. Having static typing with type inference ala Kotlin
           | just seems to be much better all around.
        
         | qayxc wrote:
         | > underscore_case (or whatever it's called)
         | 
         | Snake case :)
         | 
         | edit: https://en.wikipedia.org/wiki/Snake_case
        
       | fogleman wrote:
       | Dijkstra's well-known argument for zero-indexing. (Hint: it's not
       | about pointers in C)
       | 
       | https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/E...
        
         | Jtsummers wrote:
         | That came up a few days ago, but in the context of Julia. I
         | wrote a long response at the time [0]. I find it interesting
         | that that's his title ("Why numbering should start at zero")
         | but it really only makes sense as an argument (that starting at
         | 0 is best) _if_ you accept that this is the proper notation for
         | ranges:                 a <= x < b
         | 
         | _If_ you accept that, then the rest of his argument follows.
         | But if you use:                 a <= x <= b
         | 
         | Then 1-based (where a = 1) indexing actually makes a lot of
         | sense as well, because the other reasons for selecting his
         | preferred range notation fall away. 1-based is only "weird" _if
         | you use his range notation_ because then you describe ranges
         | as:                 1 <=  x < N+1
         | 
         | Where N is the length of the range. But, if you use the second
         | form:                 1 <= x <= N
         | 
         | Which reads fairly well.
         | 
         | [0] https://news.ycombinator.com/item?id=25723676
        
       | 1vuio0pswjnm7 wrote:
       | People employed as programmers who are vocal in mailing lists,
       | forums, blogs, etc. can have some very warped views on
       | programming. Curiously, their statements often take a didactic
       | tone. It seems they want to tell others what to do and what not
       | to do. Sadly, these are not the folks who anyone should be
       | attempting to "learn" from. They are antithetical to curiousity.
       | Nice to hear something from someone who is not working as a
       | programmer. This is a much clearer perspective, IMO. At the very
       | least, regardless of anyone's opinion, it gives us a more
       | balanced perspective.
        
         | fwsgonzo wrote:
         | I have always understood the reason why Lua keeps getting
         | embedded into games and game engines is because it's a language
         | that you can reasonably hope non-technical people to be able to
         | contribute a little bit from.
         | 
         | I know that from experience myself. I've moved on from Lua to
         | using tiny virtual machines that run RISC-V instead, and so I
         | choose to use Nim inside the VMs in the hopes that non-
         | technical people will find that easy to grok, somehow. I don't
         | have any anecdata to report yet because it's still early in the
         | project. But, that's the only thing I consider when choosing
         | the language.
        
           | TulliusCicero wrote:
           | I've had the opposite experience. Teaching my 9 year old son
           | Lua has been kind of painful, in large part because of
           | language decisions that make learning things harder for
           | beginners.
           | 
           | For example, did you know that if you pass in a variable to a
           | function, when that variable doesn't actually exist, Lua
           | won't complain? I don't just mean that there's no compiler,
           | but even the runtime is fine with it. It'll just silently
           | assign the argument value to be nil.
           | 
           | This resulted in my son being very confused, after having a
           | typo in the variable name he was using there. Why is the
           | value nil? He was sure he gave it a value earlier, before
           | passing it into the function (and he was correct, to an
           | extent).
           | 
           | I have a laundry list of complaints about the language,
           | things that make it harder to teach beginners. Sure, there's
           | less 'setup' than, say, Java, and that's nice. And the
           | 1-indexing is fine, really.
           | 
           | But there's other language decisions that are just _weird_ ,
           | man. Why would you make this 'table' structure so flexible
           | and important, and then completely neglect to provide a
           | built-in function create copies of said table? How is that
           | non-programmer-friendly? How is providing no ++ or +=
           | increment operators better for beginners?
        
             | striking wrote:
             | I gave you an upvote because I think you don't deserve to
             | go negative just for raising some of these concerns. Still,
             | I'm going to examine some of them.
             | 
             | With regards to variables, the best way to hack around this
             | issue is to 1) always use `local` when declaring a variable
             | and 2) set the `_G` metatable to never allow the creation
             | of keys, which prevents accidentally using globals like
             | you've inadvertently discovered is the default behavior.
             | This is this way because it is I guess simpler than
             | teaching someone how declarations work, but it obviously
             | leads to a pretty immediately bad situation for anyone who
             | wants to do more programming than setting a global
             | constant. It harkens back from when Lua was basically a
             | TCL-like.
             | 
             | Copying a table is generally unnecessary, if you never
             | mutate the table to be cloned. Just set the __index
             | property of a new table to a reference to the table to be
             | cloned. Ta-da, you have inherited the previous table. Not
             | giving you an immediate, easy way to do this forces you to
             | come to terms with copying not always being the right
             | solution. It's not great, and the language offers no
             | pointers to those who want to get a thing done, but it
             | isn't the worst choice.
             | 
             | Not providing increment operators is a design choice, one
             | that simplifies the metatabling for operators. Only having
             | one case for addition, and not having to worry about
             | increment / incremental assignment, means people creating
             | metatables that override operators have a good experience.
             | This is one of those times where power users are given the
             | advantage at the cost of the less experienced, and I share
             | your implied concern in feeling the inconsistencies in who
             | is favored by which language features.
        
       | diego_moita wrote:
       | > Lua is small enough that newbie developers can understand its
       | internals well and keep it in their mind.
       | 
       | This is, by far, Lua's best "feature". If you know programming
       | you can learn 90% of Lua in 15 minutes (metatables and the C
       | stack interface takes more time).
       | 
       | For a language meant to be used by non-programmers this is more
       | than precious, it is essential.
       | 
       | Edit: my favourite Lua-enabled tools:
       | 
       | 1) Hammerspoon, an automation tool for OS-X (like Windows'
       | AutoHotkey) https://www.hammerspoon.org/
       | 
       | 2) Openresty, Nginx turbo-charged in Lua:
       | https://openresty.org/en/
       | 
       | 3) Wireshark, a powerful network traffic analyzer:
       | https://www.wireshark.org/
       | 
       | Many others at: https://github.com/LewisJEllis/awesome-lua
       | 
       | PS: on Windows I highly recommend the ZeroBrane Studio IDE. It is
       | really fantastic.
        
       | lxe wrote:
       | Lua static binary can be made to be less than ~150k, while
       | providing very advanced high level dynamic language features
       | you'd expect from JavaScript or PHP.
       | 
       | I used it to build a admin UI for an embedded device without an
       | MMU. The only other alternative available was C/C++, which slowed
       | the iteration cycle significantly.
       | 
       | Yeah it does things in a strange way, but when I used it, those
       | quirks are vastly overshadowed by its benefits.
        
         | jcims wrote:
         | Did you compile to bytecode on or off the device?
         | 
         | I'm thinking about trying to add Lua support to a small motor
         | controller to provide some more advanced capability inside the
         | control loop. But I don't actually have any experience doing
         | this, and I can't even decide if I want to try to compile the
         | bytecode on the device or do that off the device and push the
         | blob to the device.
         | 
         | It's pretty capable microcontroller, STM32G4.
        
       | 1vuio0pswjnm7 wrote:
       | nmap's "nse" scripts are perhaps an interesting example of lua's
       | utility
       | 
       | https://nmap.org/nsedoc/scripts/
       | 
       | and if by chance you have nmap installed:
       | 
       | /usr/share/nmap/nselib/
        
       | aeturnum wrote:
       | My first real job after school was working on Lua (5.1a mostly)
       | in an embedded context. It was much faster than iterating on the
       | QT C++ application that the Lua was embedded in. It would,
       | eventually, even allow us to do custom targeted push updates to
       | our software (in 2009).
       | 
       | So I love Lua. I appreciate its speed and its flexibility. I
       | think of it as Javascript's easy to use cousin. Straightforward
       | to write and debug - you control the entire environment.
       | 
       | I also think this idea is deeply silly:
       | 
       | >People who want batteries want a ready-made powertool full of
       | opinions. They are not looking towards Lua in the context that
       | Lua wants to exist.
       | 
       | I would have loved ready-made powertools! I wouldn't include all
       | the tools in _my_ toolkit (and we already added some by building
       | our own Lua with a few patches), but it sure would have saved me
       | time writing them (and writing them badly as I was just out of
       | school). I don 't think a complicated, robust library would hurt
       | Lua's mission and I'm sad to see this attitude in the community.
       | I understand that Lua may be too small to support a "big" set of
       | official libraries, but I think the idea that offering fewer
       | options is better than more options is wrong.
        
       ___________________________________________________________________
       (page generated 2021-01-15 23:00 UTC)