---
title: "TagSetDelayed"
language: "en"
type: "Symbol"
summary: "f /: lhs := rhs assigns rhs to be the delayed value of lhs, and associates the assignment with the symbol f."
keywords: 
- associating values
- setting values
- generic programming
- type based programming
- object programming
canonical_url: "https://reference.wolfram.com/language/ref/TagSetDelayed.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Assignments"
    link: "https://reference.wolfram.com/language/guide/Assignments.en.md"
related_functions: 
  - 
    title: "TagSet"
    link: "https://reference.wolfram.com/language/ref/TagSet.en.md"
  - 
    title: "SetDelayed"
    link: "https://reference.wolfram.com/language/ref/SetDelayed.en.md"
  - 
    title: "UpSetDelayed"
    link: "https://reference.wolfram.com/language/ref/UpSetDelayed.en.md"
  - 
    title: "UpValues"
    link: "https://reference.wolfram.com/language/ref/UpValues.en.md"
  - 
    title: "DownValues"
    link: "https://reference.wolfram.com/language/ref/DownValues.en.md"
  - 
    title: "SubValues"
    link: "https://reference.wolfram.com/language/ref/SubValues.en.md"
  - 
    title: "TagUnset"
    link: "https://reference.wolfram.com/language/ref/TagUnset.en.md"
related_tutorials: 
  - 
    title: "Associating Definitions with Different Symbols"
    link: "https://reference.wolfram.com/language/tutorial/TransformationRulesAndDefinitions.en.md#6972"
---
# TagSetDelayed (/: :=)

f/:lhs := rhs assigns rhs to be the delayed value of lhs, and associates the assignment with the symbol f.

## Details

* ``TagSetDelayed`` defines upvalues, downvalues or subvalues as appropriate.

* The symbol ``f`` in ``f/:lhs := rhs`` must appear in ``lhs`` as the head of ``lhs``, the head of the head, one of the elements of ``lhs`` or the head of one of the elements.

* A common case is ``f/:h[f[args]] := rhs``.

* You can see all the rules associated with a particular symbol by typing `` ? symbol``.

* If ``f`` appears several times in ``lhs``, then ``f/:lhs := rhs`` associates the assignment with each occurrence.

* When it appears in unevaluated symbolic form, ``TagSetDelayed`` is treated as a scoping construct so that variables in nested occurrences are renamed if necessary.

---

## Examples (16)

### Basic Examples (1)

```wl
In[1]:= g/:f[g[x_]] := fg[x]

In[2]:= {f[g[2]], f[h[2]]}

Out[2]= {fg[2], f[h[2]]}
```

### Scope (7)

#### Left-Hand Sides (4)

An expression with a delayed definition is evaluated every time it is used:

```wl
In[1]:= int/:rand[int] := RandomInteger[]

In[2]:= Table[rand[int], {5}]

Out[2]= {1, 0, 0, 1, 1}
```

---

Make definitions for special and general cases using immediate and delayed assignments:

```wl
In[1]:=
h/:f[h[0]] = h0;
h/:f[h[x_]] := 2f[h[x - 1]]

In[2]:= f[h[10]]

Out[2]= 1024 h0
```

---

The tag can appear as an argument of the left side:

```wl
In[1]:= sq/:area[sq, s_] := s ^ 2

In[2]:= area[sq, 2]

Out[2]= 4
```

---

The tag can appear as the head of an argument of the left side:

```wl
In[1]:= sq/:area[sq[s_]] := s ^ 2

In[2]:= area[sq[3]]

Out[2]= 9
```

#### Different Kinds of Values (3)

For ownvalues, the tag is redundant:

```wl
In[1]:=
x/:x := RandomReal[]
y := RandomReal[]

In[2]:= {OwnValues[x], OwnValues[y]}

Out[2]= {{HoldPattern[x] :> RandomReal[]}, {HoldPattern[y] :> RandomReal[]}}
```

---

For downvalues, the tag is redundant:

```wl
In[1]:=
f/:f[x_] := x ^ 2;
g[x_] := x ^ 2

In[2]:= {DownValues[f], DownValues[g]}

Out[2]= {{HoldPattern[f[x_]] :> x^2}, {HoldPattern[g[x_]] :> x^2}}
```

---

Use a tag to define upvalues:

```wl
In[1]:=
g/:f[g[x_]] := f1[x]
f[h[x_]] := f2[x]

In[2]:= {UpValues[g], DownValues[f]}

Out[2]= {{HoldPattern[f[g[x_]]] :> f1[x]}, {HoldPattern[f[h[x_]]] :> f2[x]}}
```

### Applications (1)

Implement modular arithmetic:

