<p>Inline assignment is when the assignment operator can return the value of the new-value (right-hand) operand. For example:</p>
<pre class="lang-c prettyprint-override"><code>if ((homedir = getenv(&quot;HOME&quot;)) == NULL) {
    // ...
}
</code></pre>
<p>I see inline assignment as a hack to make code less redundant. Certainly useful to minimize the number of helper variables that need to be created or evaluating expressions more times than need be. I can also assign multiple items to one value without having to use a variable or repeat the value:</p>
<pre class="lang-c prettyprint-override"><code>x = y = z = 0;
</code></pre>
<p>However, are there downsides to supporting inline assignment? Are there better options for their use cases, such as the aforementioned example?</p>

<operators><assignment>
What are the potential problems with assignment operators returning the new-value operand and how can they be avoided or mitigated?
CC BY-SA 4.0
2023-05-21T20:29:40.810Z
"_I see inline assignment as a hack to make code less redundant._" - Is this an essential point to the question? (is it necessary to understand the question and to answer it?) It seems to me something that should belong in elaborated form in an answer post. Consider the possibility that you are leading the question in a way that taints answers. Would that be intended?
starball
<h1>Disadvantage: Same object ID</h1>
<p>In Python, all variables assigned using this method will have the same object ID. This can be undesirable because</p>
<pre class="lang-python prettyprint-override"><code>x=y=z=[]
x.append(&quot;hi&quot;)
</code></pre>
<p>will add the string “hi” to all lists instead of just list <code>x</code>. <a href="https://tio.run/##K6gsycjPM7YoKPr/v8K20rbKNjqWq0IvsaAgNS9FQz0jU12Tq6AoM69Eo0KnUqcKxslM0ajQ1AGSlWCySlPz/38A" rel="nofollow noreferrer">TIO Link in case you don’t believe me.</a></p>
<h1>Workaround: using <code>exec()</code></h1>
<pre class="lang-python prettyprint-override"><code>def massassign(list,val):
 for x in list: # Iterate through the list
  exec(x+&quot;=&quot;+val) # Assigns the value to the variable. Value has to be in string form, like &quot;2&quot; to assign the integer 2 or &quot;'hi'&quot; to assign the string 'hi'.
</code></pre>
<p><strong>Note that <code>exec()</code> is very dangerous if you allow other users to access your hosted script.</strong></p>

