Page 1 of 1

Does Love2D execute functions even before they are called?

Posted: Mon Jul 17, 2017 6:48 am
by mustafatouny
Hello, while I was coding I faced a problem -which is expected-, then I figured out the solution but it raised a contradict conception in my head.

Code that caused error, "index global grid a nil value"

Code: Select all

function love.load()

	gridYCount = 4
	gridXCount = 4

	function move(direction)
		for y = 1, gridYCount do
			for x = 1, gridXCount do
				if grid[y][x] == gridXCount * gridYCount then
					emptyX = x
					emptyY = y
				end
			end
		end
		-- establishing grid
		grid = {}
  		for y = 1, gridYCount do
    			grid[y] = {}
   		 	for x = 1, gridXCount do
     		 		grid[y][x] = x + ((y - 1) * gridXCount)
    			end
		end
    
end
all what I did is to change the position of code under comment "establishing grid" to be a predecessor of move function, here is it

Code: Select all

function love.load()

	gridYCount = 4
	gridXCount = 4

	-- establishing grid
	grid = {}
  	for y = 1, gridYCount do
    		grid[y] = {}
   	 	for x = 1, gridXCount do
     	 		grid[y][x] = x + ((y - 1) * gridXCount)
    		end
	end

	function move(direction)
		for y = 1, gridYCount do
			for x = 1, gridXCount do
				if grid[y][x] == gridXCount * gridYCount then
					emptyX = x
					emptyY = y
				end
			end
		end
end


The conceptual model (i.e knowledge) I gained during studying the fundamentals of programming is that functions are not executed unless they are called, The error arised immediately after running Love2D file. Could someone explain this to me?

Re: Does Love2D execute functions even before they are called?

Posted: Mon Jul 17, 2017 8:33 am
by raidho36
Try reading complete error message (i.e. with backtrace), it will give you a good idea of what's going on. I'd wager you simply call it yourself elsewhere.

There are many problems with this code, you can start with not using global variables and function-local functions.

Re: Does Love2D execute functions even before they are called?

Posted: Mon Jul 17, 2017 8:48 am
by bartbes
In your first code snippet grid is initialized inside of move, after trying to use it, so that could definitely be your problem.

Re: Does Love2D execute functions even before they are called?

Posted: Wed Jul 19, 2017 6:07 pm
by mustafatouny
Thank you @bartbes, How surprised I am that silly mistakes like these could trigger faraway false reasoning ideas.

Also, Thank you @raidho36, Every advise is counted.

Re: Does Love2D execute functions even before they are called?

Posted: Sat Jul 22, 2017 5:40 pm
by IsawU
To answer your question... What Lua does is that it pre-compiles the source in, what is called, a bytecode, which is later executed by Lua interpreter.

So what CAN happen is that the compiler finds an error and stops.

This happened to you, because Lua compiler is single-pass, which would mean that all variables must exist before you try to access them (otherwise the compiler doesn't know where to point).

Typical example of this error would be when calling functions (called a nil value) or accessing tables (index a nil value). A reason this will never be seen when accessing just a normal variable is that you will simply get nil (no reason to panic just yet).

Re: Does Love2D execute functions even before they are called?

Posted: Sun Jul 23, 2017 9:32 am
by bartbes
IsawU wrote: Sat Jul 22, 2017 5:40 pm This happened to you, because Lua compiler is single-pass, which would mean that all variables must exist before you try to access them (otherwise the compiler doesn't know where to point).
Not true, that wouldn't work with the way lua deals with globals (or tables) at all. The "compiler" does little more than a syntax check.
IsawU wrote: Sat Jul 22, 2017 5:40 pm Typical example of this error would be when calling functions (called a nil value) or accessing tables (index a nil value). A reason this will never be seen when accessing just a normal variable is that you will simply get nil (no reason to panic just yet).
(emphasis mine)

And calling functions doesn't happen until your code runs, so this doesn't happen when parsing. Same goes for accessing tables. And of course it couldn't do this earlier, because functions and tables are just values, they could be created later, or what was once a number could now be a function.

Re: Does Love2D execute functions even before they are called?

Posted: Sun Jul 23, 2017 10:37 am
by IsawU
bartbes wrote: Sun Jul 23, 2017 9:32 am
IsawU wrote: Sat Jul 22, 2017 5:40 pm This happened to you, because Lua compiler is single-pass, which would mean that all variables must exist before you try to access them (otherwise the compiler doesn't know where to point).
Not true, that wouldn't work with the way lua deals with globals (or tables) at all. The "compiler" does little more than a syntax check.
Sorry for the misinformation I messed this one up. Of course what the compiler does at this moment is not much, and only if there is something non-understandable (syntax error, invalid escape sequence, missing end, and so), it errors immediately.
bartbes wrote: Sun Jul 23, 2017 9:32 am
IsawU wrote: Sat Jul 22, 2017 5:40 pm Typical example of this error would be when calling functions (called a nil value) or accessing tables (index a nil value). A reason this will never be seen when accessing just a normal variable is that you will simply get nil (no reason to panic just yet).
(emphasis mine)

And calling functions doesn't happen until your code runs, so this doesn't happen when parsing. Same goes for accessing tables. And of course it couldn't do this earlier, because functions and tables are just values, they could be created later, or what was once a number could now be a function.
Yes, this statement was a bit poorly placed. Theese errors are of course present when trying to call (index) while the program is running. I was thinking a little bit ahead, actually describing the first program.

Let's fix the first program (add the missing end)

Code: Select all

function love.load()

	gridYCount = 4
	gridXCount = 4

	function move(direction)
		for y = 1, gridYCount do
			for x = 1, gridXCount do
				if grid[y][x] == gridXCount * gridYCount then
					emptyX = x
					emptyY = y
				end
			end
		end
		-- establishing grid
		grid = {}
  		for y = 1, gridYCount do
    			grid[y] = {}
   		 	for x = 1, gridXCount do
     		 		grid[y][x] = x + ((y - 1) * gridXCount)
    			end
		end
    
	end	--MISSING END
    
    
end
Now if we were to call move() we would get the error with attempted to index global grid a nil value[b/].

Returning to the original example, if you fix the missing end, it runs. The error appears once you call move().