[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)