# I Am Puzzled By A Problem With Return

I’m a beginner so maybe I am missing something obvious. Anyone know what the problem is here? (see the capitalized comments) Is it a bug?

``````
function next_line_from(sequence, line)
local pattern = renoise.song().sequencer.pattern_sequence[sequence]
if line == renoise.song().patterns[pattern].number_of_lines then
if sequence + 1 > table.getn(renoise.song().sequencer.pattern_sequence) then
return "END"
else
sequence = sequence + 1
line = 1
end
else
line = line + 1
end
return sequence, line
end

local steps = 1

function next_note_from(sequence, line)
local n_sequence, n_line = next_line_from(sequence, line)
if n_sequence == "END" then return "END" else
if renoise.song().patterns[renoise.song().sequencer.pattern_sequence[n_sequence]].tracks[renoise.song().selected_track_index]:line(n_line).note_columns[renoise.song().selected_note_column_index].is_empty == false then
return n_line -- THIS DOES NOT WORK
-- print(n_line) -- THIS WILL WORK
else
steps = steps + 1
next_note_from(next_line_from(sequence, line))
end
end
end

function main()
print(next_note_from(renoise.song().selected_sequence_index, renoise.song().selected_line_index)) -- THIS DOES NOT WORK
-- next_note_from(renoise.song().selected_sequence_index, renoise.song().selected_line_index) -- THIS WILL WORK TOGETHER WITH PRINT ABOVE
end

main()

``````

It should work the same way this does:

``````
function test1()
local a = 1
return a
end

function test2()
print(test1())
end

test2()

``````

Any help is much appreciated.

It seems that “return n_line” returns nil, but it is printable before that. Is something strange happening regarding datatypes maybe?

Variables don’t have a fixed datatype in LUA so that would seem a little strange.

Have to admit the Return command is one so far I’ve felt a little ambiguous on though, so have always used local variables (even if local for the entire script) instead on the whole. What are you trying to return the value into? As I can’t see it actually going anywhere… (Although I probably misunderstand.)

But something like:

function power(x,y)
z = x^y
return z
end

As far as I understand it will not generate a variable called z.

If you then went:

fish = power(2,3)

print (fish)

-> 8 – would be outputted.

Or at least that is now I’ve been thinking it works.

Yes. It should work like that but something is jammin in my example.

You misunderstand recursion, I think.

When you call next_note_from() recursively, you are returning to the previous next_note_from() call, not to main().

Change line ~26 from:

``````
next_note_from(next_line_from(sequence, line))

``````

To:

``````
return next_note_from(next_line_from(sequence, line))

``````

You should add a return value to your else statement, otherwise all function calls that proceed to the else will return nil.

I see that you have a recursive function in the else scope: next_note_from(next_line_from(sequence, line))

This function will execute but it does not override the current functions scope so you should return the executed functions returned value.

More simply return your recursive function:

return next_note_from(next_line_from(sequence, line))

I have not tested this, not enough time atm, but I’m pretty sure it’s your problem. Let us know how it goes.

Thanks a lot guys. Just adding a return helped me. I probably missed something with the scope, and I’m too stupid to fully understand it atm. I was puzzled because print worked but not return.

Here you have a working example, in case anyone will benefit from it

``````
function next_line_from(sequence, line)
local pattern = renoise.song().sequencer.pattern_sequence[sequence]
if line == renoise.song().patterns[pattern].number_of_lines then
if sequence + 1 > table.getn(renoise.song().sequencer.pattern_sequence) then
return "END"
else
sequence = sequence + 1
line = 1
end
else
line = line + 1
end
return sequence, line
end

local steps = 1

function next_note_from(sequence, line)
local n_sequence, n_line = next_line_from(sequence, line)
if n_sequence == "END" then return "END" else
if renoise.song().patterns[renoise.song().sequencer.pattern_sequence[n_sequence]].tracks[renoise.song().selected_track_index]:line(n_line).note_columns[renoise.song().selected_note_column_index].is_empty == false then
return { n_sequence, n_line, steps }
else
steps = steps + 1
return next_note_from(next_line_from(sequence, line))
end
end
end

function main()
local next_note = next_note_from(renoise.song().selected_sequence_index, renoise.song().selected_line_index)
print("The next note is at sequence " .. next_note[1] .. ", line " .. next_note[2] .. ", " .. next_note[3] .. " steps ahead")
end

main()

``````

Great that it works! Thumbs up to Conner for beating me to the punch.

I find scopes and recursion quite hard to explain. But it’s important to understand.

This is because the function was executed within another function. Each time you execute a function it runs with it’s own scope instance. So your print function was being fired, and actually your return was also being returned but it was not handled in the previous scope.

Consider the following code as a more scope related way to handle recursion:

``````
local return_value = next_note_from(next_line_from(sequence, line))
return return_value

``````

This way you could modify the return_value again within the previous function scope before returning to main().