512
$\begingroup$

As you may already know, Mathematica is a wonderful piece of software.
However, it has a few characteristics that tend to confuse new (and sometimes not-so-new) users. That can be clearly seen from the the fact that the same questions keep being posted at this site over and over again.

Please help me to identify and explain those pitfalls, so that fewer new users make the mistake of walking into these unexpected traps.

Suggestions for posting answers:

  • One topic per answer
  • Focus on non-advanced uses (it's intended to be useful for beginners/newbies/novices and as a question closing reference)
  • Include a self explanatory title in h2 style
  • Explain the symptoms of problems, the mechanism behind the scenes and all possible causes and solutions you can think of. Be sure to include a beginner's level explanation (and a more advanced one too, if you're in the mood)
  • Include a link to your answer by editing the Index below (for quick reference)

Stability and usability

Syntax and semantics

Assignment and definition

General guidelines

Graphics and images

Tricky functions

$\endgroup$
15
  • 6
    $\begingroup$ Few suggestions: 1. old definitions in memory and "overloaded" functions like f[x_]:=a; f[x_Integer]=b; 2. Forgotten underscore in patterns f[x]=a 3. Set vs SetDelayed; 4. m = {{1, 2}, {3, 4}} // MatrixForm and then Eigenvalues[q]; 5. Plotting complex function produces empty plot without any warnings. $\endgroup$ Jan 24 '13 at 22:23
  • 2
    $\begingroup$ I want to throw $HistoryLength in there, a memory management in general category including MaxMemoryUsed and MemoryConstrained etc $\endgroup$
    – ssch
    Jan 25 '13 at 0:03
  • 5
    $\begingroup$ Suggestion: If appropriate to the problem, force Mathematica to use approximate numerical algorithms to avoid the computational overhead of their symbolic counterparts. There are several ways to do this (e.g., NIntegrate vs. Integrate, using real approximate numbers instead of integers in equations, etc). $\endgroup$
    – Cassini
    Jan 25 '13 at 3:51
  • 4
    $\begingroup$ Suggestion: mathematica.stackexchange.com/q/18483/193 (Using the result of functions that return replacement rules) $\endgroup$ Jan 26 '13 at 7:46
  • 6
    $\begingroup$ Maybe there should be a (short) answer about security. Most people don't realize mathematica has a large set of functions that are capable of taking over your computer entirely, or as a more specific example, activating your webcam (CurrentImage). $\endgroup$ Aug 8 '13 at 11:19

37 Answers 37

1
2
9
$\begingroup$

Association/<||> objects are Atomic and thus unmatchable before 10.4

AtomQ@Association[] yields True.

This is confusing because it is not stated anywhere in the manual. For example tutorial/BasicObjects#15871 claims that only numbers (including complex ones), Strings and Symbols are atomic objects. guide/AtomicElementsOfExpressions does not mention Association either, neither does guide/Associations.

Association@@{a -> b, c -> d} does not act like association @@ {a -> b, c -> d}, although the FullForm suggests it does

association @@ {a -> b, c -> d} // FullForm
Association @@ {a -> b, c -> d} // FullForm

The Association[] constructor function does a non trivial job, such that the following are both False:

MatchQ[Association[], Unevaluated@Association[]]
MatchQ[Unevaluated@Association[], Association[]]

Also, MatchQ[<|x->1|>, Association[___]] === False. Note: MatchQ[<|x->1|>, Association[___]] should evaluate to True (checked with version 11.1)

standard pattern matching inside the structure will not work.

You are probably best off converting associations to rule lists before pattern matching via Normal: MatchQ[Normal@<|x -> 1|>, {___}] === True.

Statement from WRI

It just so happens that Association is currently AtomQ, though I've argued strongly against that fact internally, and I've got SW's say-so that we'll change that eventually. But that doesn't have all that much to do with pattern matching not working inside associations: we all agree it should, it's just hard to do efficiently and we couldn't deliver it for 10. So, to sum up: Association will not be AtomQ forever, and it will support pattern matching eventually. There's a correlation here, not a causation.

Further reading

How to match Association[]?

MatchQ-ing Associations (MMA 10)

Fixed in 10.4

In Mathematica 10.4, Association can now be used in pattern matching.

There's now also KeyValuePattern which is a pattern object specifically to match elements of an Association or list of rules.

