# SubtractFrom::rvalue with Compile

I want to compile the code described here, but I get the error:

SubtractFrom::rvalue: 1.*^8 is not a variable with a value, so its value cannot be changed.

A minimal non working example could be:

ClearAll[s]
fun = Compile[{{s, _Real}}, s -= 1]
fun


Where is my error?

• Please do make an effort to construct a minimal example (this applies to your last question as well). This error occurs when the left-hand side of -= is not a symbol, e.g. 2 -= 1 or With[{x=2}, x -= 1]. – Szabolcs Aug 15 '18 at 8:54
• enp is a function argument, not a variable. enp -= something is not valid. – Szabolcs Aug 15 '18 at 8:55

### Why does this happen?

To expand on the point made by @Szabolcs in the comments: In Mathematica, functions defined via downvalues, such as

f[x_] := x^2


are replacement rules. When an expression such as f is encountered, the rule is applied, and placeholders are inserted before any evaluation is done. So the first thing the right hand side "sees" is 2^2, not x^2. Notice how the "variable" x is already gone. Pure functions (Function/…&), and by extension compiled functions, work in a very similar fashion. This means that you cannot modify the value of such a parameter, as you're trying to do with x -= 1.

The following examples demonstrate that the behavior/issue is really much more fundamental that just Compile:

f[x_] := (x -= 1)

f
(* During evaluation of … SubtractFrom::rvalue: 10 is not a variable with a value, so its value cannot be changed. *)
(* 10 -= 1 *)

f2 = Function[x, x -= 1]
(* Function[x, x -= 1] *)

f2

(*During evaluation of … SubtractFrom::rvalue: 10 is not a variable with a value, so its value cannot be changed. *)
(* 10 -= 1 *)


Coming from another language, this might be unexpected, as function parameters are typically mutable variables.

### Solution/Workaround

The most straightforward solution is to just create a local variable using Module with the value of the parameter:

fun = Compile[{{s, _Real}}, Module[
{vs = s},
vs -= 1
]]

fun
`