CC BY-SA 4.0
2023-05-21T09:23:00.550Z
2023-05-21T13:32:33.577Z
2023-05-21T13:32:33.577Z
The Empty String Photographer
CC BY-SA 4.0
2023-05-21T13:08:05.660Z
How is this related to having a inline assignment operator in a language?
mousetail 'he-him'
CC BY-SA 4.0
2023-05-21T13:29:52.617Z
Make sure you read everything @mousetail
The Empty String Photographer
CC BY-SA 4.0
2023-05-21T13:30:18.113Z
@mousetail I might edit it to make it more readable
The Empty String Photographer
CC BY-SA 4.0
2023-05-21T13:34:27.057Z
@mousetail fixed: try reading now.
The Empty String Photographer
CC BY-SA 4.0
2023-05-21T13:46:57.740Z
Still not related to the question at all
mousetail 'he-him'
CC BY-SA 4.0
2023-05-21T13:47:23.087Z
Note the question is about assignment expressions, multiple assignment is just one example of how it could be used
mousetail 'he-him'
CC BY-SA 4.0
2023-07-07T10:13:49.583Z
Yes, it's totally unrelated.  The equivalent, with only assignment statements, is `z=[]; y=z; x=y` and that shows exactly the criticised behaviour (which may be desired or not, according to the problem domain).
Toby Speight
CC BY-SA 4.0
2023-09-05T20:13:35.890Z
@TobySpeight The difference is that if you're writing separate assignments, you're more likely to  write `x = []; y = []; z = [];` -- there's less temptation to avoid the duplication.
Barmar
<p>One downside is that this syntax can't be used in variable declarations, only in assignments. For example, in a language like Java which requires variables to be declared before they are used, the following line will give an error because <code>y</code> isn't declared:</p>
<pre class="lang-java prettyprint-override"><code>int x = y = 0;
</code></pre>
<p>Theoretically there could be a special case for this syntax, so that this statement would declare both <code>x</code> and <code>y</code> as new variables; but this would be surprising since <code>y = 0</code> is a perfectly valid expression when <code>y</code> already exists, so somebody <em>could</em> write the above expecting to assign to the existing variable <code>y</code>, in which case they would not expect the statement to declare a new variable with the same name, shadowing it.</p>
<hr />
<p>This is particularly a problem in Javascript, which requires <em>local</em> variables to be declared (as <code>var</code>, <code>let</code> or <code>const</code>) but <em>global</em> variables don't need to be. The following statement in Javascript won't fail at either compile-time or runtime:</p>
<pre class="lang-js prettyprint-override"><code>var x = y = 0;
</code></pre>
<p>But it doesn't do what the programmer really intended: it declares <code>x</code> as a local variable, but assigns to <code>y</code> <em>globally</em>, possibly overwriting an existing global variable of the same name.</p>
<hr />
<p>It may be worth noting that this <em>isn't</em> a problem in Python, because Python uses separate <code>global</code> or <code>nonlocal</code> declarations to determine whether a given name in this scope is a local variable or not. So</p>
<pre class="lang-python prettyprint-override"><code>(x := (y := 0))
</code></pre>
<p>in Python (using assignment expressions) can't accidentally assign to a nonlocal variable <code>y</code>. The same applies to multiple assignments like <code>x = y = 0</code>, but in Python's syntax this is only allowed as a statement, not an expression.</p>

CC BY-SA 4.0
2023-05-21T07:42:44.293Z
2023-09-03T19:02:57.517Z
2023-09-03T19:02:57.517Z
kaya3
CC BY-SA 4.0
2023-09-02T19:40:19.803Z
It would certainly be possible to make it also work for declarations: `int x = (int y = 0);`
xigoi
<p>Another downside is that it leads to code like:</p>
<pre><code>if (a == b) …
…
if (x = y) …
</code></pre>
<p>Is the second condition a test with a typo, or an inline assignment and test?<br />
I ran into far too many instances of those during my career.</p>
<p>(Note that things were often coded this way because older compilers would generate more code for separate <code>x=y</code> and <code>if (x==y) …</code> statements.)</p>
<p>In those cases where I <em>did</em> use the second form, I'd write it as:</p>
<pre><code>if (0 != (x=y)) …
</code></pre>
<p>The intent is clear and the same machine code will be generated.</p>

CC BY-SA 4.0
2023-05-21T14:13:26.613Z
2023-05-21T14:13:26.613Z
Ray Butterworth
CC BY-SA 4.0
2023-05-21T15:22:45.483Z
Inline assign-and-test is fairly common for one specific case in Objective-C: `if ((self = [super init]))` prevents the rest of your initializer from running if the superclass initializer failed.
Bbrk24
CC BY-SA 4.0
2023-09-05T20:11:11.430Z
The potential typo of `if (x = 1)` is what leads people to write "yoda conditions", e.g. `if (1 == x)`
Barmar
CC BY-SA 4.0
2023-09-07T20:54:34.433Z
How about having a language where `x=y` does not yield a value, but `x:=y;` would be an assignment expression that yields the value that was assigned, and `x=:y` would be an assignment expression that yields the value of the object prior to assignment?
supercat
<p>The main downside of inline assignment is that it creates confusion between <code>=</code> and <code>==</code>.</p>
<p>There are two workaround I know off:</p>
<ul>
<li>You could special case expressions like <code>x = y = z = 0</code> when they appear as their own statement. This is what python does.</li>
<li>You could just not use <code>=</code> for assignment. Either always use <code>:=</code> style assignment like Pascal or use <code>:=</code> only for inline assignment like python.</li>
<li>While this wouldn't work in the <code>x = y = z = 1</code> case, a way to embed arbitrary statements inside expressions would also allow assigment. For example, in rust <code>x = {y = {z = 0; z}; y}; x};</code> For just assigning the same value to many variables it is a bit verbose but this allows more flexibility when for example assigning in a loop condition.</li>
<li>For assignment inside loops or conditionals specifically you could have a <code>if let</code>/<code>while let</code> construct that allows you to check a condition and assign to a variable at the same time.</li>
</ul>

