<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
		<id>https://www.ekopedia.fr/index.php?action=history&amp;feed=atom&amp;title=Module%3ALuafun</id>
		<title>Module:Luafun - Historique des versions</title>
		<link rel="self" type="application/atom+xml" href="https://www.ekopedia.fr/index.php?action=history&amp;feed=atom&amp;title=Module%3ALuafun"/>
		<link rel="alternate" type="text/html" href="https://www.ekopedia.fr/index.php?title=Module:Luafun&amp;action=history"/>
		<updated>2026-04-25T17:59:23Z</updated>
		<subtitle>Historique pour cette page sur le wiki</subtitle>
		<generator>MediaWiki 1.27.1</generator>

	<entry>
		<id>https://www.ekopedia.fr/index.php?title=Module:Luafun&amp;diff=126392&amp;oldid=prev</id>
		<title>- Hermes - : Page créée avec « --- --- Lua Fun - a high-performance functional programming library for LuaJIT --- --- Copyright (c) 2013-2017 Roman Tsisyk &lt;roman@tsisyk.com&gt; --- --- Distributed under th... »</title>
		<link rel="alternate" type="text/html" href="https://www.ekopedia.fr/index.php?title=Module:Luafun&amp;diff=126392&amp;oldid=prev"/>
				<updated>2021-10-16T12:10:12Z</updated>
		
		<summary type="html">&lt;p&gt;Page créée avec « --- --- Lua Fun - a high-performance functional programming library for LuaJIT --- --- Copyright (c) 2013-2017 Roman Tsisyk &amp;lt;roman@tsisyk.com&amp;gt; --- --- Distributed under th... »&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;---&lt;br /&gt;
