lua-users home
lua-l archive

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


On Tue, Dec 08, 1998 at 03:30:07PM -0200, Roberto Ierusalimschy wrote:
> > [...] Is there some way to do assignment inside
> > an expression like this, and if not, why not?
> 
> Why not?
> The main reason is syntactical. Assignments inside expressions would create
> many syntactical ambiguities in the language. For instance, the constructor
> {x=3, y=4} could be interpreted in the current way, or as a list of two
> expressions, x=3 (value 3 to be stored in index 1) and y=4 (value 4
> in index 2). As lhf said, you can do something "equivalent", but with
> another syntax (calling a function).

When I wrote the above, I was thinking about wanting to do nicer
iterators. However, I've decided that if there was a way to write a
'macro' which was bound into the callers scope, then we could do some
really nice things.

I propose the following idea for making a block of code which runs
inside the local-scope of the caller, but is otherwise similar to a
function and evaluates as such:

-- note that I don't necessarily like the syntactic use of "macro", I'm
-- just describing it this way for simplicity

macro (arg1, arg2, ...)   -- arguments are optional
end

macro for(from,to,code)
   local i = from

   while (i<to) do
      code(i);
      i = i + 1;
   end
end


for(1,2, macro (x)
  print("iteration: ".. tostring(x));
end);

macro foreach(tbl,code)
   local i,v = next(tbl,nil)

   while (i) do
     code(v,i,tbl); -- note the inverse (v,i)
     i,v = next(tbl,i);
   end
end

macro foreach_iter(tbl,code)
   local iter_index_tbl = {}
   local iter_value_tbl = {}
   local iter_num = 1
   local i,v = next(tbl,nil)
  
   while(i) do
    iter_index_tbl[iter_num] = i;
    iter_value_tbl[iter_num] = v;
    i,v = next(tbl,i);
    iter_num = iter_num + 1;
   end

   local iter_var = 1;

   while (iter_var < iter_num) do
     code(iter_value_tbl[iter_var],iter_index_tbl[iter_var],tbl);
     iter_var = iter_var + 1;
   end

foreach({ x = 1, y = 2, z = 3}, macro (v,i,tbl)
    print(format("[%s] = %d",i,v));
end);
  -- output (might be in different order):
  -- [x] = 1
  -- [y] = 2
  -- [z] = 3

local t = { x = 1, y = 2, z = 3};

foreach_iter(t, macro(v,i,tbl)
    print(format("[%s] = %d",i,v));
    t[i] = nil;
end);

  -- output (might be in different order):
  -- [x] = 1
  -- [y] = 2
  -- [z] = 3

foreach(t,macro(v,i,tbl)
    print(format("[%s] = %d",i,v));
end);

  -- no output, because the above 'foreach_iter' removed all the elements

-- 
David Jeske (N9LCA) + http://www.chat.net/~jeske/ + jeske@chat.net