List comprehensions: Difference between revisions
Content added Content deleted
(Add implementation in Lua) |
|||
Line 179: | Line 179: | ||
9,12,15 |
9,12,15 |
||
12,16,20</pre> |
12,16,20</pre> |
||
=={{header|Lua}}== |
|||
Lua doesn't have list comprehensions built in, but they can be constructed from chained coroutines: |
|||
<lang lua> |
|||
LC={} |
|||
LC.__index = LC |
|||
function LC:new(o) |
|||
o = o or {} |
|||
setmetatable(o, self) |
|||
return o |
|||
end |
|||
function LC:add_iter(func) |
|||
local prev_iter = self.iter |
|||
self.iter = coroutine.wrap( |
|||
(prev_iter == nil) and (function() func{} end) |
|||
or (function() for arg in prev_iter do func(arg) end end)) |
|||
return self |
|||
end |
|||
function maybe_call(maybe_func, arg) |
|||
if type(maybe_func) == "function" then return maybe_func(arg) end |
|||
return maybe_func |
|||
end |
|||
function LC:range(key, first, last) |
|||
return self:add_iter(function(arg) |
|||
for value=maybe_call(first, arg), maybe_call(last, arg) do |
|||
arg[key] = value |
|||
coroutine.yield(arg) |
|||
end |
|||
end) |
|||
end |
|||
function LC:where(pred) |
|||
return self:add_iter(function(arg) if pred(arg) then coroutine.yield(arg) end end) |
|||
end |
|||
</lang> |
|||
We can then define a function to compute Pythagorean triples as follows: |
|||
<lang lua> |
|||
function get(key) |
|||
return (function(arg) return arg[key] end) |
|||
end |
|||
function is_pythagorean(arg) |
|||
return (arg.x^2 + arg.y^2 == arg.z^2) |
|||
end |
|||
function list_pythagorean_triples(n) |
|||
return LC:new():range("x",1,n):range("y",1,get("x")):range("z", get("y"), n):where(is_pythagorean).iter |
|||
end |
|||
for arg in list_pythagorean_triples(100) do |
|||
print(arg.x, arg.y, arg.z) |
|||
end |
|||
</lang> |
|||
=={{header|Mathematica}}== |
=={{header|Mathematica}}== |