lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


First off, thanks for your answer. It helps to see what other people think or what solutions they've come up with.

I've seen the solution using a "function decorator" on the page I linked, though I wasn't sure if there are any benefits to it. Is it more efficient than putting the typechecks directly in the used function? Thinking about it, I suppose an advantage would be that the original function can be left untouched, potentially making it easier to separate function declaration and its actual body.

Metalua seems very interesting, but as I said I'm using luajit, and I don't think metalua is compatible.



2011/12/2 Dimiter 'malkia' Stanev <malkia@gmail.com>
There is probably already solutions to this, like metalua, or in projects like the zile (mini emacs) the lua version (look for the Defun function there).

Here is my little 5 minute concontion. It's not efficient at all, and a bit ugly, but might get you started:

-- This is our function definer - e.g. a function that generates function
local function def( ... )
  local args = { ... }
  local types = {}
  local func

  for _, v in ipairs(args) do
     local type = type(v)
     if type == "function" then
        func = v
        break
     end
     types[ #types + 1 ] = v
  end

  return function( ... )
     local args = { ... }
     if #args ~= #types then
        error( "Expected " .. #types .. " arguments, got " .. #args " instead!" )
     end
     for a = 1, #types do
        local type = type(args[a])
        if types[a] ~= type then
           error( "Expected argument " .. a .. " to be of type " .. types[a] .. ", instead it's type " .. type )
        end
     end
     -- You can extend here, by declaring what you expect to be returned
     return func(...)
  end
end

-- Let's make a test - an unfinished "C" like strcmp functin that expects string, string, then number
local strcmp = def(
  "string", "string", "number",
  function( s1, s2, len )
     for i = 1, len do
        if true then
        end
     end
  end)        
               
-- This is okay
strcmp("test","blah",10)

-- Next would error out
strcmp("test","blah","10")

Thanks,
Dimiter "malkia" Stanev.


On 12/2/2011 11:42 AM, Christian Bielert wrote:
I'm currently in the process of integrating luajit into my game engine,
using its most superb FFI. I have chosen lua for various reasons, among
others that I want my own class-system and lua offers the most
flexibility in this.

Of course, lua only offers this flexibility by not providing this
mechanism in the first place. And sadly, while it does provide the tools
to build your own such mechanism, there's no way to adjust its syntax
for this.. As such, my current plan is to use a preprocessor to create

the kind of syntax that I desire, such as "class" constructs or typed
function signatures. Unrelated, but the a+=1 syntax wouldn't hurt either :)


In either case, my current concern is mostly the semantics, not the
syntax. A thing that I will need pretty early on will be clean, fast
type-checks on function entry. http://lua-users.org/wiki/LuaTypeChecking
provides some useful information on that, though I personally would
prefer something along the lines of:

function param_guard(var, dtype, default)
   if not var then return default end
   if type(var) ~= dtype then error("Type error") end
end

function foo(a, b, c)
   a = param_guard(a, "number")
   a = param_guard(b, "string", "nA")
   a = param_guard(c, "int")
end


Obviously, the type-checks would have to be extended to also support
cdata and custom class-objects, but the point should be clear. It
basically reflects a function declaration as it can be found in C++,
i.e. in C++ you would write the above code as: void foo(number a, string
b = "nA", int c)


My only concern is whether code like this will be efficient, or in fact,
if a semantic like this can be achieved at all without huge loss in
efficiency. I'm mainly concerned since I know that luajit relies on a
lot of internal optimizations, and I'm concerned that a lot of these
manual typechecks will make it impossible for some of these
optimizations to happen.

Anyway, I'm mainly asking here since I have little experience with lua,
and if there are any fundamental flaws with my approach, the sooner I
know it the better. :)