Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

I've been studying various bits of code I found around the place and on this forum and I was slightly confused about the assignments going on in one block I came across:

Code: Select all

player.x, player.y, cols, len = world:move(player, player.x + player.dx, player.y + player.dy)

player.xAcc, player.yAcc = 0, player.yAcc * 0.45
I'm aware that you can make assignment like this in lua:

Code: Select all

SW, SH = 10, 12
But the above assignments seem to be slightly different. I'm not sure what's getting assigned to what in these lines.

grump
Party member
Posts: 612
Joined: Sat Jul 22, 2017 7:43 pm

But the above assignments seem to be slightly different. I'm not sure what's getting assigned to what in these lines.
The right side of an assignment is always assigned to the left side. There can only be variables on the left, while the right side can be arbitrary expressions. Lua evaluates all expressions on the right side (going from left to right) and assigns the results to the variables on the left (also from left to right).

Code: Select all

left1, left2, left3 = expression1, expression2, expression3
hasen wrote:
Tue Jan 30, 2018 8:37 am

Code: Select all

player.x, player.y, cols, len = world:move(player, player.x + player.dx, player.y + player.dy)
Functions in Lua can have more than one return value. The function world:move() probably returns 4 values. This line assigns these values to the variables player.x, player.y, cols and len.

Code: Select all

player.xAcc, player.yAcc = 0, player.yAcc * 0.45
Same here, just without the function call. player.xAcc is set to 0, player.yAcc is set to player.yAcc * 0.45. It's equivalent to

Code: Select all

player.xAcc = 0
player.yAcc = player.yAcc * 0.45

hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

grump wrote:
Tue Jan 30, 2018 9:01 am
But the above assignments seem to be slightly different. I'm not sure what's getting assigned to what in these lines.
The right side of an assignment is always assigned to the left side. There can only be variables on the left, while the right side can be arbitrary expressions. Lua evaluates all expressions on the right side (going from left to right) and assigns the results to the variables on the left (also from left to right).

Code: Select all

left1, left2, left3 = expression1, expression2, expression3
hasen wrote:
Tue Jan 30, 2018 8:37 am

Code: Select all

player.x, player.y, cols, len = world:move(player, player.x + player.dx, player.y + player.dy)
Functions in Lua can have more than one return value. The function world:move() probably returns 4 values. This line assigns these values to the variables player.x, player.y, cols and len.

Code: Select all

player.xAcc, player.yAcc = 0, player.yAcc * 0.45
Same here, just without the function call. player.xAcc is set to 0, player.yAcc is set to player.yAcc * 0.45. It's equivalent to

Code: Select all

player.xAcc = 0
player.yAcc = player.yAcc * 0.45
Ok I see, so it was like I thought, it was just that the world:move was returning four values. And for the second one it seems obvious now, don't know why I didn't get that before. Thanks very much for your help.

zorg
Party member
Posts: 2914
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

hasen wrote:
Tue Jan 30, 2018 9:16 am
grump wrote:
Tue Jan 30, 2018 9:01 am
...
Ok I see, so it was like I thought, it was just that the world:move was returning four values. And for the second one it seems obvious now, don't know why I didn't get that before. Thanks very much for your help.
Keep in mind two more things;
lua functions can return more than one value (without using tables, i mean)
the comma (as well as extra parentheses around function calls) limit the number of returned values to 1.
So in the example code:

Code: Select all

player.x, player.y, cols, len = world:move(player, player.x + player.dx, player.y + player.dy) -- this probably returns 4 values, although there's no rule that it needs to; if it returns more than how many vars are on the left side of the equals sign, they get discarded, if it returns less, then the rightmost vars will be set to nil.

a,b = fn(), 'whatever', -- fn will return one value because of the comma
d,d = (fn()) -- fn will return one value because of the parentheses around it

Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Ok I see, thanks for elaborating on that, Zorg. That would make sense since in Lua anything that isn't something get's labeled as nil. Which is pretty convenient really. Good tips regarding the functions too.

grump
Party member
Posts: 612
Joined: Sat Jul 22, 2017 7:43 pm

Thanks zorg. Sematics of multiple return values is one of the more difficult, least intuitive parts about Lua, and it keeps messing with me to this day.

pgimeno
Party member
Posts: 2172
Joined: Sun Oct 18, 2015 2:58 pm

By the way, that applies to parameters in function calls too. Only the last element can see multiple values, e.g.

Code: Select all

function f()
return 1, 2
end

function g(a,b,c,d)
print(a,b,c,d)
end

g(f(),f(),f()) -- prints 1,1,1,2
w,x,y,z = f(), f(), f() -- w=1 x=1 y=1 z=2
w,x,y,z = f(), f(), (f()) -- w=1 x=1 y=1 z=nil


zorg
Party member
Posts: 2914
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

I think it's correct to say, that in anything that features commas as variable delimiters; tables, function (even anonymous and "functionalized table via metatable") parameters, and parentheses around a multi-value returning construct will have its return values trimmed to one.

Code: Select all

function myprint(t)
for i,v in ipairs(t) do io.write(tostring(v)) end
io.write('\n')
end

myprint({1,2,(function() return 3,4 end)()}) -- table + anon function at the end, not wrapped in parentheses --> 1,2,3,4
myprint({1,2,(function() return 3,4 end)(),5}) -- table + anon function not at the end, not wrapped in parentheses --> 1,2,3,5
myprint({1,2,((function() return 3,4 end)())}) -- table + anon function at the end, wrapped in parentheses --> 1,2,3
myprint({1,2,((function() return 3,4 end)()),5}) -- table + anon function not at the end, wrapped in parentheses --> 1,2,3,5

-- and just for some extra shenanigans, parameters to the anonymous function while it's at the last table slot

myprint({1,2,(function(a,b) return a,b end)(3,4)}) --> 1,2,3,4
myprint({1,2,(function(a,b) return a,b end)(3)}) --> 1,2,3
myprint({1,2,(function(a,b) return a,b end)(nil,4)}) --> 1,2,nil,4
myprint({1,2,(function(a) return a end)(3,4)}) --> 1,2,3
myprint({1,2,(function(a) return a end)(nil,4)}) --> 1,2

Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.

choopos
Prole
Posts: 2
Joined: Tue Aug 28, 2018 12:38 pm

Here's my solution to the problem https://www.assignmentexpert.com/progra ... ce-project. They haven't break my trust yet.

Sasha264
Citizen
Posts: 71
Joined: Mon Sep 08, 2014 7:57 am

Is here an explanation why the comma limits the number of returned values to 1?

I can imagine negative side of that solution. For example this call:

Code: Select all

love.graphics.draw(drawable, x, y, r, sx, sy, ox, oy, kx, ky)
can not be made like this:

Code: Select all

love.graphics.draw(drawable, obj:getPosition(), r, obj:getScale(), ox, oy, kx, ky)
instead it requires a bunch of temp variables.

But what is positive side?

### Who is online

Users browsing this forum: Bing [Bot] and 58 guests