So here’s a fun little snippet of lua that is functional but also object oriented (the function maintains state).

function CreateInstance()
    local self = {}
    return function(msg)
        if msg == "setMessage" then
            return function (s)
                self.message = s
            end
        elseif msg == "getMessage" then
            return self.message
        else
            error("Method missing")
        end
    end
end
local x = CreateInstance()
x("setMessage")("Hello World")
print(x("getMessage"))
x("setMessage")("Goobye Cruel World")
print(x("getMessage"))

Here is an alternative way, using the Lua “:” syntactic sugar:

local MyClass = {}
MyClass.__index = MyClass
function MyClass.new()
    local self = setmetatable({},MyClass)
    return self
end
function MyClass.setMessage(self,s)
    self.message = s
end
function MyClass.getMessage(self)
    return self.message
end
local y = MyClass.new()
y:setMessage("Hello World")
print(y:getMessage())
y:setMessage("Goodbye Cruel World")
print(y:getMessage())

In the first instance, everything is private. In the second, everything is public. In the second example, it’s possible to modify the code to have both public and private members, it’s also possible to create multiple inheritance. That’s already been well covered, here’s how we can do it functionally.

function TrapParents(real_args)
   local parents = {}
    for i=1,real_args.n do
        table.insert(parents,real_args[i])
    end
    return parents
end
function TraverseParents(parents,message,...)
    local res = nil
    for i=1,#parents do
        res = parents[i](message)
        if res then
            return res
        end
    end
    return nil
end
function MethodMissing(parents,message,...)
    return TraverseParents(parents,message)
end
function CreateParent1(...)
    local self = {}
    local parents = TrapParents({n=select('#', ...),...})
    return function(msg)
        if msg == "helloParent1" then
            return "hello from Parent1"
        elseif msg == "name" then
            return "Parent1"
        else
            return MethodMissing(parents,msg)
        end
    end
end
function CreateParent2(...)
    local self = {}
    local parents = TrapParents({n=select('#', ...),...})
    return function(msg)
        if msg == "helloParent2" then
            return "hello from parent2"
        elseif msg == "hijacked" then
            return "Muahaha, I has hijacked it!"
        elseif msg == "name" then
            return "Parent2"
        else
            return MethodMissing(parents,msg)
        end
    end
end
function CreateParent3(...)
    local self = {}
    local parents = TrapParents({n=select('#', ...),...})
    return function(msg)
        if msg == "helloParent3" then
            return "hello from parent3"
        elseif msg == "hijacked" then
            return "Not Hijacked"
        elseif msg == "name" then
            return "Parent3"
        else
            return MethodMissing(parents,msg)
        end
    end
end
function CreateInstance(...)
    local self = {}
    local parents = TrapParents({n=select('#', ...),...})
    return function(msg)
        if msg == "setMessage" then
            return function (s)
                self.message = s
            end
        elseif msg == "getMessage" then
            return self.message
        else
            return MethodMissing(parents,msg)
        end
    end
end
local x = CreateInstance(CreateParent2(CreateParent1()),CreateParent3())
x("setMessage")("Hello World")
print(x("getMessage"))
x("setMessage")("Goobye Cruel World")
print(x("getMessage"))
print(x("helloParent1"))
print(x("helloParent3"))
print(x("hijacked"))
print(x("notImplemented"))

We notice that the order of searching for a function is left to right. Since CreateParent2 comes first, it is searched first and therefore hijacks. We may want to do it backwards:

function TraverseParents(parents,message,...)
    local res = nil
    for i=#parents,1,-1 do
        res = parents[i](message)
        if res then
            return res
        end
    end
    return nil
end