Confused about assignments

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
hasen
Party member
Posts: 157
Joined: Sat Jan 20, 2018 2:01 pm

Confused about assignments

Post by hasen »

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: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Confused about assignments

Post by grump »

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

Re: Confused about assignments

Post by hasen »

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.
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Confused about assignments

Post by zorg »

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 :3True 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

Re: Confused about assignments

Post by hasen »

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: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Confused about assignments

Post by grump »

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.
User avatar
pgimeno
Party member
Posts: 3548
Joined: Sun Oct 18, 2015 2:58 pm

Re: Confused about assignments

Post by pgimeno »

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
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Confused about assignments

Post by zorg »

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 :3True 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

Re: Confused about assignments

Post by choopos »

Here's my solution to the problem https://www.assignmentexpert.com/progra ... ce-project. They haven't break my trust yet.
User avatar
Sasha264
Party member
Posts: 131
Joined: Mon Sep 08, 2014 7:57 am

Re: Confused about assignments

Post by Sasha264 »

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?
Post Reply

Who is online

Users browsing this forum: Yolwoocle and 21 guests