[HN Gopher] Lua: The Little Language That Could
___________________________________________________________________
Lua: The Little Language That Could
Author : mooreds
Score : 137 points
Date : 2023-05-28 18:00 UTC (4 hours ago)
(HTM) web link (matt.blwt.io)
(TXT) w3m dump (matt.blwt.io)
| PicassoCTs wrote:
| A whole gamer generation has learned to make mods/games with
| this. (Roblox).
|
| Not javascript.
|
| Not python.
|
| This.
|
| That which educates the young, shapes the future, may the elders
| like it or not.
| ChristopherDrum wrote:
| Pico-8 fantasy console uses Lua (a subset of; with
| Pico-8-specific console APIs). I keep going back to it in my
| personal projects time and again. I always think, "OK, I'm
| going to build the next thing in C" and wind up falling back to
| Pico-8 and Lua.
|
| The in-the-works Picotron will grow from Pico-8's roots and
| present a full fantasy computer, with an OS, windowing system,
| etc. and expands Lua support to the full v5.4 language.
| nanidin wrote:
| World of Warcraft addons as well.
| kitsunesoba wrote:
| That's where I first encountered Lua.
| epivosism wrote:
| yep.
|
| Roblox Lua/Luau tutorials on youtube - millions of views
| https://www.youtube.com/results?search_query=luau+roblox&sp=...
|
| Luau
|
| https://github.com/Roblox/luau
|
| Roblox wrote a superset of Roblox Lua which is way faster
| https://luau-lang.org/
| kzrdude wrote:
| nice pointers, that sounds interesting. Have they kept it
| near-compatible with lua when it comes to how to embed it in
| a host app? Wondering if they are "competitive" in that
| aspect.
| rektide wrote:
| Lua's presence is honestly hugely because it is so easy to embed
| in other programs. If you needed some scripting capabilities, Lua
| was the way. Whether it's a webserver (nginx) or editor (vim) or
| a window manager (awesome), Lua was the easiest & best at hand
| option to integrate.
|
| There is a huge opportunity, IMO, for more players here. Deno
| definitely has some good gestures toward a this. Wasm though
| seems like the likely general heir, and will have many different
| offerings for how to do that (Deno being one!).
| Blackthorn wrote:
| I've honestly not found it easy to embed as-is, at least in
| C++. Getting functions into Lua is a challenge. Sol2 makes life
| soooo much easier for it.
| vvanders wrote:
| It's not just that it's easy to embed but it's also tiny as
| well, I've run it on many embedded platforms. It wasn't until
| quickjs came along that there was anything even in the same
| ballpark.
|
| When you factor in LuaJIT[1] and the incredible
| performance/zero-overhead-FFI[2] it really is a neat language.
|
| [1] https://luajit.org/
|
| [2] https://github.com/dyu/ffi-overhead
| dleslie wrote:
| Janet is another language that's just trivial to embed, but
| it's newer so it has less traction.
| alexjplant wrote:
| > webserver (nginx)
|
| How timely! Right now I'm learning Lapis [1] by building a toy
| CRUD app that I plan on deploying to fly.io. Lua reminds me of
| Go insofar as it's a really "dumb" language. You can't get too
| cute and there are a few powerful abstractions that let you
| accomplish a lot. Coming from Python (which is an endless
| horizon of PEPs and build artifact standards and name mangling
| and kwargs and... well, you get the idea) it's kind of a breath
| of fresh air.
|
| As for 1-based indexing: it makes more sense. We're all just
| used to 0-based because that's how C worked. If you stop and
| think about it early C was really just a veneer on top of
| assembly and since addressing an array in memory meant having a
| pointer to the first element that meant that it was arr[0]. We
| have no need for this decades later.
|
| [1] https://leafo.net/lapis/
| vvanders wrote:
| Oh you can totally get too cute with metatables. I've seen
| inheritance/straight-OO(Java/C++ style), component based
| design, and eventing/message based approaches all with the
| core primitives that Lua provides.
|
| I think my favorite one was one that used yield[1] with the
| parameters being the number of frames to resume the execution
| of the coroutine. That was used by a number of our game
| designers to write AI scripting that felt close to literate
| programming(I.E. "move x, look for player, yield 30, if found
| player, go here, etc). You could build a whole AI state
| machine that fit into one page of code and was very easy to
| follow.
|
| [1] https://www.lua.org/manual/5.1/manual.html#pdf-
| coroutine.yie...
| fanf2 wrote:
| Years ago I wrote a DNS-over-HTTPS proxy as an nginx /
| OpenResty module in Lua. The Lua code included a very
| stripped-down DNS message parser. The 1-based indexes and
| closed (instead of half-open) intervals were a _massive_ pain
| in the arse. The code has a tricky mixture of odd and even
| offsets that would all have been even in C, and it would have
| been much easier to replace the magic numbers with named
| constants.
|
| https://github.com/fanf2/doh101/blob/master/roles/doh101/fil.
| ..
| Rochus wrote:
| > _hugely because it is so easy to embed in other programs_
|
| Not only; Lua is also an example of excellent language design:
| a minimum of concepts for a maximum of expressability; it's
| minimal, complete and elegant.
|
| > _Deno definitely has some good gestures toward a this_
|
| Lua is much leaner, only ~100k machine code. WAMR looks like a
| better candidate than Deno, but concerning performance and
| simplicity it has still to catch up.
| qznc wrote:
| Forth and Lisp/Scheme and TCL are in the same league.
| However, they are more alien to C programmers, I assume.
| Rochus wrote:
| TCL, Forth and Lisp are languages with minimum possible
| syntax, delegating all higher-level concepts to runtime
| structures and conventions (e.g. which list position means
| what), whereas Lua for its syntax and semantics inherited,
| pruned and elegantly integrated the best features of
| Modula-2 and other languages. It is true that Lua is more
| familiar to C developers, since they look back to the ALGOL
| ancestry; but Lua - unlike C - clearly follows the Pascal
| heritage.
| stefanos82 wrote:
| I've just used `cloc`-ed Lua repo's entire code base,
| excluding makefile's and markdown's: 33619 lines in total of
| C, Lua, and C / C++ Header code; very lightweight code base.
| Rochus wrote:
| Lua 5.1 has 11'081 SLOC in 32 _.c and 1 '506 SLOC in 23 _.h
| files (without tests and examples).
| hgs3 wrote:
| > There is a huge opportunity, IMO, for more players here.
|
| There are quite a few embeddable scripting languages [1]. I
| think these days it's less common to embed a language mostly
| because there are good high-level languages that applications
| can be predominantly written in.
|
| [1] https://github.com/dbohdan/embedded-scripting-languages
| krapp wrote:
| I've started to view Lua as an extension to C rather than a
| language in its own right, which isn't really accurate, but
| reflects how well the two languages complement each other.
| PhilipRoman wrote:
| I'm surprised people dislike 1-based indexing. I use both types
| of indexing commonly and never had an issue with it.
|
| The only issue I've come across in practice is lack of immutable
| tuples that could be used as table keys. I found myself either
| emulating this with nested tables or creating string identifiers
| for my multi-valued keys.
| fanf2 wrote:
| You can also use light userdata for that kind of thing.
| pyjarrett wrote:
| Wow, I just integrated Lua into a C++ project for the first time
| last night.
|
| Took <15 minutes to integrate it with the build system
| (FASTBuild), watched a tutorial video[1], and then in another 15
| minutes I had it hooked up to configure my application.
|
| [1]: https://www.youtube.com/watch?v=4l5HdmPoynw
| SeanLuke wrote:
| Let's put aside the god-awful 1-based tables, in 1993, which
| alone should have killed the language. My big problem with Lua is
| that it tries very hard to make possible all styles of language
| to all people, and as a result it is a language with a lot of
| boilerplate to do any one of them.
|
| For example, consider Lua's OO. The most obvious inspiration for
| Lua here was Newtonscript, via Self. They're quite open about it.
| Newtonscript and Self are prototype-style OO languages done well,
| as opposed to Javascript, which is a prototype-style OO
| abomination. Lua advertises itself as being able to do prototype-
| style OO, all you have to do is make some tweaks to its
| metatables. But while this stuff is baked into Newtonscript and
| Self, it is an amazing amount of boilerplate to do it in Lua, to
| the point of parody. https://www.lua.org/pil/16.1.html
| krapp wrote:
| You're way too triggered by a programming language, dude. Move
| past it.
| tayistay wrote:
| On the page you linked, I see four lines of boilerplate in a
| constructor: function Account:new (o)
| o = o or {} -- create object if user does not provide one
| setmetatable(o, self) self.__index = self
| return o end
|
| Doesn't seem so bad. Are you referring to something else?
| daneel_w wrote:
| Why would you wish the death of a language only because its
| default index for arrays is 1?
|
| You're not forced to index from 1 and onwards. You can use any
| range you want to: https://www.lua.org/pil/11.1.html
| akkartik wrote:
| For the past year I exclusively use Lua for my side projects. And
| I use it with certain self-imposed restrictions:
|
| * no Luarocks
|
| * no native libraries
|
| More details: http://akkartik.name/freewheeling
| carapace wrote:
| That essay/software/discipline is awesome!
| iamcreasy wrote:
| Can you kindly provide a one line explanation as to why no
| Luarocks?
| akkartik wrote:
| https://xkcd.com/2347
|
| That way lies npm and left-pad.
|
| Tools encourage behaviors. I avoid tools that encourage
| behaviors I want to avoid.
| AHTERIX5000 wrote:
| Luarocks works quite well if the lib is pure Lua.
|
| For native libs it's a wild west and success depends a lot on
| your environment. Sometimes the lib is being built with
| -Werror and fails if you're using more recent compiler,
| sometimes include paths are not resolved correctly using
| pkgconfig or similar and so on.
| harryvederci wrote:
| Great talk!
| zephraph wrote:
| Anytime Lua comes up I'm reminded of John Earnest's Lil scripting
| language[1]. It's inspired by Lua and Q, built for Decker[2]
| which is a re-imagined version of HyperCard. Generally though, I
| love lua for its embeddability and am extremely happy anytime I
| see someone chatting about integrating it. Modding and scripting
| in games was a tremendous motivation for me to dig more into
| programming and these approachable languages are a core aspect of
| that.
|
| [1] https://beyondloom.com/decker/lil.html
|
| [2] https://beyondloom.com/decker/
| tayistay wrote:
| I'm currently using Lua as an extension language in my app [1].
| Users can write their own custom UIs and DSP code. It's great how
| the Lua interpreter (and LuaJIT) allow you to provide your own
| memory allocator, so I can preallocate a region and do realtime-
| safe allocation within it.
|
| [1] https://audulus.com
| iamcreasy wrote:
| Looks cool. Is there any 5 min intro video introducing the app
| to the world?
| tayistay wrote:
| Thanks! There are a couple preview videos on the App Store
| and lots of stuff on YT: https://www.youtube.com/audulus
| jmclnx wrote:
| Lua was on my very short list of languages to learn. Will need to
| revisit that.
|
| Also worth noting, NetBSD has had lua hooks into their kernel for
| about 10 years I think.
| ok_dad wrote:
| You can learn Lua in a weekend, easy. The language is
| ridiculously small, but also ridiculously powerful. You can
| learn how to use C libraries in Lua in another weekend, easy.
| Using Lua from C is also easy, one weekend or less.
| stefanos82 wrote:
| How about in 15 minutes lol ?
| https://tylerneylon.com/a/learn-lua/
| celaleddin wrote:
| Just curious: Can you share your list of languages to learn?
| thangalin wrote:
| The ConTeXt typesetting system tightly integrates Lua. One aspect
| of Lua I dislike is that it isn't object-oriented. What's
| impressive is that the language can be extended to be so in
| astonishingly little code:
|
| * https://github.com/kikito/middleclass/blob/master/middleclas...
|
| Using OOP, typesetting a hexagonal grid and a symbolic
| representation of a neural network on top is easier develop, IMO.
|
| A vertex defines a point in 2D space:
|
| * https://github.com/DaveJarvis/keenwrite-themes/blob/main/bos...
|
| An edge connects two vertices:
|
| * https://github.com/DaveJarvis/keenwrite-themes/blob/main/bos...
|
| A graph connects edges:
|
| * https://github.com/DaveJarvis/keenwrite-themes/blob/main/bos...
|
| A priority queue serves for ordering edges by weight of adjoining
| vertices:
|
| * https://github.com/DaveJarvis/keenwrite-themes/blob/main/bos...
|
| With these concepts in hand, we can typeset a grid and a "neural
| network" on top:
|
| * https://github.com/DaveJarvis/keenwrite-themes/blob/main/bos...
|
| Here's an example of the output from the first chapter:
|
| * https://i.ibb.co/19DCDZy/ch-1.png
|
| And a later chapter, where the "network" has grown in complexity:
|
| * https://i.ibb.co/ncf16vg/ch-2.png
|
| This is for my near future hard sci-fi book on AGI. I'm looking
| for alpha readers to give me feedback. See profile for contact
| details.
|
| P.S.
|
| There's a subtle bug in the code that can result in one or two
| disconnected vertices. If you spot it, let me know!
| taylorius wrote:
| Arrays start at 1. Just... no.
| huimang wrote:
| Very insightful discussion.
| taylorius wrote:
| Thank you. I'm here all week.. :-)
| josephcsible wrote:
| Yeah that's a wart, but it's basically the only wart in an
| otherwise amazing language.
| fbdab103 wrote:
| Ehh, local being a keyword (instead of local default, global
| only if required) was a significantly bigger gaff. The other
| would be no nulls in tables. 0/1 based indexing is
| familiarity only.
| josephcsible wrote:
| Requiring a keyword to declare a variable is a good thing.
| Otherwise, it'd be easily to accidentally declare new
| variables when you meant to assign to an existing one.
| Since global is the default, starting a program with
| something like this effectively keeps that from happening:
| local gindex = {} setmetatable(_G, {__index =
| function(t,k) local v = gindex[k] if v ==
| nil then error("Bad read of global variable " ..
| tostring(k), 2) else return v end
| end, __newindex = function(t,k,v) error("Bad write
| of global variable " .. tostring(k), 2) end})
| for k,v in pairs(_G) do gindex[k] = v
| rawset(_G, k, nil) end
| ok_dad wrote:
| Why? 0 based indexing came from a time where you used memory
| addresses directly to index into arrays. Today, we don't do
| that, so 1 based indexing seems extremely reasonable. Besides,
| with Lua you can still do 0 based indexing with a small
| personal extension function.
| imbnwa wrote:
| One of the first things requested by users of an internal
| media sequencing tool where time is measured by frames was
| 1-based indexing, they absolutely hated starting from 0
| ok_dad wrote:
| Yea, I love how 0 indexing is such a big deal. Like tabs vs
| spaces, it doesn't matter even a tiny bit, it's like a
| religion. It's not that hard to index off of 1, and like I
| said, you can write like 5 lines of code to make 0 indexing
| the default!
| krylon wrote:
| From an aesthetic perspective, I agree. In practice, it wasn't
| a problem, though. I rarely accessed arrays with a constant
| index anyway.
| bryanrasmussen wrote:
| maybe I'm being dim but what possible aesthetic benefit does
| it offer? The only benefit that springs to my mind from a
| language design perspective is that it is most likely
| familiar to the user of the language from languages they have
| used before.
|
| Both Smalltalk and APL use 1 based indices so I just find any
| claim of obvious aesthetic superiority on this issue a little
| hard to accept without some back up.
|
| If speaking aesthetics the fact that the number of items in
| your array is equal to the position of the last index item in
| the array would seem aesthetically superior.
| ok_dad wrote:
| One of my favorite projects that uses Lua is
|
| https://redbean.dev/
|
| It's a single file web application engine, and more, in an
| executable you can run on several OSes and I think even bare
| metal, but it's been a while since I looked at it so it's
| probably even more awesome today.
| rlawson wrote:
| Yes! I'm currently learning Lua now just because of redbean.
|
| I also recommend the excellent ZeroBrane IDE -
| https://studio.zerobrane.com/
|
| As a Java/Python dev there is something about using such light
| weight and _fast_ tools like redbean, lua and ZeroBrane that
| brings a smile to my face.
| MarkusWandel wrote:
| I once read through the entire Stroustrup C++ book and figured in
| one case, there is absolutely no way to make this work except for
| a secret, hidden variable in the class. Did a test compile and:
| There it was! OK, I get C++, done. Then I saw actual C++
| programs. Whoa, how do you index into an array using a string?
| You don't of course, you overload the [ ] operator.
|
| Reading about Lua when it was newer I could foresee the same
| thing happening on steroids. Yes, the language itself is simple
| but what you can do with it - emulate almost any construct in any
| language - promises confusion. When it comes to readable code,
| sometimes "less is more" in terms of langauge features.
| notacoward wrote:
| > OK, I get C++, done.
|
| > ...
|
| > When it comes to readable code, sometimes "less is more" in
| terms of langauge features.
|
| Please tell me that is meant as satire. There is no sane way to
| look at C++ and Lua and decide "less is more" would favor C++.
| andrewmcwatters wrote:
| It is inevitable that people complain about Lua's 1-based
| "tables" which serve as both arrays and hash maps.
|
| I usually encourage people to remember the practical origins of
| 0-based arrays when thinking in terms of pointers, where 0-based
| counting is useful in terms of talking about offsets from a point
| in memory, as contrasted to 1-based counting where you are
| primarily talking about quantities of collections.
|
| Lua is a great language. My only wish is that it was easier to do
| multithreaded work in it. Unfortunately, this is not the case
| without some significant architectural forethought.
| cyberax wrote:
| The problem with 1-based arrays is that it makes the offset and
| location be different. For example, we want to place an item
| into a simple circular buffer with zero-based indexing:
|
| arr[idx mod capacity] = 123
|
| Now with 1-based indexing:
|
| arr[(idx-1) mod capacity + 1] = 123
|
| This is absolutely makes it a PITA if you're working with
| things like bitmaps, blending, or sound mixing. If you only
| need a language for high-level scripting, then it indeed is not
| such a big deal.
| teamonkey wrote:
| Lua's arrays can start at index 0 if you like, there's no
| real reason why the first line wouldn't work.
|
| Starting at 1 is a convention:
|
| array = {"hello", "world"}
|
| print(array[1]) --- displays "hello"
|
| array[0] = "why"
|
| array[2] = "there"
|
| for i=0,2 do print(array[i]) end --- "why" "hello" "there"
| saurik wrote:
| The reason why 0 makes sense for pointers isn't due to some
| arcane implementation detail of programming but because of how
| one conceptualizes ranges and distance and pointers just so
| happen to be a place where that comes up very directly in
| programming. Any time you attempt to develop an algorithm that
| needs to think about multiple ranges of a collection at the
| same time or needs to scale ranges through a collection,
| 1-based indexing causes you to have to throw in a bunch of +/-1
| compensation factors to prevent you from double-counting or
| scaling past an edge. Life is just too short to have to
| constantly debug the issues that come from 1-based indexing
| when developing complex algorithms, even if it means beginners
| feel a bit confused by "counting from 0".
| andrewmcwatters wrote:
| No, it actually does originate from 1960's era programming
| practices. Not to say there weren't also 1-based or N-based
| numbering, but you're historically misled here.
|
| You could also say the same about counting collections. No
| regular person counts 0... 1... 2... 3... and ends counting
| N-1. It, too, is a workaround.
| kzrdude wrote:
| I don't think saurik is talking about history, so you're
| talking past each other in that sense.
| andrewmcwatters wrote:
| I think so, too, but my point is that it makes sense for
| other historical reasons--not the one the poster
| mentions. Those decisions weren't made due to
| mathematics.
| adfgoinionio wrote:
| [dead]
| hypertele-Xii wrote:
| If the 1st element is [0], something's conceptually wrong.
| adfgoinionio wrote:
| [dead]
| verytrivial wrote:
| Dijkstra had an opinion on this (and many other things).
| 0-based ftw.
|
| https://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF
| fosk wrote:
| Yes that is annoying the first week, then you get used to it.
|
| If the biggest complaint about Lua is 1-based tables, I'd say
| that's a compliment to the language indeed.
| charlieyu1 wrote:
| The difference between 1-based and 0-based indices is
| irreverent enough, that's the reason it feels uncomfortable for
| choosing to use something that is different. It is like little-
| endian vs big-endian, but you never see people choosing to use
| big-endian now
| imbnwa wrote:
| Lua metatable > JavaScript prototype
| squarefoot wrote:
| Lua was born in 1993. That's 30 years, not bad for a language
| that some still consider new.
|
| For those looking for a GUI library for Lua, check out TekUI.
| http://tekui.neoscientists.org/index.html
|
| I tested it on various distros without hassle, both on x86 and
| ARM. It would probably be worth of porting to other languages
| too.
| ValtteriL wrote:
| Lua is also the language of choice for the nmap scripting engine.
|
| While cute, easy to learn and all, I feel like it has kept back
| the development of nmap scripts. Only a few people are dedicated
| enough to take the time to learn it.
|
| Then again, I think this has kept the quality of the available
| scripts high.
| nottorp wrote:
| Well who knew nmap has a scripting engine? :)
|
| Before reading your post, if i were in a situation where I
| needed to do complex stuff with nmap, i'd just integrate it in
| a script that would run it multiple times, parse the output
| etc.
|
| I never imagined it had a scripting language inside itself.
|
| Guessing the only people who know about that are admins in
| large networks and black or white hat crackers...
| anony23 wrote:
| What are some of the nmap scripts that you use regularly?
___________________________________________________________________
(page generated 2023-05-28 23:00 UTC)