GOPHERSPACE.DE - P H O X Y
gophering on zaibatsu.circumlunar.space
Learning to love Lua
--------------------

As I have explained elsewhere[1], the Zaibatsu is a small place and I
am always looking at the memory consumption of things people are
running - possibly I make a bigger deal out of this than I need
to, as we still haven't run in to any actual problems yet.  Anyway,
through this habit I realised very early on that if I wanted to write
useful software for sundogs to use there I might need to learn some
new tools.  It doesn't matter how spartan a Python program is, its
memory footprint has an unavoidable lower-bound equal to the footprint
of the Python interpreter, which is not small.  This makes, e.g. VF-1,
which I had always thought of as "lean and mean", into probably the
heaviest user program which is regularly used there (the shame!).  Of
course the same is true for Perl, PHP (which our earliest BBS client
was written in), Ruby, etc.  Truly lightweight software needs to be
either compiled or written in an interpreted language with a very
small interpreter.

I can write C, although not terribly well.  I wouldn't at all mind the
opportunity to get better through practice (and when kvothe phlogged
about "Modern C"[2] my interest was piqued), but it didn't seem wise
to use a language so unforgiving with security issues in a pubnix
environment without really knowing what I was doing.  After a bit of
searching, I ended up with Go and Lua on my radar (yes, I've heard of
Rust, no, I don't want to talk about it).  I am still interested in
learning and using both, but for whatever reason I have ended up using
Lua first.  I wrote a replacement for our PHP BBS client in it, which
is now the standard client at both the Zaibatsu and Republic, and I am
currently writing a "social unix" tool in it - which some of you are
now testing and which I will write about at some length soonish.  I am
still very much a novice and still learning, but it's starting to be
vaguely comfortably and I'm enjoying using it and would like to keep
getting better at it.

Those of you who follow me on Mastodon may remember when I first
started looking into these leaner languages that I angrily dismissed
Lua very early on as soon as I discovered that it doesn't throw an
error when you try to access a variable which has never been used
before, instead just creating that variable with a value of `nil`.
This is probably my number one most hated language mis-feature and I'm
actually not sure what got me to push past it in this case.  In fact,
on paper, I *shouldn't* like Lua at all.  It turns typos into
transient empty variables ala PHP, it indexes arrays starting at 1 ala
MATLAB and it has overly verbose "My First Language" flow control
tokens like "then", "do" and "end" instead of God-fearing alternatives
like ":", "{" or, yes, significant whitespace.  Nuts to all that.  And
yet, I *do* find myself really liking it.

(I make this joke far too often, but I usually mean it: "Significant
Whitespace" would be a great name for a band)

I think what redeems Lua for me is its multifaceted minimalism.  There
is, of course, the thing which drew me to Lua in the first place, the
micropubnix-friendly tiny interpreter.  Lua is minimal in its
*implementation*.  The interpreter is less than 500 lines of very
vanilla C.  Allegedly, it builds just fine with Turbo C 1.0 from 1990.
The resulting binary is less than 200KB in size (cf over 4MB for
Python 3).  It can be made to run just about anywhere.  But Lua is
also minimal in its *design* (which, of course, is largely what
facilitates the minimal implementation).  It provides one non-trivial
but very flexible data structure, the table, out of which you are
expected to build whatever other structures you need.  There is a
healthy dose of the philosophy of building your own domain-specific
tools to solve the problem at hand.  In this respect it reminds me a
bit of Forth, with the notable exception that it is very practical and
very easy to actually write real-world software in Lua.  I think this
is maybe the real greatness of Lua - it seems to strike an excellent
balance between the ascetic minimalism that I find so conceptually
attractive and the practical usability and readability that I need to
actually, well, use something.

Of course, basic Lua comes very much "without batteries included", in
Python parlance, and some third party libraries are necessary to get
real work done.  But I've not yet had any trouble finding a
well-estalished library to do what I've needed yet.  The luaposix and
luafilesystem libraries do, well, what you'd expect.  Penlight is a
small-ish "Swiss army knife" of useful functions, influenced by the
Python Standard Library, and it has a smaller more spartan sibling
named microlight.  With these libraries it's quite possible to write
nice command-line tools which need far less memory than their Python
equivalents would, but with far less hassle than using C would
involve.  I might even try to port VF-1 someday, although it's not a
priority right now.

Encouraged by this success, I've tried to dive deeper into the Lua
world, but this has been a very different experience to what I
expected and, if anything, has been a bit discouraging.

I went to Stack Overflow, loaded all questions tagged "Lua" and sorted
them by "most votes".  I was hoping to find interesting questions with
detailed, thoughtful replies, or long explanations of accepted best
practices for Lua coding by respected members of the community.  This
didn't exactly pan out as I expected.  It seems that the Stack
Overflow Lua community is mostly used by beginners coming to grips
with the language.  Which is fine, there has to be a place like that,
but it's not the sort of place I was trying to find.  I was a bit
taken aback to find that the most upvoted Lua question of all time is
"How can I convert a string to an integer in Lua?".  The answer is to
use the built-in `tonumber` function.  This is explained in the
second chapter of "Programming in Lua"[3], a book written by one of
the creators of the language which is available online, for free.
Specifically, it's in the section on strings, which is entitled
"Strings".  I don't want to be too snarky, but...come on.

So, my search continued, and I was unnerved to find out how much of
the Luaverse online feels abandoned.  There is a suite of tools for
using Lua as a web development language (e.g a webserver, an API
similar to Python's WSGI, an MVC framework) called Kepler.  If you
head to www.keplerproject.org it might take you a little while to
notice that the site has, in fact, been hacked and turned into a a
spam blog.  It's been much more cleverly done than usual, as all the
original content is still present, at the top, so until you scroll
past it you don't see the spam at all.  It's been this way for over a
year.  I can only assume that the domain name was snapped up by
evildoers shortly after it expired and is no longer under the control
of anybody associated with the project, otherwise surely nobody would
leave things in this state even if development had ceased (which for
most components it seems to have).

There is a library repository / package manager called Luarocks[4],
which is analogous to cpan, pip, gem, cargo, etc.  Many of the most
popular packages, including those I mentioned above, have not seen
releases in years.  In principle, I actually welcome this.  I am a
firm believer that good software can, and *should*, be "done".  If you
tackled a well-defined and suitably-sized task, and designed your tool
well, a program should eventually reach feature completeness, bugs
should get shaken out, and eventually the thing should just do what it
is supposed to do without breaking.  It may never be perfect, but the
time between subsequent releases should slowly tend toward infinity.
If it doesn't, either the program is too poorly designed to reason
about and fix bugs, or it deals with a moving target.  Which is
sometimes unavoidable, e.g. with constantly updated network protocols,
but for a library with a clearly defined and unchanging task, should
not happen.  For some reason, this is a very rare opinion and people
seem to actively steer away from anything which is not actively
developed.  Frankly, I'd be happier if as much of the software I used
as possible was *not* actively developed.  Then I wouldn't have to
waste time worrying about updates and nothing would break when
something was changed for the sake of fashion.  So, in principle, I
should be happy that all the major third party Lua libraries are years
old.  Have I not, at last, found my people?  Well, maybe, but this
attitude is rare, and actual honest-to-God "finished" programs are
very rare in practice.  I have not yet encountered a vocal subset of
the Lua community spreading the gospel of finished software.  It
doesn't seem to be an acknolwedged part of the Lua mindset.  So, in
the absence of explicit declarations to the contrary, I do worry that
a lot of these libraries are not so much "finished" and in a mature
maintenance phase, as they are simply abandoned.

I get the impression that Lua may be a victim of its reputation for
embeddability.  It is well known as being a popular language to add
scriptability to games, because of its small footprint and high speed.
Because of this, information about how to use Lua as a standalone
language for non-game applications is relatively rare.  It seems
apparent that many years ago there was an effort to get it adopted
more widely, such as the now decrepit Kepler project, or widely used
but no-longer actively developed third-party libraries, but this seems
to have ultimately failed and now it is just "the gaming language", or
perhaps "the embedded language" (sometimes people ask Lua questions
and people reply asking "what's your host language?", even if the OP
never specified there was one.  It seems often to go without saying).
This reminds me a little bit of NetBSD; it has become so strongly
associated in the public mindset with extreme portability that it
seems like it never occurs to most people that it would ever be
sensible to install it on an x86_64 machine - despite the fact that it
is a perfectly good small, clean and reliable OS which makes a really
solid server and even a usable desktop if you have modest
expectations.  It seems that being really, really good at one niche
application is actually an impediment to being widely adopted as a
general-purpose tool, no matter how good a general-purpose something
might be.

So, I plan to just plod along at my own pace, reading manuals,
tackling larger projects, and learning as I go.  Not everything needs
a vibrant online community, anyway, as the gopher and pubnix scenes
illustrate.  In the unlikely event than any master Lua hackers read
this, feel free to email me if you want to share any particularly
valuable resources or insights.

[1] gopher://zaibatsu.circumlunar.space:70/0/~solderpunk/phlog/on-tiny-servers.txt
[2] gopher://zaibatsu.circumlunar.space:70/1/~kvothe/phlog/2018-09-30-modern-c/
[3] https://www.lua.org/pil/contents.html
[4] https://luarocks.org