--- Lua Fun - a high-performance functional programming library for LuaJIT&lt;br /&gt;
---&lt;br /&gt;
--- Copyright (c) 2013-2017 Roman Tsisyk &amp;lt;roman@tsisyk.com&amp;gt;&lt;br /&gt;
---&lt;br /&gt;
--- Distributed under the MIT/X11 License. See COPYING.md for more details.&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
local exports = {}&lt;br /&gt;
local methods = {}&lt;br /&gt;
&lt;br /&gt;
-- compatibility with Lua 5.1/5.2&lt;br /&gt;
local unpack = rawget(table, &amp;quot;unpack&amp;quot;) or unpack&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Tools&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local return_if_not_empty = function(state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local call_if_not_empty = function(fun, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return state_x, fun(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function deepcopy(orig) -- used by cycle()&lt;br /&gt;
    local orig_type = type(orig)&lt;br /&gt;
    local copy&lt;br /&gt;
    if orig_type == 'table' then&lt;br /&gt;
        copy = {}&lt;br /&gt;
        for orig_key, orig_value in next, orig, nil do&lt;br /&gt;
            copy[deepcopy(orig_key)] = deepcopy(orig_value)&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        copy = orig&lt;br /&gt;
    end&lt;br /&gt;
    return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local iterator_mt = {&lt;br /&gt;
    -- usually called by for-in loop&lt;br /&gt;
    __call = function(self, param, state)&lt;br /&gt;
        return self.gen(param, state)&lt;br /&gt;
    end;&lt;br /&gt;
    __tostring = function(self)&lt;br /&gt;
        return '&amp;lt;generator&amp;gt;'&lt;br /&gt;
    end;&lt;br /&gt;
    -- add all exported methods&lt;br /&gt;
    __index = methods;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local wrap = function(gen, param, state)&lt;br /&gt;
    return setmetatable({&lt;br /&gt;
        gen = gen,&lt;br /&gt;
        param = param,&lt;br /&gt;
        state = state&lt;br /&gt;
    }, iterator_mt), param, state&lt;br /&gt;
end&lt;br /&gt;
exports.wrap = wrap&lt;br /&gt;
&lt;br /&gt;
local unwrap = function(self)&lt;br /&gt;
    return self.gen, self.param, self.state&lt;br /&gt;
end&lt;br /&gt;
methods.unwrap = unwrap&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Basic Functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local nil_gen = function(_param, _state)&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local string_gen = function(param, state)&lt;br /&gt;
    local state = state + 1&lt;br /&gt;
    if state &amp;gt; #param then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    local r = string.sub(param, state, state)&lt;br /&gt;
    return state, r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local ipairs_gen = ipairs({}) -- get the generating function from ipairs&lt;br /&gt;
&lt;br /&gt;
local pairs_gen = pairs({ a = 0 }) -- get the generating function from pairs&lt;br /&gt;
local map_gen = function(tab, key)&lt;br /&gt;
    local value&lt;br /&gt;
    local key, value = pairs_gen(tab, key)&lt;br /&gt;
    return key, key, value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local rawiter = function(obj, param, state)&lt;br /&gt;
    assert(obj ~= nil, &amp;quot;invalid iterator&amp;quot;)&lt;br /&gt;
    if type(obj) == &amp;quot;table&amp;quot; then&lt;br /&gt;
        local mt = getmetatable(obj);&lt;br /&gt;
        if mt ~= nil then&lt;br /&gt;
            if mt == iterator_mt then&lt;br /&gt;
                return obj.gen, obj.param, obj.state&lt;br /&gt;
            elseif mt.__ipairs ~= nil then&lt;br /&gt;
                return mt.__ipairs(obj)&lt;br /&gt;
            elseif mt.__pairs ~= nil then&lt;br /&gt;
                return mt.__pairs(obj)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        if #obj &amp;gt; 0 then&lt;br /&gt;
            -- array&lt;br /&gt;
            return ipairs(obj)&lt;br /&gt;
        else&lt;br /&gt;
            -- hash&lt;br /&gt;
            return map_gen, obj, nil&lt;br /&gt;
        end&lt;br /&gt;
    elseif (type(obj) == &amp;quot;function&amp;quot;) then&lt;br /&gt;
        return obj, param, state&lt;br /&gt;
    elseif (type(obj) == &amp;quot;string&amp;quot;) then&lt;br /&gt;
        if #obj == 0 then&lt;br /&gt;
            return nil_gen, nil, nil&lt;br /&gt;
        end&lt;br /&gt;
        return string_gen, obj, 0&lt;br /&gt;
    end&lt;br /&gt;
    error(string.format('object %s of type &amp;quot;%s&amp;quot; is not iterable',&lt;br /&gt;
          obj, type(obj)))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local iter = function(obj, param, state)&lt;br /&gt;
    return wrap(rawiter(obj, param, state))&lt;br /&gt;
end&lt;br /&gt;
exports.iter = iter&lt;br /&gt;
&lt;br /&gt;
local method0 = function(fun)&lt;br /&gt;
    return function(self)&lt;br /&gt;
        return fun(self.gen, self.param, self.state)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local method1 = function(fun)&lt;br /&gt;
    return function(self, arg1)&lt;br /&gt;
        return fun(arg1, self.gen, self.param, self.state)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local method2 = function(fun)&lt;br /&gt;
    return function(self, arg1, arg2)&lt;br /&gt;
        return fun(arg1, arg2, self.gen, self.param, self.state)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local export0 = function(fun)&lt;br /&gt;
    return function(gen, param, state)&lt;br /&gt;
        return fun(rawiter(gen, param, state))&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local export1 = function(fun)&lt;br /&gt;
    return function(arg1, gen, param, state)&lt;br /&gt;
        return fun(arg1, rawiter(gen, param, state))&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local export2 = function(fun)&lt;br /&gt;
    return function(arg1, arg2, gen, param, state)&lt;br /&gt;
        return fun(arg1, arg2, rawiter(gen, param, state))&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local each = function(fun, gen, param, state)&lt;br /&gt;
    repeat&lt;br /&gt;
        state = call_if_not_empty(fun, gen(param, state))&lt;br /&gt;
    until state == nil&lt;br /&gt;
end&lt;br /&gt;
methods.each = method1(each)&lt;br /&gt;
exports.each = export1(each)&lt;br /&gt;
methods.for_each = methods.each&lt;br /&gt;
exports.for_each = exports.each&lt;br /&gt;
methods.foreach = methods.each&lt;br /&gt;
exports.foreach = exports.each&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Generators&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local range_gen = function(param, state)&lt;br /&gt;
    local stop, step = param[1], param[2]&lt;br /&gt;
    local state = state + step&lt;br /&gt;
    if state &amp;gt; stop then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return state, state&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local range_rev_gen = function(param, state)&lt;br /&gt;
    local stop, step = param[1], param[2]&lt;br /&gt;
    local state = state + step&lt;br /&gt;
    if state &amp;lt; stop then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return state, state&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local range = function(start, stop, step)&lt;br /&gt;
    if step == nil then&lt;br /&gt;
        if stop == nil then&lt;br /&gt;
            if start == 0 then&lt;br /&gt;
                return nil_gen, nil, nil&lt;br /&gt;
            end&lt;br /&gt;
            stop = start&lt;br /&gt;
            start = stop &amp;gt; 0 and 1 or -1&lt;br /&gt;
        end&lt;br /&gt;
        step = start &amp;lt;= stop and 1 or -1&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    assert(type(start) == &amp;quot;number&amp;quot;, &amp;quot;start must be a number&amp;quot;)&lt;br /&gt;
    assert(type(stop) == &amp;quot;number&amp;quot;, &amp;quot;stop must be a number&amp;quot;)&lt;br /&gt;
    assert(type(step) == &amp;quot;number&amp;quot;, &amp;quot;step must be a number&amp;quot;)&lt;br /&gt;
    assert(step ~= 0, &amp;quot;step must not be zero&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    if (step &amp;gt; 0) then&lt;br /&gt;
        return wrap(range_gen, {stop, step}, start - step)&lt;br /&gt;
    elseif (step &amp;lt; 0) then&lt;br /&gt;
        return wrap(range_rev_gen, {stop, step}, start - step)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
exports.range = range&lt;br /&gt;
&lt;br /&gt;
local duplicate_table_gen = function(param_x, state_x)&lt;br /&gt;
    return state_x + 1, unpack(param_x)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local duplicate_fun_gen = function(param_x, state_x)&lt;br /&gt;
    return state_x + 1, param_x(state_x)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local duplicate_gen = function(param_x, state_x)&lt;br /&gt;
    return state_x + 1, param_x&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local duplicate = function(...)&lt;br /&gt;
    if select('#', ...) &amp;lt;= 1 then&lt;br /&gt;
        return wrap(duplicate_gen, select(1, ...), 0)&lt;br /&gt;
    else&lt;br /&gt;
        return wrap(duplicate_table_gen, {...}, 0)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
exports.duplicate = duplicate&lt;br /&gt;
exports.replicate = duplicate&lt;br /&gt;
exports.xrepeat = duplicate&lt;br /&gt;
&lt;br /&gt;
local tabulate = function(fun)&lt;br /&gt;
    assert(type(fun) == &amp;quot;function&amp;quot;)&lt;br /&gt;
    return wrap(duplicate_fun_gen, fun, 0)&lt;br /&gt;
end&lt;br /&gt;
exports.tabulate = tabulate&lt;br /&gt;
&lt;br /&gt;
local zeros = function()&lt;br /&gt;
    return wrap(duplicate_gen, 0, 0)&lt;br /&gt;
end&lt;br /&gt;
exports.zeros = zeros&lt;br /&gt;
&lt;br /&gt;
local ones = function()&lt;br /&gt;
    return wrap(duplicate_gen, 1, 0)&lt;br /&gt;
end&lt;br /&gt;
exports.ones = ones&lt;br /&gt;
&lt;br /&gt;
local rands_gen = function(param_x, _state_x)&lt;br /&gt;
    return 0, math.random(param_x[1], param_x[2])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local rands_nil_gen = function(_param_x, _state_x)&lt;br /&gt;
    return 0, math.random()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local rands = function(n, m)&lt;br /&gt;
    if n == nil and m == nil then&lt;br /&gt;
        return wrap(rands_nil_gen, 0, 0)&lt;br /&gt;
    end&lt;br /&gt;
    assert(type(n) == &amp;quot;number&amp;quot;, &amp;quot;invalid first arg to rands&amp;quot;)&lt;br /&gt;
    if m == nil then&lt;br /&gt;
        m = n&lt;br /&gt;
        n = 0&lt;br /&gt;
    else&lt;br /&gt;
        assert(type(m) == &amp;quot;number&amp;quot;, &amp;quot;invalid second arg to rands&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    assert(n &amp;lt; m, &amp;quot;empty interval&amp;quot;)&lt;br /&gt;
    return wrap(rands_gen, {n, m - 1}, 0)&lt;br /&gt;
end&lt;br /&gt;
exports.rands = rands&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Slicing&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local nth = function(n, gen_x, param_x, state_x)&lt;br /&gt;
    assert(n &amp;gt; 0, &amp;quot;invalid first argument to nth&amp;quot;)&lt;br /&gt;
    -- An optimization for arrays and strings&lt;br /&gt;
    if gen_x == ipairs_gen then&lt;br /&gt;
        return param_x[n]&lt;br /&gt;
    elseif gen_x == string_gen then&lt;br /&gt;
        if n &amp;lt;= #param_x then&lt;br /&gt;
            return string.sub(param_x, n, n)&lt;br /&gt;
        else&lt;br /&gt;
            return nil&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for i=1,n-1,1 do&lt;br /&gt;
        state_x = gen_x(param_x, state_x)&lt;br /&gt;
        if state_x == nil then&lt;br /&gt;
            return nil&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return return_if_not_empty(gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
methods.nth = method1(nth)&lt;br /&gt;
exports.nth = export1(nth)&lt;br /&gt;
&lt;br /&gt;
local head_call = function(state, ...)&lt;br /&gt;
    if state == nil then&lt;br /&gt;
        error(&amp;quot;head: iterator is empty&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local head = function(gen, param, state)&lt;br /&gt;
    return head_call(gen(param, state))&lt;br /&gt;
end&lt;br /&gt;
methods.head = method0(head)&lt;br /&gt;
exports.head = export0(head)&lt;br /&gt;
exports.car = exports.head&lt;br /&gt;
methods.car = methods.head&lt;br /&gt;
&lt;br /&gt;
local tail = function(gen, param, state)&lt;br /&gt;
    state = gen(param, state)&lt;br /&gt;
    if state == nil then&lt;br /&gt;
        return wrap(nil_gen, nil, nil)&lt;br /&gt;
    end&lt;br /&gt;
    return wrap(gen, param, state)&lt;br /&gt;
end&lt;br /&gt;
methods.tail = method0(tail)&lt;br /&gt;
exports.tail = export0(tail)&lt;br /&gt;
exports.cdr = exports.tail&lt;br /&gt;
methods.cdr = methods.tail&lt;br /&gt;
&lt;br /&gt;
local take_n_gen_x = function(i, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return {i, state_x}, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local take_n_gen = function(param, state)&lt;br /&gt;
    local n, gen_x, param_x = param[1], param[2], param[3]&lt;br /&gt;
    local i, state_x = state[1], state[2]&lt;br /&gt;
    if i &amp;gt;= n then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return take_n_gen_x(i + 1, gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local take_n = function(n, gen, param, state)&lt;br /&gt;
    assert(n &amp;gt;= 0, &amp;quot;invalid first argument to take_n&amp;quot;)&lt;br /&gt;
    return wrap(take_n_gen, {n, gen, param}, {0, state})&lt;br /&gt;
end&lt;br /&gt;
methods.take_n = method1(take_n)&lt;br /&gt;
exports.take_n = export1(take_n)&lt;br /&gt;
&lt;br /&gt;
local take_while_gen_x = function(fun, state_x, ...)&lt;br /&gt;
    if state_x == nil or not fun(...) then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return state_x, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local take_while_gen = function(param, state_x)&lt;br /&gt;
    local fun, gen_x, param_x = param[1], param[2], param[3]&lt;br /&gt;
    return take_while_gen_x(fun, gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local take_while = function(fun, gen, param, state)&lt;br /&gt;
    assert(type(fun) == &amp;quot;function&amp;quot;, &amp;quot;invalid first argument to take_while&amp;quot;)&lt;br /&gt;
    return wrap(take_while_gen, {fun, gen, param}, state)&lt;br /&gt;
end&lt;br /&gt;
methods.take_while = method1(take_while)&lt;br /&gt;
exports.take_while = export1(take_while)&lt;br /&gt;
&lt;br /&gt;
local take = function(n_or_fun, gen, param, state)&lt;br /&gt;
    if type(n_or_fun) == &amp;quot;number&amp;quot; then&lt;br /&gt;
        return take_n(n_or_fun, gen, param, state)&lt;br /&gt;
    else&lt;br /&gt;
        return take_while(n_or_fun, gen, param, state)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
methods.take = method1(take)&lt;br /&gt;
exports.take = export1(take)&lt;br /&gt;
&lt;br /&gt;
local drop_n = function(n, gen, param, state)&lt;br /&gt;
    assert(n &amp;gt;= 0, &amp;quot;invalid first argument to drop_n&amp;quot;)&lt;br /&gt;
    local i&lt;br /&gt;
    for i=1,n,1 do&lt;br /&gt;
        state = gen(param, state)&lt;br /&gt;
        if state == nil then&lt;br /&gt;
            return wrap(nil_gen, nil, nil)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return wrap(gen, param, state)&lt;br /&gt;
end&lt;br /&gt;
methods.drop_n = method1(drop_n)&lt;br /&gt;
exports.drop_n = export1(drop_n)&lt;br /&gt;
&lt;br /&gt;
local drop_while_x = function(fun, state_x, ...)&lt;br /&gt;
    if state_x == nil or not fun(...) then&lt;br /&gt;
        return state_x, false&lt;br /&gt;
    end&lt;br /&gt;
    return state_x, true, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local drop_while = function(fun, gen_x, param_x, state_x)&lt;br /&gt;
    assert(type(fun) == &amp;quot;function&amp;quot;, &amp;quot;invalid first argument to drop_while&amp;quot;)&lt;br /&gt;
    local cont, state_x_prev&lt;br /&gt;
    repeat&lt;br /&gt;
        state_x_prev = deepcopy(state_x)&lt;br /&gt;
        state_x, cont = drop_while_x(fun, gen_x(param_x, state_x))&lt;br /&gt;
    until not cont&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return wrap(nil_gen, nil, nil)&lt;br /&gt;
    end&lt;br /&gt;
    return wrap(gen_x, param_x, state_x_prev)&lt;br /&gt;
end&lt;br /&gt;
methods.drop_while = method1(drop_while)&lt;br /&gt;
exports.drop_while = export1(drop_while)&lt;br /&gt;
&lt;br /&gt;
local drop = function(n_or_fun, gen_x, param_x, state_x)&lt;br /&gt;
    if type(n_or_fun) == &amp;quot;number&amp;quot; then&lt;br /&gt;
        return drop_n(n_or_fun, gen_x, param_x, state_x)&lt;br /&gt;
    else&lt;br /&gt;
        return drop_while(n_or_fun, gen_x, param_x, state_x)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
methods.drop = method1(drop)&lt;br /&gt;
exports.drop = export1(drop)&lt;br /&gt;
&lt;br /&gt;
local split = function(n_or_fun, gen_x, param_x, state_x)&lt;br /&gt;
    return take(n_or_fun, gen_x, param_x, state_x),&lt;br /&gt;
           drop(n_or_fun, gen_x, param_x, state_x)&lt;br /&gt;
end&lt;br /&gt;
methods.split = method1(split)&lt;br /&gt;
exports.split = export1(split)&lt;br /&gt;
methods.split_at = methods.split&lt;br /&gt;
exports.split_at = exports.split&lt;br /&gt;
methods.span = methods.split&lt;br /&gt;
exports.span = exports.split&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Indexing&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local index = function(x, gen, param, state)&lt;br /&gt;
    local i = 1&lt;br /&gt;
    for _k, r in gen, param, state do&lt;br /&gt;
        if r == x then&lt;br /&gt;
            return i&lt;br /&gt;
        end&lt;br /&gt;
        i = i + 1&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
methods.index = method1(index)&lt;br /&gt;
exports.index = export1(index)&lt;br /&gt;
methods.index_of = methods.index&lt;br /&gt;
exports.index_of = exports.index&lt;br /&gt;
methods.elem_index = methods.index&lt;br /&gt;
exports.elem_index = exports.index&lt;br /&gt;
&lt;br /&gt;
local indexes_gen = function(param, state)&lt;br /&gt;
    local x, gen_x, param_x = param[1], param[2], param[3]&lt;br /&gt;
    local i, state_x = state[1], state[2]&lt;br /&gt;
    local r&lt;br /&gt;
    while true do&lt;br /&gt;
        state_x, r = gen_x(param_x, state_x)&lt;br /&gt;
        if state_x == nil then&lt;br /&gt;
            return nil&lt;br /&gt;
        end&lt;br /&gt;
        i = i + 1&lt;br /&gt;
        if r == x then&lt;br /&gt;
            return {i, state_x}, i&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local indexes = function(x, gen, param, state)&lt;br /&gt;
    return wrap(indexes_gen, {x, gen, param}, {0, state})&lt;br /&gt;
end&lt;br /&gt;
methods.indexes = method1(indexes)&lt;br /&gt;
exports.indexes = export1(indexes)&lt;br /&gt;
methods.elem_indexes = methods.indexes&lt;br /&gt;
exports.elem_indexes = exports.indexes&lt;br /&gt;
methods.indices = methods.indexes&lt;br /&gt;
exports.indices = exports.indexes&lt;br /&gt;
methods.elem_indices = methods.indexes&lt;br /&gt;
exports.elem_indices = exports.indexes&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Filtering&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local filter1_gen = function(fun, gen_x, param_x, state_x, a)&lt;br /&gt;
    while true do&lt;br /&gt;
        if state_x == nil or fun(a) then break; end&lt;br /&gt;
        state_x, a = gen_x(param_x, state_x)&lt;br /&gt;
    end&lt;br /&gt;
    return state_x, a&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- call each other&lt;br /&gt;
local filterm_gen&lt;br /&gt;
local filterm_gen_shrink = function(fun, gen_x, param_x, state_x)&lt;br /&gt;
    return filterm_gen(fun, gen_x, param_x, gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
filterm_gen = function(fun, gen_x, param_x, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    if fun(...) then&lt;br /&gt;
        return state_x, ...&lt;br /&gt;
    end&lt;br /&gt;
    return filterm_gen_shrink(fun, gen_x, param_x, state_x)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local filter_detect = function(fun, gen_x, param_x, state_x, ...)&lt;br /&gt;
    if select('#', ...) &amp;lt; 2 then&lt;br /&gt;
        return filter1_gen(fun, gen_x, param_x, state_x, ...)&lt;br /&gt;
    else&lt;br /&gt;
        return filterm_gen(fun, gen_x, param_x, state_x, ...)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local filter_gen = function(param, state_x)&lt;br /&gt;
    local fun, gen_x, param_x = param[1], param[2], param[3]&lt;br /&gt;
    return filter_detect(fun, gen_x, param_x, gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local filter = function(fun, gen, param, state)&lt;br /&gt;
    return wrap(filter_gen, {fun, gen, param}, state)&lt;br /&gt;
end&lt;br /&gt;
methods.filter = method1(filter)&lt;br /&gt;
exports.filter = export1(filter)&lt;br /&gt;
methods.remove_if = methods.filter&lt;br /&gt;
exports.remove_if = exports.filter&lt;br /&gt;
&lt;br /&gt;
local grep = function(fun_or_regexp, gen, param, state)&lt;br /&gt;
    local fun = fun_or_regexp&lt;br /&gt;
    if type(fun_or_regexp) == &amp;quot;string&amp;quot; then&lt;br /&gt;
        fun = function(x) return string.find(x, fun_or_regexp) ~= nil end&lt;br /&gt;
    end&lt;br /&gt;
    return filter(fun, gen, param, state)&lt;br /&gt;
end&lt;br /&gt;
methods.grep = method1(grep)&lt;br /&gt;
exports.grep = export1(grep)&lt;br /&gt;
&lt;br /&gt;
local partition = function(fun, gen, param, state)&lt;br /&gt;
    local neg_fun = function(...)&lt;br /&gt;
        return not fun(...)&lt;br /&gt;
    end&lt;br /&gt;
    return filter(fun, gen, param, state),&lt;br /&gt;
           filter(neg_fun, gen, param, state)&lt;br /&gt;
end&lt;br /&gt;
methods.partition = method1(partition)&lt;br /&gt;
exports.partition = export1(partition)&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Reducing&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local foldl_call = function(fun, start, state, ...)&lt;br /&gt;
    if state == nil then&lt;br /&gt;
        return nil, start&lt;br /&gt;
    end&lt;br /&gt;
    return state, fun(start, ...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local foldl = function(fun, start, gen_x, param_x, state_x)&lt;br /&gt;
    while true do&lt;br /&gt;
        state_x, start = foldl_call(fun, start, gen_x(param_x, state_x))&lt;br /&gt;
        if state_x == nil then&lt;br /&gt;
            break;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return start&lt;br /&gt;
end&lt;br /&gt;
methods.foldl = method2(foldl)&lt;br /&gt;
exports.foldl = export2(foldl)&lt;br /&gt;
methods.reduce = methods.foldl&lt;br /&gt;
exports.reduce = exports.foldl&lt;br /&gt;
&lt;br /&gt;
local length = function(gen, param, state)&lt;br /&gt;
    if gen == ipairs_gen or gen == string_gen then&lt;br /&gt;
        return #param&lt;br /&gt;
    end&lt;br /&gt;
    local len = 0&lt;br /&gt;
    repeat&lt;br /&gt;
        state = gen(param, state)&lt;br /&gt;
        len = len + 1&lt;br /&gt;
    until state == nil&lt;br /&gt;
    return len - 1&lt;br /&gt;
end&lt;br /&gt;
methods.length = method0(length)&lt;br /&gt;
exports.length = export0(length)&lt;br /&gt;
&lt;br /&gt;
local is_null = function(gen, param, state)&lt;br /&gt;
    return gen(param, deepcopy(state)) == nil&lt;br /&gt;
end&lt;br /&gt;
methods.is_null = method0(is_null)&lt;br /&gt;
exports.is_null = export0(is_null)&lt;br /&gt;
&lt;br /&gt;
local is_prefix_of = function(iter_x, iter_y)&lt;br /&gt;
    local gen_x, param_x, state_x = iter(iter_x)&lt;br /&gt;
    local gen_y, param_y, state_y = iter(iter_y)&lt;br /&gt;
&lt;br /&gt;
    local r_x, r_y&lt;br /&gt;
    for i=1,10,1 do&lt;br /&gt;
        state_x, r_x = gen_x(param_x, state_x)&lt;br /&gt;
        state_y, r_y = gen_y(param_y, state_y)&lt;br /&gt;
        if state_x == nil then&lt;br /&gt;
            return true&lt;br /&gt;
        end&lt;br /&gt;
        if state_y == nil or r_x ~= r_y then&lt;br /&gt;
            return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
methods.is_prefix_of = is_prefix_of&lt;br /&gt;
exports.is_prefix_of = is_prefix_of&lt;br /&gt;
&lt;br /&gt;
local all = function(fun, gen_x, param_x, state_x)&lt;br /&gt;
    local r&lt;br /&gt;
    repeat&lt;br /&gt;
        state_x, r = call_if_not_empty(fun, gen_x(param_x, state_x))&lt;br /&gt;
    until state_x == nil or not r&lt;br /&gt;
    return state_x == nil&lt;br /&gt;
end&lt;br /&gt;
methods.all = method1(all)&lt;br /&gt;
exports.all = export1(all)&lt;br /&gt;
methods.every = methods.all&lt;br /&gt;
exports.every = exports.all&lt;br /&gt;
&lt;br /&gt;
local any = function(fun, gen_x, param_x, state_x)&lt;br /&gt;
    local r&lt;br /&gt;
    repeat&lt;br /&gt;
        state_x, r = call_if_not_empty(fun, gen_x(param_x, state_x))&lt;br /&gt;
    until state_x == nil or r&lt;br /&gt;
    return not not r&lt;br /&gt;
end&lt;br /&gt;
methods.any = method1(any)&lt;br /&gt;
exports.any = export1(any)&lt;br /&gt;
methods.some = methods.any&lt;br /&gt;
exports.some = exports.any&lt;br /&gt;
&lt;br /&gt;
local sum = function(gen, param, state)&lt;br /&gt;
    local s = 0&lt;br /&gt;
    local r = 0&lt;br /&gt;
    repeat&lt;br /&gt;
        s = s + r&lt;br /&gt;
        state, r = gen(param, state)&lt;br /&gt;
    until state == nil&lt;br /&gt;
    return s&lt;br /&gt;
end&lt;br /&gt;
methods.sum = method0(sum)&lt;br /&gt;
exports.sum = export0(sum)&lt;br /&gt;
&lt;br /&gt;
local product = function(gen, param, state)&lt;br /&gt;
    local p = 1&lt;br /&gt;
    local r = 1&lt;br /&gt;
    repeat&lt;br /&gt;
        p = p * r&lt;br /&gt;
        state, r = gen(param, state)&lt;br /&gt;
    until state == nil&lt;br /&gt;
    return p&lt;br /&gt;
end&lt;br /&gt;
methods.product = method0(product)&lt;br /&gt;
exports.product = export0(product)&lt;br /&gt;
&lt;br /&gt;
local min_cmp = function(m, n)&lt;br /&gt;
    if n &amp;lt; m then return n else return m end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local max_cmp = function(m, n)&lt;br /&gt;
    if n &amp;gt; m then return n else return m end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local min = function(gen, param, state)&lt;br /&gt;
    local state, m = gen(param, state)&lt;br /&gt;
    if state == nil then&lt;br /&gt;
        error(&amp;quot;min: iterator is empty&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local cmp&lt;br /&gt;
    if type(m) == &amp;quot;number&amp;quot; then&lt;br /&gt;
        -- An optimization: use math.min for numbers&lt;br /&gt;
        cmp = math.min&lt;br /&gt;
    else&lt;br /&gt;
        cmp = min_cmp&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, r in gen, param, state do&lt;br /&gt;
        m = cmp(m, r)&lt;br /&gt;
    end&lt;br /&gt;
    return m&lt;br /&gt;
end&lt;br /&gt;
methods.min = method0(min)&lt;br /&gt;
exports.min = export0(min)&lt;br /&gt;
methods.minimum = methods.min&lt;br /&gt;
exports.minimum = exports.min&lt;br /&gt;
&lt;br /&gt;
local min_by = function(cmp, gen_x, param_x, state_x)&lt;br /&gt;
    local state_x, m = gen_x(param_x, state_x)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        error(&amp;quot;min: iterator is empty&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, r in gen_x, param_x, state_x do&lt;br /&gt;
        m = cmp(m, r)&lt;br /&gt;
    end&lt;br /&gt;
    return m&lt;br /&gt;
end&lt;br /&gt;
methods.min_by = method1(min_by)&lt;br /&gt;
exports.min_by = export1(min_by)&lt;br /&gt;
methods.minimum_by = methods.min_by&lt;br /&gt;
exports.minimum_by = exports.min_by&lt;br /&gt;
&lt;br /&gt;
local max = function(gen_x, param_x, state_x)&lt;br /&gt;
    local state_x, m = gen_x(param_x, state_x)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        error(&amp;quot;max: iterator is empty&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local cmp&lt;br /&gt;
    if type(m) == &amp;quot;number&amp;quot; then&lt;br /&gt;
        -- An optimization: use math.max for numbers&lt;br /&gt;
        cmp = math.max&lt;br /&gt;
    else&lt;br /&gt;
        cmp = max_cmp&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, r in gen_x, param_x, state_x do&lt;br /&gt;
        m = cmp(m, r)&lt;br /&gt;
    end&lt;br /&gt;
    return m&lt;br /&gt;
end&lt;br /&gt;
methods.max = method0(max)&lt;br /&gt;
exports.max = export0(max)&lt;br /&gt;
methods.maximum = methods.max&lt;br /&gt;
exports.maximum = exports.max&lt;br /&gt;
&lt;br /&gt;
local max_by = function(cmp, gen_x, param_x, state_x)&lt;br /&gt;
    local state_x, m = gen_x(param_x, state_x)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        error(&amp;quot;max: iterator is empty&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, r in gen_x, param_x, state_x do&lt;br /&gt;
        m = cmp(m, r)&lt;br /&gt;
    end&lt;br /&gt;
    return m&lt;br /&gt;
end&lt;br /&gt;
methods.max_by = method1(max_by)&lt;br /&gt;
exports.max_by = export1(max_by)&lt;br /&gt;
methods.maximum_by = methods.maximum_by&lt;br /&gt;
exports.maximum_by = exports.maximum_by&lt;br /&gt;
&lt;br /&gt;
local totable = function(gen_x, param_x, state_x)&lt;br /&gt;
    local tab, key, val = {}&lt;br /&gt;
    while true do&lt;br /&gt;
        state_x, val = gen_x(param_x, state_x)&lt;br /&gt;
        if state_x == nil then&lt;br /&gt;
            break&lt;br /&gt;
        end&lt;br /&gt;
        table.insert(tab, val)&lt;br /&gt;
    end&lt;br /&gt;
    return tab&lt;br /&gt;
end&lt;br /&gt;
methods.totable = method0(totable)&lt;br /&gt;
exports.totable = export0(totable)&lt;br /&gt;
&lt;br /&gt;
local tomap = function(gen_x, param_x, state_x)&lt;br /&gt;
    local tab, key, val = {}&lt;br /&gt;
    while true do&lt;br /&gt;
        state_x, key, val = gen_x(param_x, state_x)&lt;br /&gt;
        if state_x == nil then&lt;br /&gt;
            break&lt;br /&gt;
        end&lt;br /&gt;
        tab[key] = val&lt;br /&gt;
    end&lt;br /&gt;
    return tab&lt;br /&gt;
end&lt;br /&gt;
methods.tomap = method0(tomap)&lt;br /&gt;
exports.tomap = export0(tomap)&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Transformations&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local map_gen = function(param, state)&lt;br /&gt;
    local gen_x, param_x, fun = param[1], param[2], param[3]&lt;br /&gt;
    return call_if_not_empty(fun, gen_x(param_x, state))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local map = function(fun, gen, param, state)&lt;br /&gt;
    return wrap(map_gen, {gen, param, fun}, state)&lt;br /&gt;
end&lt;br /&gt;
methods.map = method1(map)&lt;br /&gt;
exports.map = export1(map)&lt;br /&gt;
&lt;br /&gt;
local enumerate_gen_call = function(state, i, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return {i + 1, state_x}, i, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local enumerate_gen = function(param, state)&lt;br /&gt;
    local gen_x, param_x = param[1], param[2]&lt;br /&gt;
    local i, state_x = state[1], state[2]&lt;br /&gt;
    return enumerate_gen_call(state, i, gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local enumerate = function(gen, param, state)&lt;br /&gt;
    return wrap(enumerate_gen, {gen, param}, {1, state})&lt;br /&gt;
end&lt;br /&gt;
methods.enumerate = method0(enumerate)&lt;br /&gt;
exports.enumerate = export0(enumerate)&lt;br /&gt;
&lt;br /&gt;
local intersperse_call = function(i, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    return {i + 1, state_x}, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local intersperse_gen = function(param, state)&lt;br /&gt;
    local x, gen_x, param_x = param[1], param[2], param[3]&lt;br /&gt;
    local i, state_x = state[1], state[2]&lt;br /&gt;
    if i % 2 == 1 then&lt;br /&gt;
        return {i + 1, state_x}, x&lt;br /&gt;
    else&lt;br /&gt;
        return intersperse_call(i, gen_x(param_x, state_x))&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- TODO: interperse must not add x to the tail&lt;br /&gt;
local intersperse = function(x, gen, param, state)&lt;br /&gt;
    return wrap(intersperse_gen, {x, gen, param}, {0, state})&lt;br /&gt;
end&lt;br /&gt;
methods.intersperse = method1(intersperse)&lt;br /&gt;
exports.intersperse = export1(intersperse)&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Compositions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function zip_gen_r(param, state, state_new, ...)&lt;br /&gt;
    if #state_new == #param / 2 then&lt;br /&gt;
        return state_new, ...&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local i = #state_new + 1&lt;br /&gt;
    local gen_x, param_x = param[2 * i - 1], param[2 * i]&lt;br /&gt;
    local state_x, r = gen_x(param_x, state[i])&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    table.insert(state_new, state_x)&lt;br /&gt;
    return zip_gen_r(param, state, state_new, r, ...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local zip_gen = function(param, state)&lt;br /&gt;
    return zip_gen_r(param, state, {})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- A special hack for zip/chain to skip last two state, if a wrapped iterator&lt;br /&gt;
-- has been passed&lt;br /&gt;
local numargs = function(...)&lt;br /&gt;
    local n = select('#', ...)&lt;br /&gt;
    if n &amp;gt;= 3 then&lt;br /&gt;
        -- Fix last argument&lt;br /&gt;
        local it = select(n - 2, ...)&lt;br /&gt;
        if type(it) == 'table' and getmetatable(it) == iterator_mt and&lt;br /&gt;
           it.param == select(n - 1, ...) and it.state == select(n, ...) then&lt;br /&gt;
            return n - 2&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return n&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local zip = function(...)&lt;br /&gt;
    local n = numargs(...)&lt;br /&gt;
    if n == 0 then&lt;br /&gt;
        return wrap(nil_gen, nil, nil)&lt;br /&gt;
    end&lt;br /&gt;
    local param = { [2 * n] = 0 }&lt;br /&gt;
    local state = { [n] = 0 }&lt;br /&gt;
&lt;br /&gt;
    local i, gen_x, param_x, state_x&lt;br /&gt;
    for i=1,n,1 do&lt;br /&gt;
        local it = select(n - i + 1, ...)&lt;br /&gt;
        gen_x, param_x, state_x = rawiter(it)&lt;br /&gt;
        param[2 * i - 1] = gen_x&lt;br /&gt;
        param[2 * i] = param_x&lt;br /&gt;
        state[i] = state_x&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return wrap(zip_gen, param, state)&lt;br /&gt;
end&lt;br /&gt;
methods.zip = zip&lt;br /&gt;
exports.zip = zip&lt;br /&gt;
&lt;br /&gt;
local cycle_gen_call = function(param, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        local gen_x, param_x, state_x0 = param[1], param[2], param[3]&lt;br /&gt;
        return gen_x(param_x, deepcopy(state_x0))&lt;br /&gt;
    end&lt;br /&gt;
    return state_x, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local cycle_gen = function(param, state_x)&lt;br /&gt;
    local gen_x, param_x, state_x0 = param[1], param[2], param[3]&lt;br /&gt;
    return cycle_gen_call(param, gen_x(param_x, state_x))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local cycle = function(gen, param, state)&lt;br /&gt;
    return wrap(cycle_gen, {gen, param, state}, deepcopy(state))&lt;br /&gt;
end&lt;br /&gt;
methods.cycle = method0(cycle)&lt;br /&gt;
exports.cycle = export0(cycle)&lt;br /&gt;
&lt;br /&gt;
-- call each other&lt;br /&gt;
local chain_gen_r1&lt;br /&gt;
local chain_gen_r2 = function(param, state, state_x, ...)&lt;br /&gt;
    if state_x == nil then&lt;br /&gt;
        local i = state[1]&lt;br /&gt;
        i = i + 1&lt;br /&gt;
        if param[3 * i - 1] == nil then&lt;br /&gt;
            return nil&lt;br /&gt;
        end&lt;br /&gt;
        local state_x = param[3 * i]&lt;br /&gt;
        return chain_gen_r1(param, {i, state_x})&lt;br /&gt;
    end&lt;br /&gt;
    return {state[1], state_x}, ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
chain_gen_r1 = function(param, state)&lt;br /&gt;
    local i, state_x = state[1], state[2]&lt;br /&gt;
    local gen_x, param_x = param[3 * i - 2], param[3 * i - 1]&lt;br /&gt;
    return chain_gen_r2(param, state, gen_x(param_x, state[2]))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local chain = function(...)&lt;br /&gt;
    local n = numargs(...)&lt;br /&gt;
    if n == 0 then&lt;br /&gt;
        return wrap(nil_gen, nil, nil)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local param = { [3 * n] = 0 }&lt;br /&gt;
    local i, gen_x, param_x, state_x&lt;br /&gt;
    for i=1,n,1 do&lt;br /&gt;
        local elem = select(i, ...)&lt;br /&gt;
        gen_x, param_x, state_x = iter(elem)&lt;br /&gt;
        param[3 * i - 2] = gen_x&lt;br /&gt;
        param[3 * i - 1] = param_x&lt;br /&gt;
        param[3 * i] = state_x&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return wrap(chain_gen_r1, param, {1, param[3]})&lt;br /&gt;
end&lt;br /&gt;
methods.chain = chain&lt;br /&gt;
exports.chain = chain&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Operators&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local operator = {&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    -- Comparison operators&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    lt  = function(a, b) return a &amp;lt; b end,&lt;br /&gt;
    le  = function(a, b) return a &amp;lt;= b end,&lt;br /&gt;
    eq  = function(a, b) return a == b end,&lt;br /&gt;
    ne  = function(a, b) return a ~= b end,&lt;br /&gt;
    ge  = function(a, b) return a &amp;gt;= b end,&lt;br /&gt;
    gt  = function(a, b) return a &amp;gt; b end,&lt;br /&gt;
&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    -- Arithmetic operators&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    add = function(a, b) return a + b end,&lt;br /&gt;
    div = function(a, b) return a / b end,&lt;br /&gt;
    floordiv = function(a, b) return math.floor(a/b) end,&lt;br /&gt;
    intdiv = function(a, b)&lt;br /&gt;
        local q = a / b&lt;br /&gt;
        if a &amp;gt;= 0 then return math.floor(q) else return math.ceil(q) end&lt;br /&gt;
    end,&lt;br /&gt;
    mod = function(a, b) return a % b end,&lt;br /&gt;
    mul = function(a, b) return a * b end,&lt;br /&gt;
    neq = function(a) return -a end,&lt;br /&gt;
    unm = function(a) return -a end, -- an alias&lt;br /&gt;
    pow = function(a, b) return a ^ b end,&lt;br /&gt;
    sub = function(a, b) return a - b end,&lt;br /&gt;
    truediv = function(a, b) return a / b end,&lt;br /&gt;
&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    -- String operators&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    concat = function(a, b) return a..b end,&lt;br /&gt;
    len = function(a) return #a end,&lt;br /&gt;
    length = function(a) return #a end, -- an alias&lt;br /&gt;
&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    -- Logical operators&lt;br /&gt;
    ----------------------------------------------------------------------------&lt;br /&gt;
    land = function(a, b) return a and b end,&lt;br /&gt;
    lor = function(a, b) return a or b end,&lt;br /&gt;
    lnot = function(a) return not a end,&lt;br /&gt;
    truth = function(a) return not not a end,&lt;br /&gt;
}&lt;br /&gt;
exports.operator = operator&lt;br /&gt;
methods.operator = operator&lt;br /&gt;
exports.op = operator&lt;br /&gt;
methods.op = operator&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- module definitions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- a special syntax sugar to export all functions to the global table&lt;br /&gt;
setmetatable(exports, {&lt;br /&gt;
    __call = function(t, override)&lt;br /&gt;
        for k, v in pairs(t) do&lt;br /&gt;
            if rawget(_G, k) ~= nil then&lt;br /&gt;
                local msg = 'function ' .. k .. ' already exists in global scope.'&lt;br /&gt;
                if override then&lt;br /&gt;
                    rawset(_G, k, v)&lt;br /&gt;
                    print('WARNING: ' .. msg .. ' Overwritten.')&lt;br /&gt;
                else&lt;br /&gt;
                    print('NOTICE: ' .. msg .. ' Skipped.')&lt;br /&gt;
                end&lt;br /&gt;
            else&lt;br /&gt;
                rawset(_G, k, v)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end,&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
return exports&lt;/div&gt;</summary>
		<author><name>- Hermes -</name></author>	</entry>

	</feed>