Let's talk about order of assignment

classic Classic list List threaded Threaded
30 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Let's talk about order of assignment

Soni "They/Them" L.
For example:

Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then io.write(v) end end}) out,out,out = "what","the","fuck"
fuckthewhat>

Reply | Threaded
Open this post in threaded view
|

RE: Let's talk about order of assignment

Alexandre Rion
Interesting lecture:

http://lua-users.org/wiki/AssignmentTutorial

Alexandre

--- Original Message ---

From: "Thiago L." <[hidden email]>
Sent: 14 September 2014 19:33
To: "Lua mailing list" <[hidden email]>
Subject: Let's talk about order of assignment

For example:

Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then io.write(v) end end}) out,out,out = "what","the","fuck"
fuckthewhat>


Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Eike Decker
In reply to this post by Soni "They/Them" L.

It's undefined. I once complained on this list about this but the opinion was that it's better to leave it undefined because it enables the VM to do optimizations. For  deterministic calculations, this means that multiple assignments are to be avoided. Though it would need a bit of crafting to run into it. Like x,y = rand(), rand()

I think I voiced the opinion that it should be documented then in the manual, but I'm not sure any more.

Eike

Am 14.09.2014 19:51 schrieb "Thiago L." <[hidden email]>:
For example:

Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then io.write(v) end end}) out,out,out = "what","the","fuck"
fuckthewhat>

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Peter Melnichenko-2
In reply to this post by Soni "They/Them" L.

14.09.2014 21:33 "Thiago L." <[hidden email]>:
>
> For example:
>
> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> > setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then io.write(v) end end}) out,out,out = "what","the","fuck"
> fuckthewhat>
>

More magic:

> local a, a, a = 1, 2, 3; print(a)
3
> b, b, b = 1, 2, 3; print(b)
1

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Soni "They/Them" L.
On 9/14/14, Peter Melnichenko <[hidden email]> wrote:

> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>
>> For example:
>>
>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>> > setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
> io.write(v) end end}) out,out,out = "what","the","fuck"
>> fuckthewhat>
>>
>
> More magic:
>
>> local a, a, a = 1, 2, 3; print(a)
> 3
>> b, b, b = 1, 2, 3; print(b)
> 1
>

Yeah, but at least it's consistent. that is, local x = 1; local x = 2;
local x = 3; print(x) -> prints 3

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Soni "They/Them" L.
On 9/14/14, Thiago L. <[hidden email]> wrote:

> On 9/14/14, Peter Melnichenko <[hidden email]> wrote:
>> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>>
>>> For example:
>>>
>>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>>> > setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>> io.write(v) end end}) out,out,out = "what","the","fuck"
>>> fuckthewhat>
>>>
>>
>> More magic:
>>
>>> local a, a, a = 1, 2, 3; print(a)
>> 3
>>> b, b, b = 1, 2, 3; print(b)
>> 1
>>
>
> Yeah, but at least it's consistent. that is, local x = 1; local x = 2;
> local x = 3; print(x) -> prints 3
>

(Side note: you should try using debug.getlocal with the local a,a,a
example/thing)

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Isaac Dupree-2
In reply to this post by Soni "They/Them" L.
On 09/14/2014 04:27 PM, Thiago L. wrote:

> On 9/14/14, Peter Melnichenko <[hidden email]> wrote:
>> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>>
>>> For example:
>>>
>>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>>>> setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>> io.write(v) end end}) out,out,out = "what","the","fuck"
>>> fuckthewhat>
>>>
>>
>> More magic:
>>
>>> local a, a, a = 1, 2, 3; print(a)
>> 3
>>> b, b, b = 1, 2, 3; print(b)
>> 1
>>
>
> Yeah, but at least it's consistent. that is, local x = 1; local x = 2;
> local x = 3; print(x) -> prints 3

local a
a, a, a = 1, 2, 3
print(a)
---> prints 1


Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Soni "They/Them" L.
On 9/14/14, Isaac Dupree <[hidden email]> wrote:

> On 09/14/2014 04:27 PM, Thiago L. wrote:
>> On 9/14/14, Peter Melnichenko <[hidden email]> wrote:
>>> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>>>
>>>> For example:
>>>>
>>>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>>>>> setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>>> io.write(v) end end}) out,out,out = "what","the","fuck"
>>>> fuckthewhat>
>>>>
>>>
>>> More magic:
>>>
>>>> local a, a, a = 1, 2, 3; print(a)
>>> 3
>>>> b, b, b = 1, 2, 3; print(b)
>>> 1
>>>
>>
>> Yeah, but at least it's consistent. that is, local x = 1; local x = 2;
>> local x = 3; print(x) -> prints 3
>
> local a
> a, a, a = 1, 2, 3
> print(a)
> ---> prints 1
>
>
>

