0
$\begingroup$

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[10]

Where is my error?

$\endgroup$
  • 1
    $\begingroup$ 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]. $\endgroup$ – Szabolcs Aug 15 '18 at 8:54
  • $\begingroup$ enp is a function argument, not a variable. enp -= something is not valid. $\endgroup$ – Szabolcs Aug 15 '18 at 8:55
2
$\begingroup$

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[2] 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[10]
(* 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[10]

(*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[10]
|improve this answer|||||
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.