58

Preamble This is a very good question, because answering it will make it very clear what immutability means, both in general and in the context of Associations. General A few general words on immutability Associations are immutable data structures. This means that they carry no state, and a copy of an Association is another completely independent Association....


32

I believe Increment (more accurately PreIncrement as george2079 noted) is essentially this: SetAttributes[inc, HoldFirst] inc[a_] := a = (a + 1) This exhibits the same behavior, e.g. f[] := (Print[#]; #) &@RandomInteger[{1, 3}] v = {0, 0, 0}; inc @ v[[f[]]]; 2 1 Here f[] is evaluated twice because parameter a is used twice within Set. On the ...


30

I hesitate to add anything after @Leonid's comprehensive answer, but I'd like to point out that an easy way to achieve the stated goal is to define f like this: f[x_] := <| x, "isFirstValueTrue" -> x@"firstValue" |> ... which yields the desired result when mapped across the associations in x: f /@ x (* { <|"firstValue" -> True, "...


21

Update: Version 10 built-in function Values does value extraction conveniently for rules appearing in lists of arbitrary lengths and depths: {{x1, y1}, {x2, y2}} = Values[Solve[y^2 == 13 x + 17 && y == 193 x + 29, {x, y}]] (* {{(-11181-Sqrt[2242057])/74498,1/386 (13-Sqrt[2242057])}, {(-11181+Sqrt[2242057])/74498,1/386 (13+Sqrt[2242057])}} *) ...


21

You asked for a general explanation instead of just focusing on specific application examples, so here it goes ... The concepts of "pass by reference" and "pass by value" that you may know from languages like C do not apply very well to Mathematica. Do not try to think in this framework. The right question is not "how to pass by ...


20

Try for example SetAttributes[def, HoldAll] def[s_Symbol, v_] := Function[Null, s[x_] := #, HoldFirst][v] Unnamed functions just don't care :) Other alternatives that should also work (but I would use the previous approach) def[s_Symbol, v_] := Identity[SetDelayed][HoldPattern@s[x_], v]; def[s_Symbol, v_] := Unevaluated[s[x_] := "Hello"] /. "Hello" -> ...


18

General considerations To my mind, the only robust way to do this is to build some custom object model in Mathematica, and in particular to restrict the way values can be changed to some well-defined route you can control. Because, as it follows from one of the discussions you linked to, there seems to be no reliable way to intercept arbitrary value changes ...


16

The behaviour you observed is completely independent of NumericQ. It could also be seen with a function foo which has the initial definition foo[_]=False. Example 1: Initially you define NumerixQ[x]=True, which tells Mathematica that whenever it evaluates the expression NumericQ[x], it should evaluate to True. Since for symbols, it is pre-defined to return ...


15

The reason is that AppendTo and PrependTo actually replace the whole list with a new one, rather than only changing a single element. In that sense, they are not really "in-place". They are in-place in the sense that the result gets assigned back to the same variable. You can see using Trace, that AppendTo and PrependTo in fact expand: bar[1]={4,3,2,1}; ...


14

Turn off the warning It should be noted that we can treat Set::nosym as a warning message rather than an error, and simply turn it Off: Off[Set::nosym] {i, _, j} = {1, 2, 3}; {i, j} {1, 3} throw-away Symbol You could asko designate a Symbol for this purpose as a kind of dev/null, using e.g. $Post to clear it every time. I'll pick \[DoubleDagger], ...


14

The problem here is that in Mathematica, parameters of a function are not local variables. So trying to modify a parameter of a function inside it's body will lead to an error. The reason is that function arguments are evaluated, when the function is called so that it is actually the result of this evaluation that's textually substituted for the function ...


14

I think the best way to understand this behavior is with this example, In[99]:= x = {a, b, c, d, e}; In[101]:= Length@x Out[101]= 5 In[102]:= x[[3]] = Nothing; In[103]:= Length[x] Out[103]= 4 In[104]:= Block[{Nothing}, Length[x]] Out[104]= 5 When you say x[[3]] = Nothing, you are not deleting an element from x. x is still a 5-element list. But x is ...


13

This is an old discussion but is about an issue that resurfaces every now and then. One of the best (for a given sense of elegance) answers is the one posted on Stack Overflow ClearAll[f] SetAttributes[f, HoldAllComplete] f[a_, b_, c_] := { ToString@Unevaluated@a, ToString@Unevaluated@b, ToString@Unevaluated@c } f[a__] := Function[x, f[a, x], ...


13

Utilizing ValueFunction as mentioned here, we could do something like this: SetAttributes[Observe, HoldFirst]; Observe[s_Symbol, fn_] := With[{VF := Experimental`ValueFunction[s]}, VF = If[ValueQ @ VF, ReplacePart[VF, {2, 2, 2} -> Append[VF[[2, 2, 2]], fn]], Function[Null, Table[f[##], {f, {fn}}], HoldAll] ]; ] We will need to include ...


13

{x1, x2} = x /. Solve[x^2 + 3 x + 2 == 0, x] {-2, -1}


13

Attributes[swap] = HoldAll; swap[x_, y_] := {x, y} = {y, x}; x = 1; y = 2; swap[x, y]; {x, y} {2, 1} There are two characteristics of this code worth noting. The first is the HoldAll Attribute: How do I treat elements in a list as variables inside a module? When should I, and when should I not, set the HoldAll attribute on a function I define? Pass ...


12

General thoughts I think that your mechanism is reasonably robust for common use cases, but not fully robust if one wants to take into account all possible ways that the value (or, generally, global properties) of the symbol can be changed in Mathematica. My current opinion is that making such triggering mechanism fully robust without new system support is ...


12

At first, overriding Integrate[] is not per-se dangerous. Nevertheless, you should make sure that it gives the correct results by implementing a few unit tests (for example check, that Integrate[2 f[x], {x,1,2}] truly results in 2F[1,2], as you'd expect. Second, the pattern matching for Integrate[] is a bit more subtle: The rule you have given will not ...


12

The way Set works in setting parts of an expression is this: symb[[..<part specification>..]] = values; The component symb must be a symbol (i.e. with head Symbol). In the OP's code, p[[All,3]][[1;;2]] = {1,1}; The symb component is p[[All,3]], which is not a symbol. Fix as @kglr suggests, p[[1 ;; 2, 3]] = {1, 1}; As for evaluating p[[All,3]][[...


11

I propose these: SetAttributes[def, HoldAllComplete] def[s_Symbol, v_] := SetDelayed @@ Hold[s[x_], v] def[s_Symbol, v_] := With[{L := s[x_]}, L := v] def[s_Symbol, v_] := Reverse @ Unevaluated[v := s[x_]] The HoldAllComplete (or SequenceHold) attribute is necessary for an assignment such as: def[q, Sequence[1, 2, x]] head[q[5]] head[1, 2, 5] Also ...


11

You can use the third argument of ToExpression to do this in a structured way: ToExpression["x", InputForm, Unset]


11

This question is done and dusted but it is such a good one (together with the existing answers) for demonstrating and encapsulating the different ways Associations can be modified, that I'd like to belatedly summarise while suggesting some other takeaways. In particular, how it can further highlight a mutable and immutable dichotomy or perhaps more ...


11

Updated 14-10-2014 see solution at the end. Updated 17-07-2015 Bug no longer present in version 10.2 This answer is basically for documentation of the problem. The credit goes mainly to the people participating in the comments. Diagnostics I can reproduce you observation on two different computers both, Windows 7 Pro 64, SP 1 running Mathematica 10.0.1. ...


11

Now that OP has accepted an answer, implicitly making the results from it correct, here's a much faster method than the fastest there (as in 3x to nearly order of magnitude faster, depending on amount of missing points): v2 = c2 = ConstantArray[0, Length@v1]; v2[[o1]] = o2; c2[[o1]] = o1; c2[[Range[1, First@o1]]] = Range[1, First@o1]; v2 = v2[[With[{xx = c2}...


11

No, not a bug. Let's think about how AppendTo may be implemented (even though the actual implementation isn't inspectable). SetAttributes[appendTo, HoldFirst] appendTo[a_, val_] := (a = Append[a, val]) What happens if we evaluate the following? appendTo[ a[[ RandomInteger[{1,3}] ]], x ] It simply does this: a[[ RandomInteger[{1,3}] ]] = Append[a[[ ...


11

The problem is not related to Set in general but to how Set works with Part on a left hand side. Following Set::setps message documentation This message is generated when a part assignment is used for the value of an expression other than a symbol. Part assignments are implemented only for parts of the value of a symbol. Shortly Part[(*something*), (*spec*)...


11

He is simply saying that the first argument of Set is not evaluated before Set creates the definition. However, the sub-parts of the first argument are all evaluated, including the head(i.e. part 0). Thus in f[x] = y f[x] is not evaluated in the sense that any previous definition similar to f[z_] := z^2 will be ignored. However, f is evaluated and x is ...


10

You can use injector pattern for that: {Hold[{a = 2, b = 3}], Hold[{a = 4, b = 6}]}[[1]] /. Hold[init_] :> With[init, a + b] (* 5 *) {Hold[{a = 2, b = 3}], Hold[{a = 4, b = 6}]}[[2]] /. Hold[init_] :> With[init, a + b] (* 10 *) but you can see that Hold is preferred over Unevaluated in such cases. As an alternative, you can define your own ...


10

You need to use InputForm to see the actual value of the numbers. x = -15*0.1 + 6*0.1; InputForm[x] Now when you wrote a[-15*0.1 + 6*0.1] = 5 Now 5 is actually stored in a[-0.8999999999999999] and not in a[-0.9], this is why a[-0.9] does not return the value 5 you expected. But when you wrote a[-0.8999999999999999] it did. Now, as to why -15*0.1 + ...


Only top voted, non community-wiki answers of a minimum length are eligible