Skip to content
AgileLogics
7 min read

Rules and Replacement

Prerequisites: Patterns

A rule lhs -> rhs says "replace lhs with rhs". /. (ReplaceAll) applies rules everywhere in an expression.

x^2 + y /. x -> 3
x + y /. {x -> 1, y -> 2}
{a, b, c} /. b -> z
{f[1], g[2], f[3]} /. f[n_] -> n^2
{1, 2, 3} /. List -> Plus
9 + y
3
{a, z, c}
{1, g[2], 9}
6

Rules work on any part of an expression — even heads: the last line turns List[1, 2, 3] into Plus[1, 2, 3].

Using results from Solve

Solve returns rules, so /. extracts the values:

sol = Solve[x^2 == 4, x]
x /. sol
x^3 + 1 /. sol
{{x -> -2}, {x -> 2}}
{-2, 2}
{-7, 9}

-> versus :>

  • lhs -> rhs (Rule) evaluates rhs once, when the rule is made.
  • lhs :> rhs (RuleDelayed) evaluates rhs each time it's used.
i = 0;
{a, a, a} /. a -> ++i
i = 0;
{a, a, a} /. a :> ++i
{1, 1, 1}
{1, 2, 3}

Use :> when the right side uses pattern variables that must not be evaluated early, or does something each time.

Replacing repeatedly

//. (ReplaceRepeated) keeps applying rules until nothing changes:

x /. {x -> y, y -> z}
x //. {x -> y, y -> z}
Log[a b c] //. Log[p_ q_] :> Log[p] + Log[q]
y
z
Log[a] + Log[b] + Log[c]

With /., each part is replaced at most once. //. is how you build small rewrite systems — this is the idea behind much of the language's own symbolic engine.

Other replacement functions

ReplacePart[{a, b, c}, 2 -> x]
Replace[f[1], f[n_] :> n + 1]
"b" /. {"a" -> 1, "b" -> 2}
{a, x, c}
2
2
  • ReplacePart replaces by position.
  • Replace only tries the whole expression, not its parts.
  • A list of rules works as a simple lookup table (associations, later in this level, are better for that).

Common mistakes

  • Expecting /. to change a variable: expr /. x -> 3 returns a new expression; expr itself is unchanged.

Practice

Given data = {{"a", 1}, {"b", -2}, {"c", 3}}, use a rule with a condition to replace every negative number with 0.

Show solution
data = {{"a", 1}, {"b", -2}, {"c", 3}};
data /. n_?Negative -> 0
{{a, 1}, {b, 0}, {c, 3}}