lua-users home
lua-l archive

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

There isn't a lot that I want that can't be emulated in another way.
For example, something I find quite useful is array slicing:

  a = { 1, 2, 3, 4, 5 }
  two, three, four = a[2..4]

You might like metalua's "clist" macro, which adds lists by comprehension and slicing, letting you write stuff like:

-{extension "clist"
-- integers from 2 to 50, by steps of 2:
x = { i for i = 2, 50, 2 }

-- the same, obtained by filtering over all integers <= 50:
y = { i for i = 1, 50 if i%2== 0 }

-- prime numbers, implemented in an inefficient way:
local sieve, n = { i for i=2, 100 }, 1
while n < #sieve do
sieve = {
i for i in values(sieve[1 ... n]);
i for i in values(sieve[n+1 ... #sieve]) if i%sieve[n] ~= 0 }
n += 1
Notice that "..." is used rather than "..": the former would cause plenty of mess with concatenation, especially when concatenation is overloaded by metatables.

As for the "function(x or 5)" syntax, it could be implemented roughly that way (naive, dirty, untested code):
mlp.func_val = gg.sequence{

"(", gg.list{ gg.sequence{ mlp.expr, gg.onkeyword { "or", mlp.expr } },
terminators = ")", separators = "," }, ")", mlp.block, "end",
builder = func_val_builder }
function func_val_builder(x)
   local params, body = unpack(x)
   for i, p in pairs(params) do
      assert(p[1].tag=='Id' or p[1].tag=='Dots' and i==#params,
             "Function parameters must be identifiers or a final vararg")
      if p[2] then
         assert(p[1].tag=='Id', "No default allowed for vararg")
         local var, default = unpack(p)
         table.insert(body, 1, +{ (-{var}) = -{var} or -{default} })
   return `Function{
{ p[1] for _, p in pairs(params) }, body }

Notice also that this hack is non-composing: other macros overloading the function definition parser would break it, and you'd better think twice before doing such a dangerous thing. My personal feeling is that this syntax sugar is not helpful enough to justify a brittle extension. Generally speaking, such monkey patching of mlp should only be done in very special situations, and should trigger your design smell detector.

-- Fabien.