Yeah but that assigns to the same register thingy not 3 different ones

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Hao Wu
In reply to this post by Peter Melnichenko-2
On Sun, Sep 14, 2014 at 1:08 PM, Peter Melnichenko <[hidden email]> wrote:

> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>
>
>>
>> For example:
>>
>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>> > setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>> > io.write(v) end end}) out,out,out = "what","the","fuck"
>> fuckthewhat>
>>
>

I am not sure this is right, but here is my thought:

> More magic:
>
>> local a, a, a = 1, 2, 3; print(a)
> 3
In this case, the latter a is defined and overrode the previous one, thus used.

>> b, b, b = 1, 2, 3; print(b)
> 1
the stack is popped in the reversed order so the first b is assigned
lastly (the same as the OP's example)

Another test I did kinda proved my theory:

> local a = 1; function foo() a = a+1; return a; end;
> local b,c,d = foo(), foo(), foo(); print(b,c,d)
2   3  4
>local b,b,b=foo(),foo(),foo(); print(b)
7

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Coda Highland
On Sun, Sep 14, 2014 at 1:44 PM, Hao Wu <[hidden email]> wrote:

> On Sun, Sep 14, 2014 at 1:08 PM, Peter Melnichenko <[hidden email]> wrote:
>> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>
>>
>>>
>>> For example:
>>>
>>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>>> > setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>>> > io.write(v) end end}) out,out,out = "what","the","fuck"
>>> fuckthewhat>
>>>
>>
>
> I am not sure this is right, but here is my thought:
>
>> More magic:
>>
>>> local a, a, a = 1, 2, 3; print(a)
>> 3
> In this case, the latter a is defined and overrode the previous one, thus used.
>
>>> b, b, b = 1, 2, 3; print(b)
>> 1
> the stack is popped in the reversed order so the first b is assigned
> lastly (the same as the OP's example)
>
> Another test I did kinda proved my theory:
>
>> local a = 1; function foo() a = a+1; return a; end;
>> local b,c,d = foo(), foo(), foo(); print(b,c,d)
> 2   3  4
>>local b,b,b=foo(),foo(),foo(); print(b)
> 7
>

As mentioned earlier in the thread: The behavior of ambiguous multiple
assignment is UNDEFINED. You can poke and speculate and figure out
what THIS version of Lua does, but you shouldn't rely on it. EVER.

It might change in the next version of Lua. It might be different in
third-party implementations of Lua. It might (however unlikely) change
if you build Lua on a different platform. It could fail entirely.

So it's a little silly to sit here and iterate on different possible
ways this might behave, because it's not required to be consistent (or
even sane).

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Hao Wu
On Sun, Sep 14, 2014 at 2:25 PM, Coda Highland <[hidden email]> wrote:

> On Sun, Sep 14, 2014 at 1:44 PM, Hao Wu <[hidden email]> wrote:
>> On Sun, Sep 14, 2014 at 1:08 PM, Peter Melnichenko <[hidden email]> wrote:
>>> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>>
>>>
>>>>
>>>> For example:
>>>>
>>>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>>>> > setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>>>> > io.write(v) end end}) out,out,out = "what","the","fuck"
>>>> fuckthewhat>
>>>>
>>>
>>
>> I am not sure this is right, but here is my thought:
>>
>>> More magic:
>>>
>>>> local a, a, a = 1, 2, 3; print(a)
>>> 3
>> In this case, the latter a is defined and overrode the previous one, thus used.
>>
>>>> b, b, b = 1, 2, 3; print(b)
>>> 1
>> the stack is popped in the reversed order so the first b is assigned
>> lastly (the same as the OP's example)
>>
>> Another test I did kinda proved my theory:
>>
>>> local a = 1; function foo() a = a+1; return a; end;
>>> local b,c,d = foo(), foo(), foo(); print(b,c,d)
>> 2   3  4
>>>local b,b,b=foo(),foo(),foo(); print(b)
>> 7
>>
>
> As mentioned earlier in the thread: The behavior of ambiguous multiple
> assignment is UNDEFINED. You can poke and speculate and figure out
> what THIS version of Lua does, but you shouldn't rely on it. EVER.
>
> It might change in the next version of Lua. It might be different in
> third-party implementations of Lua. It might (however unlikely) change
> if you build Lua on a different platform. It could fail entirely.
>
> So it's a little silly to sit here and iterate on different possible
> ways this might behave, because it's not required to be consistent (or
> even sane).