https://mathematica.stackexchange.com/a/109383/6804

$\endgroup$
7
$\begingroup$

Plot functions do not print output (Where are my plots?)

Quite often new users write something like this and are surprised that no plots are produced:

For[
  n = 1,
  n <= 3,
  n++,
  Plot[Sin[x*n], {x, 0, 2 Pi}]
]

Since version 6 of Mathematica the plot functions (Plot, Plot3D, ListPlot, ContourPlot, ParametricPlot, etc.) do not print their output but instead evaluate to a Graphics or Graphics3D expression, just as 2 + 2 evaluates to 4.

To see the output of Plot in this loop one needs to write it to the Notebook as a side-effect which is exactly what Print does. This can be done explicitly (Print[ Plot[. . .] ]) or by setting $DisplayFunction to something with a side-effect as it was in versions 5.2 and earlier.

A better approach is to collect and display the direct output of Plot as it may be manipulated like any other expression. The most direct substitute for the For loop is Table:

Table[
  Plot[Sin[x*n], {x, 0, 2 Pi}],
  {n, 1, 3}
]

enter image description here

This returns (evaluates to) a List containing three Graphics expressions. These expressions are displayed by the Front End as graphical objects that may be interactively manipulated. This output may be assigned to a Symbol or Indexed Object. It may be displayed in particular arrangements using e.g. Row, Column, Multicolumn, GraphicsRow, etc., or animated with ListAnimate

The Graphics expressions may be modified with the full range of expression manipulation tools, sometimes referred to as post-processing as one starts with the existing plot output.

$\endgroup$
7
$\begingroup$

In symbolic algebra, x[1] is quite different from x1. This one-liner avoids problems and gets nice subscript formatting.

x[i_Integer] := x[i] = 
   With[
     {u = Unique[x]}, 
     Format[u] = Subscript[x,i];
     u
   ]

There are many advantages to using x[1], x[2], ... as symbolic variables, such as creating a list of them with Array[x, 5] to pass into Solve[], or creating a list of expressions with Table[x[i] + x[i + 1], {i, 5}].

There are also some good reasons to avoid this practice. Some operations choke on them. Writing x[1] sometimes declares that x is a function of one variable only and x[1] may be assumed constant.

They also are not formatted as subscripts. Using Subscript[x,1] as a variable also invites trouble. The above one-liner solves both problems.

Array[x, 4] then displays as $\left\{\text{x}_1,\text{x}_2,\text{x}_3,\text{x}_4\right\}$, actually (say) {x$2136, x$2152, x$2163, x$2164}.

Table[x[i] + x[i + 1], {i, 3}] returns $\{\text{x}_1 + \text{x}_2, \text{x}_2 + \text{x}_3, \text{x}_3 + \text{x}_4\}$.

Further reading:

$\endgroup$
5
  • $\begingroup$ ??x does not show the internal form. DownValues[x]//InputForm does, but does not list the Format definitions. How can I make Information["x"] print the internal values? How can I discover what Format definitions exist? $\endgroup$ Feb 7 '17 at 19:36
  • $\begingroup$ I made a new answer because this one is very different from what 3 people downvoted. I hope it will be judged on its merits. $\endgroup$ Feb 7 '17 at 19:38
  • $\begingroup$ FullDefinition[x] should show what you want. $\endgroup$
    – Mr.Wizard
    Feb 8 '17 at 3:13
  • $\begingroup$ It seems FormatValues[] contains the definitions. It's hard to print it, though, because the Format gets applied even to things inside HoldComplete[]. FormatType inside the MakeBoxes rule triggers an error message. With[{XX=x[100]}, With[{fvxx=FormatValues[XX]}, FormatValues[XX]={}; Print[fvxx/.{Format->"Format",Subscript->"Subscript"}];FormatValues[XX]=fvxx ]]; prints {HoldPattern[Format[x$145]] :> Subscript[x, 100], HoldPattern[MakeBoxes[x$145, FormatType_]] :> Format[Subscript[x, 100], FormatType]} $\endgroup$ Feb 8 '17 at 6:54
  • $\begingroup$ Oh, sorry, I finally understand what you're talking about. Consider FullDefinition[x] // InputForm $\endgroup$
    – Mr.Wizard
    Feb 8 '17 at 7:45
6
$\begingroup$

PerformanceGoal -> "Speed" can yield irreproducible results.

