  lua-l archive

• Subject: Re: Addition of map() and filter().
• From: Jim Jennings <jennings.durham.nc+lua@...>
• Date: Wed, 14 Oct 2009 17:45:24 -0400

```>> >    function map(f,...)
>> >      if select('#',...) == 0 then return end
>> >      return f((...)),map(f,select(2,...))
>> >    end

Recursion and tail-call optimization are the right ideas here, of
course.  Given this particular signature for the map function, I would
write:

local function map1(f, a, results, i)
if i==0 then return results;  end
results[i] = f(a[i])
return map1(f, a, results, i-1)
end

function map(f, ...)
local a = {...}
return unpack(map1(f, a, {}, #a))
end

However, there are good reasons to consider using the classical
signature for map instead.  In other words, the arguments to map could
be a function and a table (instead of a function and a series of
arguments which implicitly form a list).

> =map(function(x) return x+1 end, list(4, 5, 6))
{5, 6, 7}
>

Using this approach, you can map multi-argument functions, and you can
also write 'reduce', which is another handy utility:

> =map(function(x,y) return math.sqrt(x^2+y^2) end, list(3, 6, 9), list(4, 8, 12))
{5, 10, 15}
> =reduce(function(x, acc) return x*acc end, list(1, 2, 3, 4), 1)
24
>

Note: These examples use my own list module, which is why there is
pretty printing of lists such as {5, 10, 15}.

One could easily write the same functions (map, filter, reduce,
foreach, member, etc.) for "tables used as arrays", which I think is
what the original poster was thinking of as an approximation to a true
list data type.

Since (1) tables are not lists, and (2) list-processing functions can
be implemented easily in either Lua or C, what is the benefit of
incorporating list-processing functions into the Lua language?  I
don't see any benefits.

--Jim

```