lua-users home
lua-l archive

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


On 3 December 2011 21:31, Robert G. Jakabosky <bobby@sharedrealm.com> wrote:
> On Friday 02, 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
>
> You could do that with a pre-processor that only parses and replace special
> comments.
>
> function foo(a, b, c)
>   --[[PARAMS: number a, string b = "nA", int c ]]
> end
>
> After running it through the pre-processor you would then end up with Lua code
> like your example.  This would also allow the pre-processor step to be
> skipped/disabled for production runs or when you need extra speed.  With the
> "PARAMS" comment inside the function the pre-processor would only need to do a
> simple search/parse/replace to enable the checks.
>
> With a small change the pre-processor could be hooked into lua/luajit so all
> Lua code is passed through it.  The pre-processor could even be written in Lua
> code using LPeg see the example Lua code lexer & parser at [1].  Using a full
> Lua parser would allow the type info to be parsed from a Doxygen/javadoc style
> comment before the function.
>
> 1. http://lua-users.org/wiki/LpegRecipes
>
>>
>>
>> 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.
>
> If you make it easy to disable the checks then you can benchmark the cost of
> the type checking and then decided to keep the checks enabled or not.
>
>> 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. :)
>
>
> --
> Robert G. Jakabosky
>

My solution was to merge it with a documentation engine:

local myfunc = doc {
    params = {
        { type = "number" , desc= "Thing to do with" } ;
        { type = "string" , desc = "A string to foobarr" } ;
    };
    returns = {
       { type = "boolean" , desc = "success" };
    }
} ( function ( n , s )
   return true
end )


The doc function can return a wrapped type checked version of the
function; or it can just return the function unmodified for
performance.

Was working on it here:
https://github.com/daurnimator/lomp2/blob/master/codedoc.lua
but have not given it much thought lately.