For example, the procedure doPlot below

  1. computes a SmoothKernelDistribution on a fixed data vector (DATA);
  2. defines a pdf function based on this distribution;
  3. plots the pdf function.
doPlot[] := Module[{
    pdf,
    distribution = SmoothKernelDistribution[DATA,
                                            "StandardGaussian", "Biweight", 
                                            PerformanceGoal -> "Speed"]
   },
   pdf = Function[x, PDF[distribution, x]];
   Plot[pdf[x], {x, 0, 180000}, PlotRange -> {All, {0, 0.00004}},
        Axes -> False, Frame -> True, FrameTicks -> None,
        ImageSize -> 50, AspectRatio -> 1, ImagePadding -> {{0, 1}, {1, 0}}]
]

Since doPlot takes no arguments, one could hope that it would produce the same results every time, but this is not the case. The figure below shows the result of 100 runs of doPlot.

Mathematica graphics

It appears that "reproducibility" is one of the ingredients of "Quality" that one forfeits when one specifies PerformanceGoal -> "Speed". This is not outlandish, of course, but it is not self-evident either.

$\endgroup$
3
$\begingroup$

Understanding $Context, $ContextPath the parsing stage and runtime scoping constructs

A symbol in Mathematica can never be without a context. We can assume that the internal representation of any symbol stores a string of the form "context`symbol".

But for you as a programmer, there are ways to enter a symbol without stating it's full context: x, Sin, `x are all valid inputs.

The values of $Context and $ContextPath at the parsing stage determine which symbol is actually meant by the above inputs.

This settles which symbols are initially used in the expression put together that will be submitted to the evaluator. You can display the actual name of symbols in a snippet of code by printing the "FullForm" of an expression with context as follows:

Hold[

(*your code here*)
x

] /. x_Symbol :> Context@x <> SymbolName@Unevaluated@x
(*=>*)
"System`Hold"["Global`x"]

(see here for more ways of doing this). Note that Mathematica strips the context whenever possible, even in FullForm, to present to you more or less what you (supposedly) entered: Global`y is displayed as just y.

However, at runtime, an x that is parsed as Global`x might well become something else still. Let's try the following:

Hold[

  Module[{x}, x]

  ] /. x_Symbol :> Context@x <> SymbolName@Unevaluated@x

gives

"System`Hold"["System`Module"["System`List"["Global`x"], "Global`x"]]

So the variable is parsed as Global`x. But evaluating Module[{x}, x] we get something like x$11686. Module changed every literal occurrence of Global`x to a variable created probably via Unique@Unevaluated@x before executing the code.

However, this replacement is aware of some scoping constructs of the language which it will not enter. Rule is one of them:

Module[{x}, {x, x_ -> x}]

gives

{x$12264, x_ -> x}

And not say {x$12264, x$12264_ -> x$12264}.

