4 ms·
Sometimes the way I explain Mathematica to people is that, where Perl is the Perl of string rewriting, Mathematica is the Perl of tree rewriting. Some comments
by kmill 6y ago
Sometimes the way I explain Mathematica to people is that, where Perl is the Perl of string rewriting, Mathematica is the Perl of tree rewriting.
Some comments about the article:
Mathematica has two types of rules, Rule and RuleDelayed, given by a -> b and a :> b. You usually use RuleDelayed unless you want Mathematica to pre-evaluate b. For example, if you create a rule like x_ -> (Print[x]; 1 + x) it will immediately print the symbol x and then result in the rule x_ -> 1 + x, but x_ :> (Print[x]; x + 1) instead evaluates to itself without that side effect.
It might be worth knowing that $Assumptions has a dynamic scope construct (like fluid-let in scheme), where Assuming[a > 0, ...] will temporarily append a > 0 to $Assumptions.
The code for Diff is not correct, since it has patterns on the right-hand side of the rules (and also it's Power, not Pow). For idiomatic Mathematica, you would attach these rules to the Diff symbol itself as "DownValues" so that Mathematica will automatically apply them:
Diff[f_ g_, x_] := f Diff[g, x] + g Diff[f, x];
Diff[f_ + g_, x_] := Diff[f, x] + Diff[g, x];
Diff[Power[x_, n_Integer], x_] := n*Power[x, n - 1];
Diff[n_?NumericQ, x_] := 0;
These := operators append a rule to DownValues[Diff], where the rule is exactly from replacing := with :>.
In[14]:= DownValues[Diff]
Out[14]= {HoldPattern[Diff[f_ g_, x_]] :> f Diff[g, x] + g Diff[f, x],
HoldPattern[Diff[f_ + g_, x_]] :> Diff[f, x] + Diff[g, x],
HoldPattern[Diff[x_^n_Integer, x_]] :> n x^(n - 1),
HoldPattern[Diff[n_?NumericQ, x_]] :> 0}
The HoldPatterns in here are to prevent Mathematica from evaluating the patterns, since Diff has all these rules that really want to activate for those left-hand sides. (Yes, patterns, too, are subject to evaluation. It can be helpful in very limited circumstances, like metaprogramming the rules.)
It looks like it's still missing some rules, though:
In[42]:= Diff[x^2 + 2 x + 1, x]
Out[42]= 2 x + 2 Diff[x, x]
One fix is to change the power rule to
Diff[Power[x_, n_Integer: 1], x_] := n*Power[x, n - 1]
which gives n the default value of 1, plugging into a system where Mathematica knows x^1 and x are the same.
---
Something I use Mathematica for is calculations in things like the Temperley-Lieb algebra (for calculating the Jones polynomial of knots). The Temperley-Lieb algebra is pretty much a calculus of path composition, but you also take formal linear combinations of these, and closed loops evaluate to some polynomial. In the following, P[1, 2] would denote a path between points 1 and 2.
SetAttributes[P, Orderless];
P /: P[a_, b_] P[b_, c_] := P[a, c];
P /: P[a_, b_]^2 := P[a, a];
P /: P[a_, a_] := -A^2 - A^-2;
For example, P[1, 2] P[2, 3] P[3, 1] evaluates to -A^2 - A^-2. (I have a library for these things where the "boxes" it renders to in the Mathematica notebook is a graphical representation of the paths. The graphical paths are the expressions, which has been very helpful to me.)
- 7thaccount 6y agoSometimes I think people don't fully understand how cool the term rewriting is in Mathematica where it continuously expands on anything from text to functions to images and audio...it's pretty neat.