[ACCEPTED]-Example usage where Lua fits much better than C/C++-lua

Accepted answer
Score: 13

Using a scripting language such as Lua has 2 many other benefits.

A couple of advantages 1 to Lua vs. C++:

  • It's often shorter in terms of development time due to the high-level nature, as in your example.
  • It doesn't require recompilation to change behavior.
  • Behavior can be changed on non-development machines.
  • Prototyping is very fast and easy, since you can just tweak logic at runtime.
Score: 5

Scripting languages reduce the effort required 33 to build complex GUIs that otherwise require 32 a lot of framework glue and repetition of 31 code. Several GUI toolkits are available 30 with Lua bindings, including wxWidgets and the IUP toolkit.

In 29 both of those bindings, first class function 28 values and full closures make event callbacks 27 easy to code and easy to use.

A large application 26 using Lua at its core (such as Adobe Photoshop 25 Lightroom) has an outer C/C++ program that 24 hosts the Lua interpreter and provides access 23 to its core features by registering C functions 22 with that interpreter. It typically implements 21 compute-intensive core functions in C functions, but 20 leaves the overall flow, operation, and 19 even the GUI layout to Lua scripts.

I have 18 found in my own projects that it is often 17 the case that the stock standalone Lua interpreter 16 (lua.exe or wlua.exe) is sufficient for 15 the outer application when combined with 14 IUP loaded at run time along with one or 13 two custom DLL-based Lua modules coded in 12 C that implement features that require that 11 level of performance, or features that are 10 implemented via other C-callable libraries.

The 9 important points for my projects have included:

  • True tail calls allow for a easy expression of finite state machines.
  • Garbage collected memory management.
  • Anonymous functions, closures, first class function values.
  • Hash tables.
  • Rich enough string library.
  • Userdata extends the garbage collector to C side allocations.
  • Metatables allow a rich variety of object oriented and functional techniques.
  • Small but sufficiently powerful C API.
  • Good documentation, with open source as a backup.
  • Good user to user support through the mailing list and wiki.
  • Powerful modules such as a PEG parser available from the authors and from the community.

One 8 of my favorite examples to cite is a test 7 jig I built for an embedded system that 6 required about 1000 lines of Lua and 1000 5 lines of C, ran under lua.exe, and used 4 IUP to present a full Windows GUI. The first 3 version was running in about a day. In C++ with 2 MFC, it would have been at least a week's 1 work, and many thousands of lines of code.

Score: 3

Try to implement a Lua table in C/C++, you'll 5 see the strength of Lua right there.

In Lua:

a["index"] = "value"

In 4 C, start by reading about linked list...

C++ STL 3 may help, but it is going to be a lot more 2 verbose than Lua.

Also, Lua makes great glue. It 1 is so easy (IMHO) to interface to C.

Score: 3

I don't know if I make it 'click' for you 15 but I'll try.

One of the advantages of embedding 14 Lua is, that you can not only use it as 13 a configfile but actually offer your C/C++-interfaces 12 to lua and 'script' their usage via the 11 Lua-scripting language.

If you want to change 10 the behaviour/logic of your application, you 9 just have to change the code in the Lua-script 8 without the need to recompile the whole 7 application.

Prominent uses are game logics 6 like AI oder state machines, where a fast 5 roundtrip-time from change to play is essential 4 for developing the game.

Of course, the main 3 logic has then to be present within the 2 Lua-script, not within the C/C++-code, to 1 be effectively used.

Score: 2

Programming just in C can be a very tedious 30 and redundant task, this certainly applies 29 when compared to more abstract, high level 28 languages.

In this sense, you can get started 27 and finish things much more quickly than 26 doing everything directly in C, this is 25 because many things that need to be set 24 up, done and cleaned up explicitly and manually 23 in C, are often implicitly and automatically 22 handled by a scripting language such as 21 Lua (e.g. imagine memory management).

Similarly, many 20 more abstract data structures and algorithms 19 are often directly provided by such high 18 level languages, so you don't have to re-invent 17 the wheel and re-implement it, if all you 16 need is a standard container (think linked 15 list, tree, map etc).

So, you can get a fairly 14 good ROI when using a fairly abstract scripting 13 language such as Lua or even Python, especially 12 if the corresponding language comes with 11 a good library of core functionality.

So, scripting 10 is actually ideal in order to prototype 9 ideas and projects, because that's when 8 you need to be able to concentrate on your 7 effort, rather than all the mechanical redundancies 6 that are likely to be identical for most 5 projects.

Once you got a basic prototype 4 done, you can always see how to improve 3 and optimize it further, possibly be re-implementing 2 essential key functionality in C space, in 1 order to improve runtime performance.

Score: 2

LUA has closures, and closures rock. For example:

function newCounter ()
  local i = 0
  return function ()   -- anonymous function
           i = i + 1
           return i
         end
end

c1 = newCounter()
print(c1())  --> 1
print(c1())  --> 2

You can 3 create a function and pass it around. Sometimes 2 it is more handy than creating separate 1 class and instantiate it.

Score: 1

For an example of where Lua fits better 10 then c++ look at distributing scripts. Mush Client offers 9 Lua as a scripting language. As shown by 8 the link above you can do a lot with Lua 7 to extend the program. Unlike C++ though 6 Lua doesn't have to be compiled and can 5 be restricted. For example you can sandbox 4 Lua so it can't access the file system. This 3 means that if you get a script from someone 2 else it is incapable of destroying your 1 data since it can't write to the disk.

