What Are the Differences Between "=" and "≪-" Assignment Operators

What are the differences between = and - assignment operators?

What are the differences between the assignment operators = and <- in R?

As your example shows, = and <- have slightly different operator precedence (which determines the order of evaluation when they are mixed in the same expression). In fact, ?Syntax in R gives the following operator precedence table, from highest to lowest:


‘-> ->>’ rightwards assignment
‘<- <<-’ assignment (right to left)
‘=’ assignment (right to left)

But is this the only difference?

Since you were asking about the assignment operators: yes, that is the only difference. However, you would be forgiven for believing otherwise. Even the R documentation of ?assignOps claims that there are more differences:

The operator <- can be used anywhere,
whereas the operator = is only allowed at the top level (e.g.,
in the complete expression typed at the command prompt) or as one
of the subexpressions in a braced list of expressions.

Let’s not put too fine a point on it: the R documentation is wrong. This is easy to show: we just need to find a counter-example of the = operator that isn’t (a) at the top level, nor (b) a subexpression in a braced list of expressions (i.e. {…; …}). — Without further ado:

x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1

Clearly we’ve performed an assignment, using =, outside of contexts (a) and (b). So, why has the documentation of a core R language feature been wrong for decades?

It’s because in R’s syntax the symbol = has two distinct meanings that get routinely conflated (even by experts, including in the documentation cited above):

  1. The first meaning is as an assignment operator. This is all we’ve talked about so far.
  2. The second meaning isn’t an operator but rather a syntax token that signals named argument passing in a function call. Unlike the = operator it performs no action at runtime, it merely changes the way an expression is parsed.

So how does R decide whether a given usage of = refers to the operator or to named argument passing? Let’s see.

In any piece of code of the general form …

‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)

… the = is the token that defines named argument passing: it is not the assignment operator. Furthermore, = is entirely forbidden in some syntactic contexts:

if (‹var› = ‹value›) …
while (‹var› = ‹value›) …
for (‹var› = ‹value› in ‹value2›) …
for (‹var1› in ‹var2› = ‹value›) …

Any of these will raise an error “unexpected '=' in ‹bla›”.

In any other context, = refers to the assignment operator call. In particular, merely putting parentheses around the subexpression makes any of the above (a) valid, and (b) an assignment. For instance, the following performs assignment:

median((x = 1 : 10))

But also:

if (! (nf = length(from))) return()

Now you might object that such code is atrocious (and you may be right). But I took this code from the base::file.copy function (replacing <- with =) — it’s a pervasive pattern in much of the core R codebase.

The original explanation by John Chambers, which the the R documentation is probably based on, actually explains this correctly:

[= assignment is] allowed in only two places in the grammar: at the top level (as a complete program or user-typed expression); and when isolated from surrounding logical structure, by braces or an extra pair of parentheses.


In sum, by default the operators <- and = do the same thing. But either of them can be overridden separately to change its behaviour. By contrast, <- and -> (left-to-right assignment), though syntactically distinct, always call the same function. Overriding one also overrides the other. Knowing this is rarely practical but it can be used for some fun shenanigans.

What's the difference between `=` and `-` in R?

From here:

The operators <- and = assign into the environment in which they are evaluated. The operator <- can be used anywhere, whereas the operator = is only allowed at the top level (e.g., in the complete expression typed at the command prompt) or as one of the subexpressions in a braced list of expressions.

What is the difference between += and =+ C assignment operators

In modern C, or even moderately ancient C, += is a compound assignment operator, and =+ is parsed as two separate tokens. = and +. Punctuation tokens are allowed to be adjacent.

So if you write:

x += y;

it's equivalent to

x = x + y;