I agree with you that any assumption shouldn't be made for the order
of assignment, for now, but my point is that the result did make sense
if you think through how Lua usually works. It is undefined, yet
unsurprised. (besides, in the future version, this could be settled
and consistent, which might be the purpose of this thread).


>
> /s/ Adam
>

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Mike Nelson
Does anyone have an example of using the pathological case

a,a,a=1,2,3

or similar in real code (except as a coding error)? I can't think of a
use case for using the same variable more then once
on the left side of a multiple assignment.

-- Mike

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Coda Highland
On Sun, Sep 14, 2014 at 2:47 PM, Mike Nelson <[hidden email]> wrote:
> Does anyone have an example of using the pathological case
>
> a,a,a=1,2,3
>
> or similar in real code (except as a coding error)? I can't think of a use
> case for using the same variable more then once
> on the left side of a multiple assignment.
>
> -- Mike

I can't imagine any way it wouldn't be a bug if you did do it, but a
realistic way I could see such a thing arising unintentionally is
like:

tbl[a], tbl[b], tbl[c] = k1, k2, k3

where a, b, and c are determined by some logic external to the
function. If any of a, b, or c are the same value, you trigger this
behavior.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Oliver Kroth

>> Does anyone have an example of using the pathological case
>>
>> a,a,a=1,2,3
>>
>> or similar in real code (except as a coding error)? I can't think of a use
>> case for using the same variable more then once
>> on the left side of a multiple assignment.
>>
>> -- Mike
>
I had, although... One may say it was an coding error:

Coding an event queue using a binary heap, I wanted to to pick the first
one (into node) andmove the last position into first while clearing the
last position  ( node <- self[1} <- self[last] <- nil) in one statement:

     node, self[1], self[last], last         = self[1], self[last], nil,
last-1

The code worked, funny enough, as long as more than one event was in the
queue.
It did work better after I made four single assignments from it to
enforce the execution order:

     node       = self[1]
     self[1]    = self[last]
     self[last] = nil
     last       = last-1

--
Oliver

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Coda Highland
On Sun, Sep 14, 2014 at 10:48 PM, Oliver Kroth <[hidden email]> wrote:

>
>>> Does anyone have an example of using the pathological case
>>>
>>> a,a,a=1,2,3
>>>
>>> or similar in real code (except as a coding error)? I can't think of a
>>> use
>>> case for using the same variable more then once
>>> on the left side of a multiple assignment.
>>>
>>> -- Mike
>>
>>
> I had, although... One may say it was an coding error:
>
> Coding an event queue using a binary heap, I wanted to to pick the first one
> (into node) andmove the last position into first while clearing the last
> position  ( node <- self[1} <- self[last] <- nil) in one statement:
>
>     node, self[1], self[last], last         = self[1], self[last], nil,
> last-1
>
> The code worked, funny enough, as long as more than one event was in the
> queue.
> It did work better after I made four single assignments from it to enforce
> the execution order:
>
>     node       = self[1]
>     self[1]    = self[last]
>     self[last] = nil
>     last       = last-1
>
> --
> Oliver
>

With the exception of last==1, this is actually well-defined behavior.
All of the right-side values are evaluated before assignment. This
allows you to express a swap as "x, y = y, x".

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Tom N Harris
In reply to this post by Coda Highland
On Sunday, September 14, 2014 05:18:50 PM Coda Highland wrote:
> I can't imagine any way it wouldn't be a bug if you did do it, but a
> realistic way I could see such a thing arising unintentionally is
> like:
>
> tbl[a], tbl[b], tbl[c] = k1, k2, k3
>
> where a, b, and c are determined by some logic external to the
> function. If any of a, b, or c are the same value, you trigger this
> behavior.

Also relevant when __newindex is defined on the metatable and has side-
effects.

