This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Xhisor's profile picture

Java error

Started by Xhisor, 06 June 2012 - 09:13 AM
Xhisor #1
Posted 06 June 2012 - 11:13 AM
Hello, i have made a clocktower using a computer and 36 monitors (if that makes any difference) which shows the current ingame time. I modified the 24h exampel on the wiki.
function tid() --tid means time in swedish
local time = os.time()
time = textutils.formatTime(time, true)
print(time)
sleep(1)
term.clear()
term.setCursorPos(7, 6)
tid()
end
tid()
It's here the problem comes, every now and then the clock stops working and i get a java error "java.lang.arrayindexoutofboundsexception".

How am i supposed to fix this? I just started with this mod and the only things i have made so far are doors!

I am very thankful for help!
Xhisor
Xtansia #2
Posted 06 June 2012 - 12:45 PM
Do not recursively call your function from your function, As that is what is giving that error is because of stack overflow,
What you should do is like this:



function tid() --tid means time in swedish
local time = os.time()
time = textutils.formatTime(time, true)
print(time)
sleep(1)
term.clear()
term.setCursorPos(7, 6)
-- See how I removed the call to tid()
end

while true do  --This will continually call your function
tid()
end

Xhisor #3
Posted 06 June 2012 - 01:09 PM
Ahh i see, thank you!
Lolgast #4
Posted 06 June 2012 - 02:06 PM
Or you can use a tail call. That is, returning the function in stead of calling it.
function tid()
...
return tid()
end
Lyqyd #5
Posted 07 June 2012 - 07:06 AM
Or you can use a tail call. That is, returning the function in stead of calling it.
function tid()
...
return tid()
end

No, this will run into the exact same problem for the exact same reason. The best option here would be to replace the function itself with an infinite loop.
BigSHinyToys #6
Posted 07 June 2012 - 07:14 AM
Or you can use a tail call. That is, returning the function in stead of calling it.
function tid()
...
return tid()
end

No, this will run into the exact same problem for the exact same reason. The best option here would be to replace the function itself with an infinite loop.

you are wrong a tail call maintains the same stack level as the function that called it
A call of the form return functioncall is called a tail call. Lua implements proper tail calls (or proper tail recursion): in a tail call, the called function reuses the stack entry of the calling function. Therefore, there is no limit on the number of nested tail calls that a program can execute. However, a tail call erases any debug information about the calling function. Note that a tail call only happens with a particular syntax, where the return has one single function call as argument; this syntax makes the calling function return exactly the returns of the called function. So, none of the following examples are tail calls:
link http://www.lua.org/manual/5.1/manual.html
so a tail call would not cause stack over flow but a loop is still a better option for simplicity sake.
Lyqyd #7
Posted 07 June 2012 - 03:08 PM
Or you can use a tail call. That is, returning the function in stead of calling it.
function tid()
...
return tid()
end

No, this will run into the exact same problem for the exact same reason. The best option here would be to replace the function itself with an infinite loop.

you are wrong a tail call maintains the same stack level as the function that called it
A call of the form return functioncall is called a tail call. Lua implements proper tail calls (or proper tail recursion): in a tail call, the called function reuses the stack entry of the calling function. Therefore, there is no limit on the number of nested tail calls that a program can execute. However, a tail call erases any debug information about the calling function. Note that a tail call only happens with a particular syntax, where the return has one single function call as argument; this syntax makes the calling function return exactly the returns of the called function. So, none of the following examples are tail calls:
link http://www.lua.org/manual/5.1/manual.html
so a tail call would not cause stack over flow but a loop is still a better option for simplicity sake.

Interesting tidbit there. However, a tail call is still the wrong thing to use here. Simplicity aside, tail calls are good for things like factorials:


function factorial(n)
    if n > 1 then
        return n * factorial(n-1)
    elseif n == 1 then
        return n
    else
        return nil
    end
end

…where the called function eventually just returns rather than unconditionally calling itself. This example unfortunately wouldn't be able to take advantage of Lua's flat tail-call recursion as written. Anyway, my point is simply that it's always best to recommend the right tool for the job.
MysticT #8
Posted 07 June 2012 - 09:23 PM
Interesting tidbit there. However, a tail call is still the wrong thing to use here. Simplicity aside, tail calls are good for things like factorials:


function factorial(n)
	if n > 1 then
		return n * factorial(n-1)
	elseif n == 1 then
		return n
	else
		return nil
	end
end

…where the called function eventually just returns rather than unconditionally calling itself. This example unfortunately wouldn't be able to take advantage of Lua's flat tail-call recursion as written. Anyway, my point is simply that it's always best to recommend the right tool for the job.
Actually, that's not a tail call. To be a tail call it has to be of the form "return func()". If you add another return value (doing "return func(), somethingElse") or use the returned value of the function (like your example), it's not a tail call.
But yes, a tail call is not the right thing to do in this case, it's better to use a loop.
BigSHinyToys #9
Posted 08 June 2012 - 03:46 AM
…where the called function eventually just returns rather than unconditionally calling itself. This example unfortunately wouldn't be able to take advantage of Lua's flat tail-call recursion as written. Anyway, my point is simply that it's always best to recommend the right tool for the job.

I was just pointing it out for academic reasons I to recommended a loop for this task.