In computer programming, an assignment statement sets and/or re-sets the value stored in the storage location(s) denoted by a variable name; in other words, it copies a value into the variable. In most imperative programming languages, the assignment statement (or expression) is a fundamental construct.
Today, the most commonly used notation for this operation is <code>x = expr</code> (originally Superplan 1949–51, popularized by Fortran 1957 and C). The second most commonly used notation is Many other notations are also in use. In some languages, the symbol used is regarded as an operator (meaning that the assignment statement as a whole returns a value). Other languages define assignment as a statement (meaning that it cannot be used in an expression).
Assignments typically allow a variable to hold different values at different times during its life-span and scope. However, some languages (primarily strictly functional languages) do not allow that kind of "destructive" reassignment, as it might imply changes of non-local state. The purpose is to enforce referential transparency, i.e. functions that do not depend on the state of some variable(s), but produce the same results for a given set of parametric inputs at any point in time. Modern programs in other languages also often use similar strategies, although less strict, and only in certain parts, in order to reduce complexity, normally in conjunction with complementing methodologies such as data structuring, structured programming and object orientation.
Semantics
An assignment operation is a process in imperative programming in which different values are associated with a particular variable name as time passes. The program, in such model, operates by changing its state using successive assignment statements. Primitives of imperative programming languages rely on assignment to do iteration.
Variables are containers for values. It is possible to put a value into a variable and later replace it with a new one. An assignment operation modifies the current state of the executing program. other than producing the result, and always produces same value for the same input. and is referred to as destructive assignment for that reason in LISP and functional programming, similar to destructive updating.
Single assignment is the only form of assignment available in purely functional languages, such as Haskell, which do not have variables in the sense of imperative programming languages
Impure functional languages provide both single assignment as well as true assignment (though true assignment is typically used with less frequency than in imperative programming languages). For example, in Scheme, both single assignment (with <code>let</code>) and true assignment (with <code>set!</code>) can be used on all variables, and specialized primitives are provided for destructive update inside lists, vectors, strings, etc. In OCaml, only single assignment is allowed for variables, via the <code>let name = value</code> syntax; however destructive update can be used on elements of arrays and strings with separate <code><-</code> operator, as well as on fields of records and objects that have been explicitly declared mutable (meaning capable of being changed after their initial declaration) by the programmer.
Functional programming languages that use single assignment include Clojure (for data structures, not vars), Erlang (it accepts multiple assignment if the values are equal, in contrast to Haskell), F#, Haskell, JavaScript (for constants), Lava, OCaml, Oz (for dataflow variables, not cells), Racket (for some data structures like lists, not symbols), SASL, Scala (for vals), SISAL, Standard ML. Non-backtracking Prolog code can be considered explicit single-assignment, explicit in a sense that its (named) variables can be in explicitly unassigned state, or be set exactly once. In Haskell, by contrast, there can be no unassigned variables, and every variable can be thought of as being implicitly set, when it is created, to its value (or rather to a computational object that will produce its value on demand).
Value of an assignment
In some programming languages, an assignment statement returns a value, while in others it does not.
In most expression-oriented programming languages (for example, C), the assignment statement returns the assigned value, allowing such idioms as <code>x = y = a</code>, in which the assignment statement <code>y = a</code> returns the value of <code>a</code>, which is then assigned to <code>x</code>. In a statement such as , the return value of a function is used to control a loop while assigning that same value to a variable.
In other programming languages, Scheme for example, the return value of an assignment is undefined and such idioms are invalid.
In Haskell, there is no variable assignment; but operations similar to assignment (like assigning to a field of an array or a field of a mutable data structure) usually evaluate to the unit type, which is represented as <code>()</code>. This type has only one possible value, therefore containing no information. It is typically the type of an expression that is evaluated purely for its side effects.
Variant forms of assignment
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 <code>*=</code>, so <code>a = 2*a</code> can instead be written as <code>a *= 2</code>. This is essentially equivalent to <code>tmp = f(); i = tmp; arr[i] = tmp</code> 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 <code>a</code> and 1 to <code>b</code>. 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 <code>a</code> and 1 to <code>b</code>. Furthermore,
a, b := b, a
swaps the values of <code>a</code> and <code>b</code>. In languages without parallel assignment, this would have to be written to use a temporary variable
var t := a
a := b
b := t
since <code>a := b; b := a</code> leaves both <code>a</code> and <code>b</code> with the original value of <code>b</code>.
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,
<syntaxhighlight lang="python">
def f() -> tuple[int, int]:
return 1, 2
a: int
b: int
a, b = f()
</syntaxhighlight>
while other languages, such as C# and Rust, shown here, require explicit tuple construction and deconstruction with parentheses:
<syntaxhighlight lang="csharp">
// Valid C# or Rust syntax
(a, b) = (b, a);
</syntaxhighlight>
<syntaxhighlight lang="csharp">
// C# tuple return
(string, int) f() => ("foo", 1);
var (a, b) = f();
</syntaxhighlight>
<syntaxhighlight lang="rust">
// Rust tuple return
let f: fn() -> (&str, i32) = || ("foo", 1);
let (a, b): (&str, i32) = f();
</syntaxhighlight>
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 <code>Deconstruct</code> 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 <code>f()</code> above would be
<syntaxhighlight lang="csharp">
void Deconstruct(out string a, out int b) { a = "foo"; b = 1; }
</syntaxhighlight>
In C and C++, the comma operator is similar to parallel assignment in allowing multiple assignments to occur within a single statement, writing <code>a = 1, b = 2</code> instead of <code>a, b = 1, 2</code>.
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 <code>a = b, b = a+1</code> is evaluated after the left side. In languages such as Python, <code>a, b = b, a+1</code> will assign the two variables concurrently, using the initial value of a to compute the new b.
Assignment versus equality
The use of the equals sign <code>=</code> as an assignment operator has been frequently criticized, due to the conflict with equals as comparison for equality. This results both in confusion by novices in writing code, and confusion even by experienced programmers in reading code. The use of equals for assignment dates back to Heinz Rutishauser's language Superplan, designed from 1949 to 1951, and was particularly popularized by Fortran:
Beginning programmers sometimes confuse assignment with the relational operator for equality, as "=" means equality in mathematics, and is used for assignment in many languages. But assignment alters the value of a variable, while equality testing tests whether two expressions have the same value.
In some languages, such as BASIC, a single equals sign (<code>"="</code>) is used for both the assignment operator and the equality relational operator, with context determining which is meant. Other languages use different symbols for the two operators. For example:
- In ALGOL and Pascal, the assignment operator is a colon and an equals sign (<code>":="</code>) while the equality operator is a single equals (<code>"="</code>).
- In C, the assignment operator is a single equals sign (<code>"="</code>) while the equality operator is a pair of equals signs (<code>"=="</code>).
- In R, the assignment operator is basically <code><-</code>, as in <code>x <- value</code>, but a single equals sign can be used in certain contexts.
The similarity in the two symbols can lead to errors if the programmer forgets which form ("<code>=</code>", "<code>==</code>", "<code>:=</code>") is appropriate, or mistypes "<code>=</code>" when "<code>==</code>" was intended. This is a common programming problem with languages such as C (including one famous attempt to backdoor the Linux kernel), where the assignment operator also returns the value assigned (in the same way that a function returns a value), and can be validly nested inside expressions. If the intention was to compare two values in an <code>if</code> statement, for instance, an assignment is quite likely to return a value interpretable as Boolean true, in which case the <code>then</code> clause will be executed, leading the program to behave unexpectedly. Some language processors (such as gcc) can detect such situations, and warn the programmer of the potential error.
Notation
The two most common representations for the copying assignment are equals sign (<code>=</code>) and colon-equals (<code>:=</code>). Both forms may semantically denote either an assignment statement or an assignment operator (which also has a value), depending on language and/or usage.
:{| class="wikitable"
|-
| <code>variable = expression</code> || Fortran, PL/I, C (and descendants such as C++, Java, etc.), Bourne shell, Python, Go (assignment to pre-declared variables), R, PowerShell, Nim, etc.
|-
| <code>variable := expression</code> || ALGOL (and derivatives), Simula, CPL, BCPL, Pascal (and descendants such as Modula), Mary, PL/M, Ada, Smalltalk, Eiffel, Oberon, Dylan, Python (an assignment expression), Go (shorthand for declaring and defining a variable), Io, AMPL, ML (assigning to a reference value), AutoHotkey etc.
|-
|}
Other possibilities include a left arrow or a keyword, though there are other, rarer, variants:
:{| class="wikitable"
|-
| <code>variable << expression</code> || Magik
|-
| <code>variable <- expression</code> || F#, OCaml, R, S
|-
| <code>variable <<- expression</code> || R
|-
| <code> assign("variable", expression)</code> || R
|-
| <code>variable ← expression</code> || APL, Smalltalk, Atari 2600 BASIC Programming
|-
| <code>variable =: expression</code> || J
|-
| <code>LET variable = expression</code> || BASIC
|-
| <code>let variable := expression</code> || XQuery
|-
| <code>set variable to expression</code> || AppleScript
|-
| <code>set variable = expression</code> || C shell
|-
| <code>Set-Variable variable (expression)</code> || PowerShell
|-
| <code>variable : expression</code> || Macsyma, Maxima, K
|-
| <code>variable: expression</code> || Rebol
|-
| <code>var variable expression</code> || mIRC scripting language
|-
| <code>reference-variable :- reference-expression</code> || Simula
|}
Mathematical pseudo code assignments are generally depicted with a left-arrow.
Some platforms put the expression on the left and the variable on the right:
:{| class="wikitable"
|-
| style="padding-right: 1em" | <code>MOVE expression TO variable</code> || COBOL
|-
| style="padding-right: 1em" | <code>expression → variable</code> || TI-BASIC, Casio BASIC
|-
| style="padding-right: 1em" | <code>expression -> variable</code> || POP-2, BETA, R
|-
| style="padding-right: 1em" | <code>put expression into variable</code> || HyperTalk, LiveCode
|-
| style="padding-right: 1em" | <code>PUT expression IN variable</code> || ABC
|}
Some expression-oriented languages, such as Lisp and Tcl, uniformly use prefix (or postfix) syntax for all statements, including assignment.
:{| class="wikitable"
|-
| style="padding-right: 1em" | <code>(setf variable expression)</code> || Common Lisp
|-
| <code>(set! variable expression)</code> || Scheme
|-
| <code>set variable expression</code> || Tcl
|-
| style="padding-right: 1em" | <code>expression variable !</code> || Forth
|}
See also
- Assignment operator (C++)
- Static single-assignment form
- Unification (computer science)
- Immutable object
- Assignment problem