But I think you'd have to be some kind of sadist to put side-effects in a
metatable function. Nothing obfuscates a program more than when what looks
like a simple `=' sign means more than just assign a value to the lvalue.

--
tom <[hidden email]>

Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Axel Kittenberger
I don't get it? How about, just don't do it? Why should anybody ever do that?

Altough its not as easy to shoot ones foot with modern high level languages, in almost all of them it is still possible to create code with ill-defined behavior.

( I welcome the collection of ill-defined ways to code for academic interests, its sometimes not too easy to find how to. But other than that, who cares? )

PS: Almost any language has ill-defined behavior by calling a sort with a custom comparator where for example a > b, b > c, c > a

On Mon, Sep 15, 2014 at 9:07 AM, Tom N Harris <[hidden email]> wrote:
On Sunday, September 14, 2014 05:18:50 PM Coda Highland wrote:
> I can't imagine any way it wouldn't be a bug if you did do it, but a
> realistic way I could see such a thing arising unintentionally is
> like:
>
> tbl[a], tbl[b], tbl[c] = k1, k2, k3
>
> where a, b, and c are determined by some logic external to the
> function. If any of a, b, or c are the same value, you trigger this
> behavior.

Also relevant when __newindex is defined on the metatable and has side-
effects.

But I think you'd have to be some kind of sadist to put side-effects in a
metatable function. Nothing obfuscates a program more than when what looks
like a simple `=' sign means more than just assign a value to the lvalue.

--
tom <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Soni "They/Them" L.
In reply to this post by Hao Wu

On 14/09/14 06:36 PM, Hao Wu wrote:

> On Sun, Sep 14, 2014 at 2:25 PM, Coda Highland <[hidden email]> wrote:
>> On Sun, Sep 14, 2014 at 1:44 PM, Hao Wu <[hidden email]> wrote:
>>> On Sun, Sep 14, 2014 at 1:08 PM, Peter Melnichenko <[hidden email]> wrote:
>>>> 14.09.2014 21:33 "Thiago L." <[hidden email]>:
>>>>
>>>>
>>>>> For example:
>>>>>
>>>>> Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
>>>>>> setmetatable(_ENV, {__newindex = function(t,k,v) if k == "out" then
>>>>>> io.write(v) end end}) out,out,out = "what","the","fuck"
>>>>> fuckthewhat>
>>>>>
>>> I am not sure this is right, but here is my thought:
>>>
>>>> More magic:
>>>>
>>>>> local a, a, a = 1, 2, 3; print(a)
>>>> 3
>>> In this case, the latter a is defined and overrode the previous one, thus used.
>>>
>>>>> b, b, b = 1, 2, 3; print(b)
>>>> 1
>>> the stack is popped in the reversed order so the first b is assigned
>>> lastly (the same as the OP's example)
>>>
>>> Another test I did kinda proved my theory:
>>>
>>>> local a = 1; function foo() a = a+1; return a; end;
>>>> local b,c,d = foo(), foo(), foo(); print(b,c,d)
>>> 2   3  4
>>>> local b,b,b=foo(),foo(),foo(); print(b)
>>> 7
>>>
>> As mentioned earlier in the thread: The behavior of ambiguous multiple
>> assignment is UNDEFINED. You can poke and speculate and figure out
>> what THIS version of Lua does, but you shouldn't rely on it. EVER.
>>
>> It might change in the next version of Lua. It might be different in
>> third-party implementations of Lua. It might (however unlikely) change
>> if you build Lua on a different platform. It could fail entirely.
>>
>> So it's a little silly to sit here and iterate on different possible
>> ways this might behave, because it's not required to be consistent (or
>> even sane).
> [snip] (besides, in the future version, this could be settled
> and consistent, which might be the purpose of this thread).
Precisely.
>
>
>> /s/ Adam
>>


Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Tim Hill
In reply to this post by Axel Kittenberger

On Sep 15, 2014, at 3:48 AM, Axel Kittenberger <[hidden email]> wrote:

> I don't get it? How about, just don't do it? Why should anybody ever do that?
>
> Altough its not as easy to shoot ones foot with modern high level languages, in almost all of them it is still possible to create code with ill-defined behavior.
>
> ( I welcome the collection of ill-defined ways to code for academic interests, its sometimes not too easy to find how to. But other than that, who cares? )
>
> PS: Almost any language has ill-defined behavior by calling a sort with a custom comparator where for example a > b, b > c, c > a
>

Indeed. One of my interview questions for a C applicant is:

int k = 1;
k = k++ + ++k;

What is the value of k?

—Tim



Reply | Threaded
Open this post in threaded view
|

Re: Let's talk about order of assignment

Coroutines


On Mon, Sep 15, 2014 at 10:41 PM, Tim Hill <[hidden email]> wrote:

Indeed. One of my interview questions for a C applicant is:

int k = 1;
k = k++ + ++k;

What is the value of k?

I get the most joy out of scaring people with k = (k++, ++k, k + k, k) 

I love how in C++11/C11 they made things even /sequenced/ just to fuck with people (but also to give compilers more freedom for optimization).

Also this is a very good read for anybody else learning C* (or going in for interviews): http://auditty.org/info/deep-c.pdf
12