```wl
In[1]:=
mod/:mod[a_, p_] + mod[b_, p_] := mod[Mod[a + b, p], p]
mod/:i_Integer mod[a_, p_] := mod[Mod[i a, p], p]

In[2]:= mod[2, 5] + 3 mod[3, 5] - mod[1, 5]

Out[2]= mod[0, 5]
```

### Properties & Relations (7)

`` ^:= `` defines upvalues in the same way as using a tag does:

```wl
In[1]:= g/:f[g[x_]] := f1[x]

In[2]:= f[h[x_]] ^:= f2[x]

In[3]:= {UpValues[g], UpValues[h]}

Out[3]= {{HoldPattern[f[g[x_]]] :> f1[x]}, {HoldPattern[f[h[x_]]] :> f2[x]}}
```

---

A tag defines only one upvalue; `` ^:= `` makes definitions for all symbols:

```wl
In[1]:= g/:f1[g[x_], h[y_]] := gh[x y]

In[2]:= f2[g[x_], h[y_]] ^:= gh[x y]

In[3]:= {UpValues[g], UpValues[h]}

Out[3]= {{HoldPattern[f1[g[x_], h[y_]]] :> gh[x y], HoldPattern[f2[g[x_], h[y_]]] :> gh[x y]}, {HoldPattern[f2[g[x_], h[y_]]] :> gh[x y]}}
```

---

The right side of an immediate definition is evaluated when the definition is made:

```wl
In[1]:= int/:rand[int] = RandomInteger[];

In[2]:= {rand[int], rand[int]}

Out[2]= {0, 0}
```

The right side of a delayed definition is evaluated each time the definition is used:

```wl
In[3]:= real/:rand[real] := RandomReal[]

In[4]:= {rand[real], rand[real]}

Out[4]= {0.631583, 0.929159}
```

---

Definitions with the same left side overwrite earlier ones:

```wl
In[1]:= h/:f[h[x_]] := f1[x]

In[2]:= h/:f[h[x_]] := f2[x]

In[3]:= Definition[h]

Out[3]= f[h[x_]] ^:= f2[x]
```

---

``Definition`` prints definitions associated with a symbol:

```wl
In[1]:= mod/:a_mod + b_mod := modPlus[a, b]

In[2]:= Definition[mod]

Out[2]= a_mod + b_mod ^:= modPlus[a, b]
```

``Information`` prints various information about a symbol, including any definitions:

```wl
In[3]:= ? mod

Cell$$4531`mod

a_mod + b_mod ^:= modPlus[a, b]
```

``UpValues`` returns a list of rules corresponding to any upvalues defined:

```wl
In[4]:= UpValues[mod]

Out[4]= {HoldPattern[a_mod + b_mod] :> modPlus[a, b]}
```

---

Use ``=.`` to clear definitions with a particular left-hand side:

```wl
In[1]:=
h/:f[h[x_]] := f1[x];
h/:g[h[x_]] := g1[x];

In[2]:= h/:f[h[x_]]=.

In[3]:= {f[h[1]], g[h[1]]}

Out[3]= {f[h[1]], g1[1]}
```

Clear all definitions:

```wl
In[4]:= Clear[h]

In[5]:= Definition[h]

Out[5]= 
```

---

Delayed assignment introduces a scope that is not affected by global variables:

```wl
In[1]:= x = 5;

In[2]:= h/:f[h[x_]] := x ^ 2

In[3]:= {f[h[2]], x}

Out[3]= {4, 5}
```

Immediate assignment does not introduce a scope:

```wl
In[4]:= h/:g[h[x_]] = x ^ 2;

In[5]:= {g[h[2]], x}

Out[5]= {25, 5}
```

## See Also

* [`TagSet`](https://reference.wolfram.com/language/ref/TagSet.en.md)
* [`SetDelayed`](https://reference.wolfram.com/language/ref/SetDelayed.en.md)
* [`UpSetDelayed`](https://reference.wolfram.com/language/ref/UpSetDelayed.en.md)
* [`UpValues`](https://reference.wolfram.com/language/ref/UpValues.en.md)
* [`DownValues`](https://reference.wolfram.com/language/ref/DownValues.en.md)
* [`SubValues`](https://reference.wolfram.com/language/ref/SubValues.en.md)
* [`TagUnset`](https://reference.wolfram.com/language/ref/TagUnset.en.md)

## Tech Notes

* [Associating Definitions with Different Symbols](https://reference.wolfram.com/language/tutorial/TransformationRulesAndDefinitions.en.md#6972)

## Related Guides

* [`Assignments`](https://reference.wolfram.com/language/guide/Assignments.en.md)

## History

* Introduced in 1988 (1.0)