With and Function are also scoping constructs which interact. Here for example, every x is parsed as Global`x:

Hold[

  With[{y = x}, Function[{x}, x + y]]

  ] /. x_Symbol :> Context@x <> SymbolName@Unevaluated@x
(*=>*)
System`Hold[System`With[System`List[System`Set[Global`y,Global`x]],System`Function[System`List[Global`x],System`Plus[Global`x,Global`y]]]]

But in the result of evaluation a new symbol $x will have been created to resolve a (potential) name clash:

Function[{x$}, x$ + x]

BeginPackage, Begin and messages like

*::shdw: Symbol * appears in multiple contexts {*}; definitions in context * may shadow or be shadowed by other definitions. >>

also fall into this complex of considerations.

Related questions and "articles"

Many questions tagged with variable-definitions scoping and contexts deal with this topic. Here's a selection:

Context of localised (dynamic) symbols

DynamicModule Initialization is not executing when expected?

How to scope `Pattern` labels in rules/set?

How to make a function like Set, but with a Block construct for the pattern names

tutorial/VariablesInPureFunctionsAndRules

package import problem in mathematica (Stackoverflow)

$\endgroup$
5
  • 4
    $\begingroup$ Is this really a "common pitfall awaiting new users?" It's tricky admittedly, but hardly a pitfall until you start writing packages, imo. $\endgroup$
    – Michael E2
    Jul 3 '16 at 18:37
  • $\begingroup$ Even when you want to use packages (which is basic/should be encouraged) you need to know that you cannot put (Needs["Apackage`"]; PackageFunction[...];) into one expression (or one line in the frontend!): You need to have one roundtrip to the kernel to have Needs update the $ContextPath, c.f. e.g. stackoverflow.com/questions/4664091/… . And I think knowing what exactly an identifier denotes is crucial in any programming language. $\endgroup$
    – masterxilo
    Jul 3 '16 at 23:30
  • 2
    $\begingroup$ @MichaelE2 I think you both are right but due to the lack of a proper place it is good to have it here. Maybe we could think about another guidelike topic: "Fundamentals that are spread too thinly across documentation", it would fit there best, don't you think? $\endgroup$
    – Kuba
    Jul 4 '16 at 5:52
  • 2
    $\begingroup$ I agree with @Michael and @Kuba: currently this post is intended for experienced users who wish to write a package. The (Needs["Apackage`"]; PackageFunction[...];) case should be included as a point into one of the multi-point answers here (I think this answer perfectly fits). Probably we should move this answer to a new thread and include in the OP here a link to that thread with wordings like "This thread is intended primarily to those who learn the basics of the WL. For discussion on subtle/professional topics see that thread". $\endgroup$ Jul 4 '16 at 9:19
  • $\begingroup$ @MichaelE2 and mastexilo, I tied to polish this topic to make it a generic one about parsing, suggestions appreciated. 119187 $\endgroup$
    – Kuba
    Jul 15 '16 at 7:15
2
$\begingroup$

Association has HoldAllComplete attribute

Association is not just another head denoting a special kind of list of rules or a certain kind of object. It has some properties that make querying it more efficient, but also cause it to behave differently from a List. You should be aware of this if you intend to use Associations as a data structure for object oriented programming.

Let me illustrate. Say we want to have a single expression representing a person with the attribute age. We might use a custom head, list or association to store a rule assigning "age" to something. A list and custom head person will support template objects which have some parameters undefined at the time of their definition. But a head with HoldAll such as hperson and Association will not fill in the blanks once you define them.

ClearAll[p1, p2, p3, x, getAgeSquared, hperson];

(*make hperson behave more like Assocation*)
SetAttributes[hperson, HoldAll];

p1 = person["age" -> x]
p2 = List["age" -> x]
p3 = Association["age" -> x]
p4 = hperson["age" -> x]

getAgeSquared@_["age" -> x_Real] := x^2;
(*these stay unevaluated*)
getAgeSquared@p1
getAgeSquared@p2
getAgeSquared@p3
getAgeSquared@p4

x = 3.;

(*note that x is not inserted into structures with HoldAll*)
p1
p2
p3
p4

(*consequently, you cannot do the following successfully with \
Assocation and hperson*)
getAgeSquared@p1
getAgeSquared@p2
getAgeSquared@p3
getAgeSquared@p4

The output is

person[age->x]
{age->x}
<|age->x|>
hperson[age->x]

getAgeSquared[person[age->x]]
getAgeSquared[{age->x}]
getAgeSquared[<|age->x|>]
getAgeSquared[hperson[age->x]]

person[age->3.]
{age->3.}
<|age->x|>
hperson[age->x]

9.
9.
getAgeSquared[<|age->x|>]
getAgeSquared[hperson[age->x]]

Example confusion

Using Associations and Pattern matching in numerical functions possibly broken

$\endgroup$
1
  • 4
    $\begingroup$ I must note that this answer is written in a clumsy way and even to me it is almost impossible to follow your thought (despite the fact that I know in principle what you want to say). I would recommend to rewrite it from the scratch or delete. $\endgroup$ Jul 4 '16 at 1:47
2
$\begingroup$

Assocation component access [] vs [[]]

With MMA we spend a lot of time manipulating lists where access to components is done by [[index]], this can make us forget that when using Association keys, the syntax is [key].

If keys are integers this can be a source a bug:

a = <|0 -> "A", 1 -> "B", 2 -> "C", 3 -> "D"|>

a[[2]]

Out: = "B"

a[2]

Out: "C"

If you want to use Part to access associations with arbitrary keys, you need the wrapper Key:

a[[Key[2]]]

Out[]= "C"

This can be used to access multiple keys as well:

a[[{Key[2], Key[3]}]]    

Out[]= <|2 -> "C", 3 -> "D"|>
$\endgroup$
1
2

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.