Lua is not only -and not mainly- a standalone interpreter program (/usr/bin/lua
on my Linux/Debian desktop) of the Lua scripting language, but Lua is mostly a library to embed an interpreter into (existing) applications (e.g. luatex
is embedding Lua inside tex
).
This is the main strength of Lua, to be embeddable in your application. Lua was originally designed for that purpose. So you have some existing application, and you can (with not too much efforts) embed the Lua interpreter library inside your application to enable some parts of it to be scriptable by Lua.
This is explained in the chapter §24 – An Overview of the C API, which starts with:
Lua is an embedded language. That means that Lua is not a stand-alone package, but a library that can be linked with other applications so as to incorporate Lua facilities into these applications.
You may be wondering: If Lua is not a stand-alone program, how come we have been using Lua stand alone through the whole book? The solution to this puzzle is the Lua interpreter (the executable lua). This interpreter is a tiny application (with less than five hundred lines of code) that uses the Lua library to implement the stand-alone interpreter. This program handles the interface with the user, taking her files and strings to feed them to the Lua library, which does the bulk of the work (such as actually running Lua code).
This ability to be used as a library to extend an application is what makes Lua an extension language. At the same time, a program that uses Lua can register new functions in the Lua environment; such functions are implemented in C (or another language) and can add facilities that cannot be written directly in Lua. This is what makes Lua an extensible language.
These two views of Lua (as an extension language and as an extensible language) correspond to two kinds of interaction between C and Lua. In the first kind, C has the control and Lua is the library. The C code in this kind of interaction is what we call application code. In the second kind, Lua has the control and C is the library. Here, the C code is called library code. Both application code and library code use the same API to communicate with Lua, the so called C API.
In that case you need to bind (i.e. wrap) some of your routines as primitive functions called by Lua scripts, and you also need to be able to run Lua (e.g. by interpreting some bytecode or script).
So the point of designing some Lua C API is to be able to use Lua to script some existing application or software (and not mainly to extend a standalone Lua interpreter with something else, even if that is possible thru plugins loaded in loadlib.c, which gets called by require ...)
Notice also that embedding an interpreter inside your application is a very strong architectural software design decision (that IMHO you should make quite early).