Score: 1

The main advantages of Lua as a programming 13 language (apart from the embeddability) are

  • Powerful, efficient hash table as the main data structure
  • String-processing library with an excellent balance of complexity and expressive power
  • First-class functions and generic for loop
  • Automatic memory management!!

It's 12 hard to find a short example that illustrates 11 all these. I have 191 Lua scripts in my 10 ~/bin directory; here's one that takes the output 9 of pstotext and joins up lines that end in a hyphen:

local function  printf(...) return io.stdout:write(string.format(...)) end
local function eprintf(...) return io.stderr:write(string.format(...)) end

local strfind, strlen = string.find, string.len

function joined_lines(f)
  return coroutine.wrap(function()
                          local s = ''
                          for l in f:lines() do
                            s = s .. l
                            local n = strlen(s)
                            if strfind(s, '[%-\173]$', n-1) then
                              s = string.sub(s, 1, n-1)
                            else
                              coroutine.yield(s)
                              s = ''
                            end
                          end
                        end)
end

-- printf('hyphen is %q; index is %d\n', '­', string.byte('­'))

for _, f in ipairs(arg) do
  for l in joined_lines(io.popen('pstotext ' .. f, 'r')) do
    printf('%s\n', l)
  end
end

This 8 example shows several features to advantage 7 but does nothing interesting with tables.

Here's 6 a short snippet from a Key Word In Context 5 indexing program, which fetches context 4 from a table and formats the key word in 3 context. This example makes more extensive 2 use of nested functions and shows some more 1 table and string stuff:

local function showpos(word, pos, lw, start)
  -- word is the key word in which the search string occurs
  -- pos is its position in the document
  -- lw is the width of the context around the word
  -- start is the position of the search string within the word
  local shift = (start or 1) - 1  -- number of cols to shift word to align keys
  lw = lw - shift -- 'left width'
  local rw = cols - 20 - 3 - lw - string.len(words[pos])  -- right width
  local data = assert(map:lookup(pos)[1], "no map info for position")
     -- data == source of this word
  local function range(lo, hi)
    -- return words in the range lo..hi, but only in the current section
    if lo < data.lo then lo = data.lo end
    if hi > data.hi then hi = data.hi end
    local t = { }
    for i = lo, hi-1 do table.insert(t, words[i]) end
    return table.concat(t, ' ')
  end
  -- grab words on left and right, 
  -- then format and print as many as we have room for
  local left  = range(pos-width, pos)
  local right = range(pos+1, pos+1+width)
  local fmt = string.format('[%%-18.18s] %%%d.%ds %%s %%-%d.%ds\n', 
                            lw, lw, rw, rw)
  printf(fmt, data.title, string.sub(left, -lw), word, right)
end
Score: 1

I use a game engine called Love2D which 28 uses Lua for writing games. All the system 27 calls and heavy-lifting is done in a C program 26 which reads a Lua script.

Writing a game 25 in C or C++, you find yourself trying to 24 work with the subtleties of the system rather 23 than just implementing your ideas.

Lua allows 22 for "clean" dirty-style coding.

Here's an 21 example of a game object written in pure 20 lua:

local GameObj = {}              -- {} is an empty table
GameObj.position = {x=0,y=0}
GameObj.components = {}

function GameObject:update()
    for i,v in ipairs(self.components) do    -- For each component...
        v:update(self)                       -- call the update method
    end
end

To instantiate:

myObj = setmetatable({},{__index=GameObj})
-- tables can have a meta table which define certain behaviours
-- __index defines a table that is referred to when the table
-- itself doesn't have the requested index

Let's define a component, how 19 about keyboard control? Assuming we have 18 an object that does input for us (that would 17 be supplied C-side)

KeyBoardControl = {}
function KeyBoardControl:update(caller)
    -- assuming "Input", an object that has a isKeyDown function that returns
    -- a boolean
    if Input.isKeyDown("left") then
        caller.position.x = caller.position.x-1
    end
    if Input.isKeyDown("right") then
        caller.position.x = caller.position.x+1
    end
    if Input.isKeyDown("up") then
        caller.position.y = caller.position.y-1
    end
    if Input.isKeyDown("down") then
        caller.position.y = caller.position.y+1
    end
end
--Instantiate a new KeyboardControl and add it to our components
table.insert(myObj.components,setmetatable({},{__index=KeyboardControl})

Now when we call myObj:update() it 16 will check inputs and move it

Let's say we'll 15 be using plenty of this kind of GameObj 14 with a KeyboardControl, we can instantiate 13 a prototype KeyObj and use THAT like an 12 inherited object:

KeyObj = setmetatable( {}, {__index = GameObj} )
table.insert(KeyObj.components,setmetatable( {}, {__index = KeyboardControl} )    

myKeyObjs = {}

for i=1,10 do
    myKeyObjs[i] = setmetatable( {}, {__index = KeyObj} )
end

Now we have a table of 11 KeyObj that we can play with. Here we can 10 see how Lua provides us with a powerful, easy 9 to extend, flexible object system which 8 allows us to structure our program in accordance 7 with the problem we're trying to solve, rather 6 than having to bend the problem to fit into 5 our language.

Also, Lua has some nice other 4 features like functions as first-class types, allowing 3 for lambda programming, anonymous functions, and 2 other stuff that usually has comp-sci teachers 1 smiling creepily.

More Related questions