CC BY-SA 4.0
2023-05-21T06:18:00.580Z
2023-05-21T06:18:00.580Z
mousetail 'he-him'
CC BY-SA 4.0
2023-09-07T20:56:49.427Z
How about having `=` syntax for assignment outside expressions, but some other syntax such as `:=` for assignments within expressions in cases where they would facilitate the tasks programmers need to perform.
supercat
CC BY-SA 4.0
2023-05-21T20:01:11.090Z
I think this _might_ be suffering from a misunderstanding of the question. I've been talking with the asker to make the question more clear.
starball
CC BY-SA 4.0
2023-05-21T20:04:20.110Z
@starball I do think the `if let` and special casing `a = b = c`  are good alternatives to assignment expressions without the obvious downsides, and the other options too but to a lesser degree
mousetail 'he-him'
# What are the potential problems with assignment operators returning the new-value operand and how can they be avoided or mitigated?
Posted by: username_0 on 2023-05-21
Inline assignment is when the assignment operator can return the value of the new-value (right-hand) operand. For example:
if ((homedir = getenv("HOME")) == NULL) {
    // ...
}

I see inline assignment as a hack to make code less redundant. Certainly useful to minimize the number of helper variables that need to be created or evaluating expressions more times than need be. I can also assign multiple items to one value without having to use a variable or repeat the value:
x = y = z = 0;

However, are there downsides to supporting inline assignment? Are there better options for their use cases, such as the aforementioned example?
**Tags:** operators assignment
> **Comments:**
> **username_1**: "_I see inline assignment as a hack to make code less redundant._" - Is this an essential point to the question? (is it necessary to understand the question and to answer it?) It seems to me something that should belong in elaborated form in an answer post. Consider the possibility that you are leading the question in a way that taints answers. Would that be intended?  
---
## 4 answers
### Answer by username_6 on 2023-05-21. Score: 10 | Accepted answer
One downside is that this syntax can't be used in variable declarations, only in assignments. For example, in a language like Java which requires variables to be declared before they are used, the following line will give an error because y isn't declared:
int x = y = 0;

Theoretically there could be a special case for this syntax, so that this statement would declare both x and y as new variables; but this would be surprising since y = 0 is a perfectly valid expression when y already exists, so somebody could write the above expecting to assign to the existing variable y, in which case they would not expect the statement to declare a new variable with the same name, shadowing it.

This is particularly a problem in Javascript, which requires local variables to be declared (as var, let or const) but global variables don't need to be. The following statement in Javascript won't fail at either compile-time or runtime:
var x = y = 0;

But it doesn't do what the programmer really intended: it declares x as a local variable, but assigns to y globally, possibly overwriting an existing global variable of the same name.

It may be worth noting that this isn't a problem in Python, because Python uses separate global or nonlocal declarations to determine whether a given name in this scope is a local variable or not. So
(x := (y := 0))

in Python (using assignment expressions) can't accidentally assign to a nonlocal variable y. The same applies to multiple assignments like x = y = 0, but in Python's syntax this is only allowed as a statement, not an expression.
> **Comments:**
> **username_7** (2023-09-02): It would certainly be possible to make it also work for declarations: `int x = (int y = 0);`  
---
### Answer by username_8 on 2023-05-21. Score: 10
Another downside is that it leads to code like:
if (a == b) …
…
if (x = y) …

