lua-users home
lua-l archive

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


On 4/23/20 1:40 PM, Gavin Wraith wrote:
I have an idle question, which I thought I would put to
the list in case anybody had come up with a slick answer.
At present the only way to implement mutual recursion in
Lua is to declare two local variables first within a chunk
and then to define two mutually dependent functions later
in that chunk with the same names. There is no way to have
mutual recursion between functions defined in separate files,
for example. But is there a way to mimic a linker, using
loadfile, and then doing some patching?
I hope this proposition does not seem too indelicate to
those of refined senses.
--
Gavin Wraith (gavin@wra1th.plus.com)
Home page: http://www.wra1th.plus.com/

I believe you can solve a lot of problems with hammer, duct tape
and Lua "debug" module.

Here is my artificial example of mutually dependent functions
placed in separate chunks. Code prints binary representation
of given integer in reverse order. print_digit() prints last digit
and calls do_shift(). Which shifts number by one position and
calls print_digit().

To avoid cycle at require() time we only allocate "do_shift.print_digit"
slot and set it to real value after require() is finished.

-- Martin


--[[ main.lua ]]--
local print_binary = require('print_digit')

print_binary(12)


--[[ print_digit.lua ]]--
local do_shift = require('do_shift')

local result =
  function(n)
    if (n <= 0) then
      return 0
    end
    print(n % 2)
    do_shift(n)
  end

local set_upval =
  function(chunk, name, value)
    local offs = 0
    repeat
      offs = offs + 1
      local k, v = debug.getupvalue(chunk, offs)
      assert(k)
    until (k == name)
    debug.setupvalue(do_shift, offs, value)
  end

-- Patch do_shift() by setting "print_digit" to us.
set_upval(do_shift, 'print_digit', result)

return result


--[[ do_shift.lua ]]--
--[[
  Can't "require('print_digit')" due cyclic reference.
  We'll patch "print_digit" value later from caller.
]]

local print_digit

return
  function(n)
    n = n // 2
    print_digit(n)
  end
_______________________________________________
lua-l mailing list -- lua-l@lists.lua.org
To unsubscribe send an email to lua-l-leave@lists.lua.org