Certain use patterns are very common, and thus often have special syntax to support them. These are primarily
syntactic sugar to reduce redundancy in the source code, but also assists readers of the code in understanding the programmer's intent, and provides the compiler with a clue to possible optimization.
Augmented assignment The case where the assigned value depends on a previous one is so common that many imperative languages, most notably
C and the majority of its descendants, provide special operators called
augmented assignment, like *=, so a = 2*a can instead be written as a *= 2. This is essentially equivalent to tmp = f(); i = tmp; arr[i] = tmp though no actual variable is produced for the temporary value.
Parallel assignment Some programming languages, such as
APL,
Common Lisp,
Go,
JavaScript (since 1.7),
Julia,
PHP,
Maple,
Lua,
occam 2,
Perl,
Python,
REBOL,
Ruby, and
PowerShell allow several variables to be assigned in parallel, with syntax like: a, b := 0, 1 which simultaneously assigns 0 to a and 1 to b. This is most often known as
parallel assignment; it was introduced in
CPL in 1963, under the name
simultaneous assignment, and is sometimes called
multiple assignment, though this is confusing when used with "single assignment", as these are not opposites. If the right-hand side of the assignment is a single variable (e.g. an array or structure), the feature is called
unpacking or
destructuring assignment:
var list := {0, 1} a, b := list The list will be unpacked so that 0 is assigned to a and 1 to b. Furthermore, a, b := b, a swaps the values of a and b. In languages without parallel assignment, this would have to be written to use a temporary variable
var t := a a := b b := t since a := b; b := a leaves both a and b with the original value of b. Some languages, such as
Go,
F# and
Python, combine parallel assignment, tuples, and automatic
tuple unpacking to allow multiple return values from a single function, as in this Python example, def f() -> tuple[int, int]: return 1, 2 a: int b: int a, b = f() while other languages, such as
C# and
Rust, shown here, require explicit tuple construction and deconstruction with parentheses: // Valid C# or Rust syntax (a, b) = (b, a); // C# tuple return (string, int) f() => ("foo", 1); var (a, b) = f(); // Rust tuple return let f: fn() -> (&str, i32) = || ("foo", 1); let (a, b): (&str, i32) = f(); This provides an alternative to the use of
output parameters for returning multiple values from a function. This dates to
CLU (1974), and CLU helped popularize parallel assignment generally. C# additionally allows generalized
deconstruction assignment with implementation defined by the expression on the right-hand side, as the compiler searches for an appropriate
instance or
extension Deconstruct method on the expression, which must have output parameters for the variables being assigned to. For example, one such method that would give the
class it appears in the same behavior as the return value of f() above would be void Deconstruct(out string a, out int b) { a = "foo"; b = 1; } In C and C++, the
comma operator is similar to parallel assignment in allowing multiple assignments to occur within a single statement, writing a = 1, b = 2 instead of a, b = 1, 2. This is primarily used in
for loops, and is replaced by parallel assignment in other languages such as Go. However, the above C++ code does not ensure perfect simultaneity, since the right side of the following code a = b, b = a+1 is evaluated after the left side. In languages such as Python, a, b = b, a+1 will assign the two variables concurrently, using the initial value of a to compute the new b. ==Assignment versus equality==