Is the second condition a test with a typo, or an inline assignment and test?
I ran into far too many instances of those during my career.
(Note that things were often coded this way because older compilers would generate more code for separate x=y and if (x==y) … statements.)
In those cases where I did use the second form, I'd write it as:
if (0 != (x=y)) …

The intent is clear and the same machine code will be generated.
> **Comments:**
> **username_9** (2023-05-21): Inline assign-and-test is fairly common for one specific case in Objective-C: `if ((self = [super init]))` prevents the rest of your initializer from running if the superclass initializer failed.  
> **username_5** (2023-09-05): The potential typo of `if (x = 1)` is what leads people to write "yoda conditions", e.g. `if (1 == x)`  
> **username_10** (2023-09-07): How about having a language where `x=y` does not yield a value, but `x:=y;` would be an assignment expression that yields the value that was assigned, and `x=:y` would be an assignment expression that yields the value of the object prior to assignment?  
---
### Answer by username_3 on 2023-05-21. Score: 6
The main downside of inline assignment is that it creates confusion between `=` and `==`.

There are two workaround I know off:

* You could special case expressions like `x = y = z = 0` when they appear as their own statement. This is what python does.
* You could just not use `=` for assignment. Either always use `:=` style assignment like Pascal or use `:=` only for inline assignment like python.
* While this wouldn't work in the `x = y = z = 1` case, a way to embed arbitrary statements inside expressions would also allow assigment. For example, in rust `x = {y = {z = 0; z}; y}; x};` For just assigning the same value to many variables it is a bit verbose but this allows more flexibility when for example assigning in a loop condition.
* For assignment inside loops or conditionals specifically you could have a `if let`/`while let` construct that allows you to check a condition and assign to a variable at the same time.
> **Comments:**
> **username_1** (2023-05-21): I think this _might_ be suffering from a misunderstanding of the question. I've been talking with the asker to make the question more clear.  
> **username_3** (2023-05-21): @starball I do think the `if let` and special casing `a = b = c`  are good alternatives to assignment expressions without the obvious downsides, and the other options too but to a lesser degree  
> **username_10** (2023-09-07): How about having `=` syntax for assignment outside expressions, but some other syntax such as `:=` for assignments within expressions in cases where they would facilitate the tasks programmers need to perform.  
---
### Answer by username_2 on 2023-05-21. Score: -2
Disadvantage: Same object ID
In Python, all variables assigned using this method will have the same object ID. This can be undesirable because
x=y=z=[]
x.append("hi")

will add the string “hi” to all lists instead of just list x. TIO Link in case you don’t believe me.
Workaround: using exec()
def massassign(list,val):
 for x in list: # Iterate through the list
  exec(x+"="+val) # Assigns the value to the variable. Value has to be in string form, like "2" to assign the integer 2 or "'hi'" to assign the string 'hi'.

Note that exec() is very dangerous if you allow other users to access your hosted script.
> **Comments:**
> **username_3** (2023-05-21): How is this related to having a inline assignment operator in a language?  
> **username_2** (2023-05-21): Make sure you read everything @mousetail  
> **username_2** (2023-05-21): @mousetail I might edit it to make it more readable  
> **username_2** (2023-05-21): @mousetail fixed: try reading now.  
> **username_3** (2023-05-21): Still not related to the question at all  
> **username_3** (2023-05-21): Note the question is about assignment expressions, multiple assignment is just one example of how it could be used  
> **username_4** (2023-07-07): Yes, it's totally unrelated.  The equivalent, with only assignment statements, is `z=[]; y=z; x=y` and that shows exactly the criticised behaviour (which may be desired or not, according to the problem domain).  
> **username_5** (2023-09-05): @TobySpeight The difference is that if you're writing separate assignments, you're more likely to  write `x = []; y = []; z = [];` -- there's less temptation to avoid the duplication.  
---
