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

• Subject: Re: Mutual recursion
• From: Gabriel Bertilson <arboreous.philologist@...>
• Date: Thu, 23 Apr 2020 23:15:09 -0500

```Here's a setter function method. Doesn't require the debug library or
metatables. (I'm guessing this what Egor Skriptunoff was referring
to.) It's a one-file example, but is applicable to separate modules:
just convert the do blocks to modules, and have the modules return the
two functions defined above each of the do blocks.

I don't recall ever having to use mutual recursion in Lua so I just
took the first example from the Wikipedia article.

local set_is_even, is_odd
do
local is_even

function set_is_even(func)
is_even = func
end

function is_odd(n)
if n == 0 then
return false
else
return is_even(n - 1)
end
end
end

local set_is_odd, is_even
do
local is_odd

function set_is_odd(func)
is_odd = func
end

function is_even(n)
if n == 0 then
return true
else
return is_odd(n - 1)
end
end
end

set_is_even(is_even)
set_is_odd(is_odd)

-- demo
for i = 1, 10 do
print("is_even(" .. i .. ")", is_even(i), "is_odd(" .. i .. ")", is_odd(i))
end

— Gabriel

On Thu, Apr 23, 2020 at 5:21 PM Andrew Gierth
<andrew@tao11.riddles.org.uk> wrote:
>
> >>>>> "Martin" == Martin  <dyngeccetor8@disroot.org> writes:
>
>  Martin> I believe you can solve a lot of problems with hammer, duct
>  Martin> tape and Lua "debug" module.
>
> Might be preferable to avoid the debug module in general; metatables
> can do the job too (cqueues does something like this):
>
> --[[ main.lua ]]
> local m = require 'mod1'
> print(m.foo(3))
>
> --[[ mod1.lua ]]
> local M = {}
> local m2 = require 'mod2'
> function M.foo(n)
>         print("in mod1.foo",n)
>         if n and n > 0 then
>                 m2.bar(n - 1)
>         end
>         return "foo";
> end
> return M
>
> --[[ mod2.lua ]]
> -- Lazy loading to avoid mutual recursion issue
> local function loader(M,k)
>         setmetatable(M,nil)
>         local m1 = require 'mod1'
>         function M.bar(n)
>                 print("in mod2.bar",n)
>                 return m1.foo(n)
>         end
>         return rawget(M,k)
> end
> return setmetatable({}, {__index = loader})
>
> --
> Andrew.
> _______________________________________________
> lua-l mailing list -- lua-l@lists.lua.org
> To unsubscribe send an email to lua-l-leave@lists.lua.org
_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org
```