Nested function return question

I am stuck. I would love to get some help with how a nested function returns value from inner to outer and then to the actual caller. Pseudo code below to help explain my question. Lets say we want to write a wrapper for network download such as below

How can I take the return from inner function (ie listener) and have the outer function return that value to its caller (ie getFileResult). Thanks for your kind assistance.

local function getMyFile(fileName) local myFunctionResult = false local function networkListener( event ) if ( event.isError ) then myFunctionResult = false -- not needed actually but here for visibility elseif ( event.phase == "ended" ) then myFunctionResult = true -- file downloaded nicely end return myFunctionResult end network.download( fileName, networkListener ) end local getFileResult = getMyFile("thisFile")

you don’t have a nesting/scoping problem, it’s a structural issue, due to the network call being asynchronous. the inner listener might not get called until much later, long after the outer function has already returned, so there’s nothing (at that moment) from the inner fn for the outer fn to return.

you’re returning a boolean, so presumably you’d later use it like “if (getFileResult) then doGoodThing() else doBadThing() end”, right? it needs to be structured to handle delayed execution, fe:

local function networkListener(event) if (event.isError) then doBadThing() -- this might not happen for several seconds elseif (event.phase=="ended") then doGoodThing() -- this might not happen for several seconds end end network.download(fileName,networkListener)

fwiw, hth

Good point. Ok lets tackle a non asynch process then. I choose a bad example in the prior case. I can write a non-asych function inside a function to handle repetition etc. The inner function can be called with a function return feeding the outer function. I guess this is how its supposed to look right? Thanks for your help.

local function getMyRandomNum(maxNum) local function makeRandomNum( localisedMaxNum ) pseudo code getting random num return myFunctionResult end local myRandomNum1, myRandomNum2, myRandomNum3 = nil myRandomNum1 = makeRandomNum(maxNum) myRandomNum2 = makeRandomNum(maxNum) myRandomNum3 = makeRandomNum(maxNum) return myRandomNum1, myRandomNum2, myRandomNum3 end local myRandomNum1, myRandomNum2, myRandomNum3 = getMyRandomNum(9) -- get back a 3 random numbers up to what is passed in 

yep, that’s fine, (and common in lua), shouldn’t pose any problem … other than readability, if you get carried away with nesting, fe what the heck does this do? :smiley:

local function a(x) local function b(y) local function c(z) return z+z end return c(y)\*c(y) end return b(x)+b(x) end

Yup. I agree. I am sure there are some great cases for using the nested approach but my two examples were both not the best. Second one probably is better off being written in a direct approach. Anyways. Thanks much.

“convenience” is a good enough reason. but also useful for encapsulation, data-hiding, etc, fe:

local function publicAPI(x) local function privateAPI(x,plusSomeSecretSauce,andAnotherMystery) return (x + plusSomeSecretSauce) \* andAnotherMystery end -- public user doesn't/shouldn't know these 'magic values' if ((x%2)==0) then return privateAPI(x,2468,4680) else return privateAPI(x,1357,3579) end end

you don’t have a nesting/scoping problem, it’s a structural issue, due to the network call being asynchronous. the inner listener might not get called until much later, long after the outer function has already returned, so there’s nothing (at that moment) from the inner fn for the outer fn to return.

you’re returning a boolean, so presumably you’d later use it like “if (getFileResult) then doGoodThing() else doBadThing() end”, right? it needs to be structured to handle delayed execution, fe:

local function networkListener(event) if (event.isError) then doBadThing() -- this might not happen for several seconds elseif (event.phase=="ended") then doGoodThing() -- this might not happen for several seconds end end network.download(fileName,networkListener)

fwiw, hth

Good point. Ok lets tackle a non asynch process then. I choose a bad example in the prior case. I can write a non-asych function inside a function to handle repetition etc. The inner function can be called with a function return feeding the outer function. I guess this is how its supposed to look right? Thanks for your help.

local function getMyRandomNum(maxNum) local function makeRandomNum( localisedMaxNum ) pseudo code getting random num return myFunctionResult end local myRandomNum1, myRandomNum2, myRandomNum3 = nil myRandomNum1 = makeRandomNum(maxNum) myRandomNum2 = makeRandomNum(maxNum) myRandomNum3 = makeRandomNum(maxNum) return myRandomNum1, myRandomNum2, myRandomNum3 end local myRandomNum1, myRandomNum2, myRandomNum3 = getMyRandomNum(9) -- get back a 3 random numbers up to what is passed in 

yep, that’s fine, (and common in lua), shouldn’t pose any problem … other than readability, if you get carried away with nesting, fe what the heck does this do? :smiley:

local function a(x) local function b(y) local function c(z) return z+z end return c(y)\*c(y) end return b(x)+b(x) end

Yup. I agree. I am sure there are some great cases for using the nested approach but my two examples were both not the best. Second one probably is better off being written in a direct approach. Anyways. Thanks much.

“convenience” is a good enough reason. but also useful for encapsulation, data-hiding, etc, fe:

local function publicAPI(x) local function privateAPI(x,plusSomeSecretSauce,andAnotherMystery) return (x + plusSomeSecretSauce) \* andAnotherMystery end -- public user doesn't/shouldn't know these 'magic values' if ((x%2)==0) then return privateAPI(x,2468,4680) else return privateAPI(x,1357,3579) end end