except that x is only evaluated once (which can matter if it's a more complicated expression).

If you write:

x =+ y;

then it's parsed as

x = + y;

and the + is a unary plus operator.

Very early versions of C (around the mid 1970s, before the publication of K&R1 in 1978) used different symbols for compound assignments. Where modern C uses +=, early C used =+. Early C had no unary + operator, but it did have a unary - operator, and the use of =- caused problems; programmers would write x=-y intending it to mean x = -y, but it was silently interpreted as x =- y. The language was changed some time between 1975 and 1978 to avoid that problem. As late as 1999, I worked with a compiler (VAXC on VMS) that would warn about an ambiguous use of =-, but would use the older meaning. That shouldn't be a concern now unless you're a hobbyist playing with some very old software and/or hardware.

(A 1975 C Reference Manual shows the old =-, =+, et al forms of the compound assignment operators. The first edition of The C Programming Language by Kernighan and Ritchie, published in 1978, shows the modern -=, +=, et al, but mentions the older forms under "Anachronisms".)

What is the difference between Assignment(=) operator and Equality(==) operator in OPA rule body

The assignment operator in Rego is :=, == is for comparison, and the = operator is for unification. There's a section describing the differences in the docs, but simply put, unification combines assignment and comparison, so in your example, given that input.path has two elements, the second elements value will be assigned to profile_id.

The policy could be written to split comparsion and assignment if you wanted:

allow {
count(input.path) == 2
input.path[0] == "users"
profile_id := input.path[1]
input.method == "GET"
profile_id == input.user_id
}

Which is arguably a bit messier. Unification should however be used sparingly, as in most other cases it is more clear to separate assignment from comparison.

Difference between - and -

The operator <<- is the parent scope assignment operator. It is used to make assignments to variables in the nearest parent scope to the scope in which it is evaluated. These assignments therefore "stick" in the scope outside of function calls. Consider the following code:

fun1 <- function() {
x <- 10
print(x)
}

> x <- 5 # x is defined in the outer (global) scope
> fun1()
[1] 10 # x was assigned to 10 in fun1()
> x
[1] 5 # but the global value of x is unchanged

In the function fun1(), a local variable x is assigned to the value 10, but in the global scope the value of x is not changed. Now consider rewriting the function to use the parent scope assignment operator:

fun2 <- function() {
x <<- 10
print(x)
}

> x <- 5
> fun2()
[1] 10 # x was assigned to 10 in fun2()
> x
[1] 10 # the global value of x changed to 10

Because the function fun2() uses the <<- operator, the assignment of x "sticks" after the function has finished evaluating. What R actually does is to go through all scopes outside fun2() and look for the first scope containing a variable called x. In this case, the only scope outside of fun2() is the global scope, so it makes the assignment there.

As a few have already commented, the <<- operator is frowned upon by many because it can break the encapsulation of your R scripts. If we view an R function as an isolated piece of functionality, then it should not be allowed to interfere with the state of the code which calls it. Abusing the <<- assignment operator runs the risk of doing just this.

Is there a technical difference between = and -

Yes there is. This is what the help page of '=' says:

The operators <- and = assign into the
environment in which they are
evaluated. The operator <- can be used
anywhere, whereas the operator = is
only allowed at the top level (e.g.,
in the complete expression typed at
the command prompt) or as one of the
subexpressions in a braced list of
expressions.

With "can be used" the help file means assigning an object here. In a function call you can't assign an object with = because = means assigning arguments there.

Basically, if you use <- then you assign a variable that you will be able to use in your current environment. For example, consider:

matrix(1,nrow=2)

This just makes a 2 row matrix. Now consider:

matrix(1,nrow<-2)

This also gives you a two row matrix, but now we also have an object called nrow which evaluates to 2! What happened is that in the second use we didn't assign the argument nrow 2, we assigned an object nrow 2 and send that to the second argument of matrix, which happens to be nrow.

Edit:

As for the edited questions. Both are the same. The use of = or <- can cause a lot of discussion as to which one is best. Many style guides advocate <- and I agree with that, but do keep spaces around <- assignments or they can become quite hard to interpret. If you don't use spaces (you should, except on twitter), I prefer =, and never use ->!

But really it doesn't matter what you use as long as you are consistent in your choice. Using = on one line and <- on the next results in very ugly code.

Difference between assignment and compound operators in Python

This is a difference between mutable and immutable objects. A mutable object can implement obj *= something by actually modifying the object in place; an immutable object can only return a new object with the updated value (in which case the result is identical to obj = obj * something). The compound assignment statements can handle either case, it's entirely up to the object's implementation.

Difference between := and = operators in Go

Only = is the assignment operator.

:= is a part of the syntax of the short variable declaration clause.

There are some rules though. See this other answer for more details.



Related Topics



Leave a reply



Submit