stevedonovan / Lake

A Lua-based Build Tool
MIT License
132 stars 16 forks source link

List constructor proposals #2 #29

Closed moteus closed 11 years ago

moteus commented 11 years ago

The first is on #8. This is my implementation

DEFS = L{
  IF(DEBUG,  {'_DEBUG', 'DEBUG'},'NDEBUG');
  IF(DEBUG,  'LUASOCKET_DEBUG');
  IF(WINDOWS,{'WIN32','_WIN32','_WINDOWS'});
  IF(MSVC,   {'_CRT_SECURE_NO_WARNINGS', '_WIN32_WINNT=0x' .. WINVER});
}

We can call this function also as L(IF(...),IF(...), ...), but i like always paste ; at the end of each element. This function always create new array and doesn't change any exist (unlike in #8).

stevedonovan commented 11 years ago

I do like the idea, but I need to integrate it somehow with deps_arg, so that something like L{'one', nil, 'two three'} would expand as {'one','two','three'}

moteus commented 11 years ago

L{'one', nil, 'two three'} would expand as {'one','two','three'}

My implementation do that. It remove "holes" and save order of elements.

stevedonovan commented 11 years ago

The "hole" removal is very cool, you taught me something new in Lua!

Here's the version I now have in Lake based on your implementation

function L(t)
    if type(t) ~= 'table' then
        return lake.deps_arg(t)
    end
    local res,keys = {},{}
    for k,v in pairs(t) do
        append(keys,k)
    end
    table.sort(keys)
    for _,k in ipairs(keys) do
        list.extend(res,L(t[k]))
    end
    return res
end

Uses the available Lake functions as much as possible - please see new docs at

http://stevedonovan.github.io/lake/modules/lakelibs.html

Now L'one two' will expand to {'one','two'} which is useful and consistent with how strings are processed elsewhere.

moteus commented 11 years ago

from doc:

L{IF(X,'a'),IF(Y,{'one','two'}} == {'one','two'} if X is true, Y is false

do we need if X is false, Y is true?

stevedonovan commented 11 years ago

Yes, wrong way around ;) I'll fix.

moteus commented 11 years ago

Also i think about key->value tables (e.g. defines) defs = L{"_DEBUG", WINVER=501} I think we should just copy all pairs with non number keys.

    for k,v in pairs(t) do
        append(keys,k)
    end

accept non number keys but

    for _,k in ipairs(keys) do
        list.extend(res,L(t[k]))
    end

do wrong job with this keys. so i suggest

    for _,k in ipairs(keys) do
        if type(k) == "number" then -- or k == math.floor(k) -- to check integer
          list.extend(res,L(t[k]))
        else
          res[k] = t[k] -- this can not be list
        end
    end
moteus commented 11 years ago

And one minor suggestion. implement L as

local function L_impl(...)
  ....
  L_impl(...)
  ...
end
L = L_impl

This needs if you would use this function in lake them self. So no one can not re implement internal function.

stevedonovan commented 11 years ago

OK, we have choice to leave out string keys, or leave them unchanged. Since with this version of Lake defines can contain string keys I've decided to pass them through:

local function L_impl(t)
    if type(t) ~= 'table' then
        return lake.deps_arg(t)
    end
    local res,indices = {},{}
    for k,v in pairs(t) do
        if type(k) ~= 'number' then -- just copy string keys
            res[k] = v
        else
            append(indices,k)
        end
    end
    table.sort(indices)
    for _,k in ipairs(indices) do
        list.extend(res,L_impl(t[k]))
    end
    return res
end