Products
  • Wolfram|One

    The definitive Wolfram Language and notebook experience

  • Mathematica

    The original technical computing environment

  • System Modeler

    Multidomain modeling and simulation of complex systems

  • Compute ServicesUse with Mathematica and Wolfram|One
  • AI AccessUse with Mathematica and Wolfram|One
  • Finance Platform
  • Wolfram|Alpha Notebook Edition
  • Application Server
  • Enterprise Private Cloud
  • Wolfram Engine
  • Wolfram Player
  • Wolfram Cloud App
  • Wolfram Player App

More mobile apps

Wolfram|Alpha

  • Wolfram|Alpha Website
  • Wolfram|Alpha APIs

AI Products

  • Wolfram AI Ecosystem
  • Wolfram Foundation Tool
  • Wolfram Cloud MCP
  • Wolfram Local MCP
  • Agent One API
  • CAG Component APIs

Core Technologies of Wolfram Products

  • Wolfram Language
  • Computable Data
  • Wolfram Notebooks
  • Linguistic Understanding

Additional Deployment Options

  • Wolfram Cloud
  • Wolfram Web Engine
  • wolframscript
  • WSTPServer
  • Group & Organizational Licensing
  • All Products
Consulting & Solutions

We deliver solutions for the AI era—combining symbolic computation, data-driven insights and deep technical expertise

Wolfram Consulting

Data Science, Finance & Business

  • Artificial Intelligence
  • Data Science
  • Healthcare
  • Real Estate

Engineering

  • Civil Engineering
  • Automotive Engineering
  • Sustainable Energy

Science & Technology

  • AgTech
  • Biosciences
  • Environmental Science
  • Food Science
  • Quantum Computation
  • Social and Behavioral Sciences

More Wolfram Solutions

Technology for Education

  • Research Universities
  • Colleges & Teaching Universities
  • High Schools
  • Resources for Students

Education Initiatives

  • Next-Gen EdTech
  • Computer-Based Math

More Solutions for Education

  • Contact Us
Learning & Support

Get Started

  • Wolfram Language Introduction
  • Fast Intro for Programmers
  • Fast Intro for Math Students
  • Wolfram Language Documentation

More Learning

  • Highlighted Core Areas
  • Demonstrations
  • YouTube
  • Daily Study Groups
  • Wolfram Schools and Programs
  • Books

Grow Your Skills

  • Wolfram U

    Courses in computing, science, life and more

  • Community

    Learn, solve problems and share ideas.

  • Blog

    News, views and insights from Wolfram

  • Resources for

    Software Developers

Tech Support

  • Contact Us
  • Support FAQs
  • Support FAQs
  • Contact Us
Company
  • About Wolfram
  • Career Center
  • All Sites & Resources
  • Connect & Follow
  • Contact Us

Work with Us

  • Student Ambassador Initiative
  • Wolfram for Startups
  • Student Opportunities
  • Jobs Using Wolfram Language

Educational Programs for Adults

  • Summer School
  • Winter School

Educational Programs for Youth

  • Middle School Camp
  • High School Research Program
  • Computational Adventures

Read

  • Stephen Wolfram's Writings
  • Wolfram Blog
  • Wolfram Tech | Books
  • Wolfram Media
  • Complex Systems

Educational Resources

  • Wolfram MathWorld
  • Wolfram in STEM
  • Wolfram Challenges
  • Wolfram Problem Generator

Wolfram Initiatives

  • Wolfram Science
  • Wolfram Foundation
  • History of Mathematics Project

Events

  • Stephen Wolfram Livestreams
  • Online & In-Person Events
  • Contact Us
  • Connect & Follow
For AIs
  • Your Account
  • User Portal
  • Wolfram Cloud
  • Products
    • Wolfram|One
    • Mathematica
    • System Modeler
    • Compute ServicesUse with Mathematica and Wolfram|One
    • AI AccessUse with Mathematica and Wolfram|One
    • Finance Platform
    • Wolfram|Alpha Notebook Edition
    • Application Server
    • Enterprise Private Cloud
    • Wolfram Engine
    • Wolfram Player
    • Wolfram Cloud App
    • Wolfram Player App

    More mobile apps

    • Wolfram|Alpha
      • Wolfram|Alpha Website
      • Wolfram|Alpha APIs
    • AI Products
      • Wolfram AI Ecosystem
      • Wolfram Foundation Tool
      • Wolfram Cloud MCP
      • Wolfram Local MCP
      • Agent One API
      • CAG Component APIs
    • Core Technologies
      • Wolfram Language
      • Computable Data
      • Wolfram Notebooks
      • Linguistic Understanding
    • Additional Deployment Options
      • Wolfram Cloud
      • Wolfram Web Engine
      • wolframscript
      • WSTPServer
    • Group & Organizational Licensing
    • All Products
  • Consulting & Solutions
    • Wolfram Consulting

    Data Science, Finance & Business

    • Artificial Intelligence
    • Data Science
    • Healthcare
    • Real Estate

    Engineering

    • Civil Engineering
    • Automotive Engineering
    • Sustainable Energy

    Science & Technology

    • AgTech
    • Biosciences
    • Environmental Science
    • Food Science
    • Quantum Computation
    • Social and Behavioral Sciences

    More Wolfram Solutions

    Technology for Education

    • Research Universities
    • Colleges & Teaching Universities
    • High Schools
    • Resources for Students

    Education Initiatives

    • Next-Gen EdTech
    • Computer-Based Math

    More Solutions for Education

    • Contact Us
  • Learning & Support

    Get Started

    • Wolfram Language Introduction
    • Fast Intro for Programmers
    • Fast Intro for Math Students
    • Wolfram Language Documentation

    Grow Your Skills

    • Wolfram U

      Courses in computing, science, life and more

    • Community

      Learn, solve problems and share ideas.

    • Blog

      News, views and insights from Wolfram

    • Resources for

      Software Developers
    • Tech Support
      • Contact Us
      • Support FAQs
    • More Learning
      • Highlighted Core Areas
      • Demonstrations
      • YouTube
      • Daily Study Groups
      • Wolfram Schools and Programs
      • Books
    • Support FAQs
    • Contact Us
  • Company
    • About Wolfram
    • Career Center
    • All Sites & Resources
    • Connect & Follow
    • Contact Us

    Work with Us

    • Student Ambassador Initiative
    • Wolfram for Startups
    • Student Opportunities
    • Jobs Using Wolfram Language

    Educational Programs for Adults

    • Summer School
    • Winter School

    Educational Programs for Youth

    • Middle School Camp
    • High School Research Program
    • Computational Adventures

    Read

    • Stephen Wolfram's Writings
    • Wolfram Blog
    • Wolfram Tech | Books
    • Wolfram Media
    • Complex Systems
    • Educational Resources
      • Wolfram MathWorld
      • Wolfram in STEM
      • Wolfram Challenges
      • Wolfram Problem Generator
    • Wolfram Initiatives
      • Wolfram Science
      • Wolfram Foundation
      • History of Mathematics Project
    • Events
      • Stephen Wolfram Livestreams
      • Online & In-Person Events
    • Contact Us
    • Connect & Follow
  • For AIs
  • Wolfram Cloud
  • Your Account
  • User Portal
Wolfram Language & System Documentation Center
Transformation Rules and Definitions
TECH NOTE

Transformation Rules and Definitions

Applying Transformation RulesImmediate and Delayed Definitions
Manipulating Sets of Transformation RulesFunctions That Remember Values They Have Found
Making DefinitionsAssociating Definitions with Different Symbols
Special Forms of AssignmentDefining Numerical Values
Making Definitions for Indexed ObjectsModifying Built‐in Functions
Making Definitions for FunctionsManipulating Value Lists
The Ordering of Definitions
Applying Transformation Rules
expr/.lhs->rhs
apply a transformation rule to expr
expr/.{lhs1->rhs1,lhs2->rhs2,…}
try a sequence of rules on each part of expr
Applying transformation rules.
The replacement operator /. (pronounced "slash‐dot") applies rules to expressions:
Wolfram Language code: x + y /. x -> 3
You can give a list of rules to apply. Each rule will be tried once on each part of the expression:
Wolfram Language code: x + y /. {x -> a, y -> b}
expr/.{rules1,rules2,…}
give a list of the results from applying each of the rulesi to expr
Applying lists of transformation rules.
If you give a list of lists of rules, you get a list of results:
Wolfram Language code: x + y /. {{x -> 1, y -> 2}, {x -> 4, y -> 2}}
Functions such as Solve and NSolve return lists whose elements are lists of rules, each representing a solution:
Wolfram Language code: Solve[x ^ 3 - 5x ^ 2 + 2x + 8 == 0, x]
When you apply these rules, you get a list of results, one corresponding to each solution:
Wolfram Language code: x ^ 2 + 6 /. %
When you use expr/.rules, each rule is tried in turn on each part of expr. As soon as a rule applies, the appropriate transformation is made, and the resulting part is returned.
The rule for x^3 is tried first; if it does not apply, the rule for x^n_ is used:
Wolfram Language code: {x ^ 2, x ^ 3, x ^ 4} /. {x ^ 3 -> u, x ^ n_ -> p[n]}
A result is returned as soon as the rule has been applied, so the inner instance of h is not replaced:
Wolfram Language code: h[x + h[y]] /. h[u_] -> u ^ 2
The replacement expr/.rules tries each rule just once on each part of expr.
Since each rule is tried just once, this serves to swap x and y:
Wolfram Language code: {x ^ 2, y ^ 3} /. {x -> y, y -> x}
You can use this notation to apply one set of rules, followed by another:
Wolfram Language code: x ^ 2 /. x -> (1 + y) /. y -> b
Sometimes you may need to go on applying rules over and over again, until the expression you are working on no longer changes. You can do this using the repeated replacement operation expr//.rules (or ReplaceRepeated[expr,rules]).
expr/.rules
try rules once on each part of expr
expr//.rules
try rules repeatedly until the result no longer changes
Single and repeated rule application.
With the single replacement operator /. each rule is tried only once on each part of the expression:
Wolfram Language code: x ^ 2 + y ^ 6 /. {x -> 2 + a, a -> 3}
With the repeated replacement operator //. the rules are tried repeatedly until the expression no longer changes:
Wolfram Language code: x ^ 2 + y ^ 6 //. {x -> 2 + a, a -> 3}
Here the rule is applied only once:
Wolfram Language code: log[a b c d] /. log[x_ y_] -> log[x] + log[y]
With the repeated replacement operator, the rule is applied repeatedly, until the result no longer changes:
Wolfram Language code: log[a b c d] //. log[x_ y_] -> log[x] + log[y]
When you use //. (pronounced "slash‐slash‐dot"), the Wolfram Language repeatedly passes through your expression, trying each of the rules given. It goes on doing this until it gets the same result on two successive passes.
If you give a set of rules that is circular, then //. can keep on getting different results forever. In practice, the maximum number of passes that //. makes on a particular expression is determined by the setting for the option MaxIterations. If you want to keep going for as long as possible, you can use ReplaceRepeated[expr,rules,MaxIterations->Infinity]. You can always stop by explicitly interrupting the Wolfram Language.
By setting the option MaxIterations, you can explicitly tell ReplaceRepeated how many times to try the rules you give:
Wolfram Language code: ReplaceRepeated[x, x -> x + 1, MaxIterations -> 1000]
The replacement operators /. and //. share the feature that they try each rule on every subpart of your expression. On the other hand, Replace[expr,rules] tries the rules only on the whole of expr, and not on any of its subparts.
You can use Replace, together with functions like Map and MapAt, to control exactly which parts of an expression a replacement is applied to. Remember that you can use the function ReplacePart[expr,new,pos] to replace part of an expression with a specific object.
The operator /. applies rules to all subparts of an expression:
Wolfram Language code: x ^ 2 /. x -> a
Without a level specification, Replace applies rules only to the whole expression:
Wolfram Language code: Replace[x ^ 2, x ^ 2 -> b]
No replacement is done here:
Wolfram Language code: Replace[x ^ 2, x -> a]
This applies rules down to level 2, and so replaces x:
Wolfram Language code: Replace[x ^ 2, x -> a, 2]
expr/.rules
apply rules to all subparts of expr
Replace[expr,rules]
apply rules to the whole of expr only
Replace[expr,rules,levspec]
apply rules to parts of expr on levels specified by levspec
Applying rules to whole expressions.
Replace returns the result from using the first rule that applies:
Wolfram Language code: Replace[f[u], {f[x_] -> x ^ 2, f[x_] -> x ^ 3}]
ReplaceList gives a list of the results from every rule that applies:
Wolfram Language code: ReplaceList[f[u], {f[x_] -> x ^ 2, f[x_] -> x ^ 3}]
If a single rule can be applied in several ways, ReplaceList gives a list of all the results:
Wolfram Language code: ReplaceList[a + b + c, x_ + y_ -> g[x, y]]
This gives a list of ways of breaking the original list in two:
Wolfram Language code: ReplaceList[{a, b, c, d}, {x__, y__} -> g[{x}, {y}]]
This finds all sublists that are flanked by the same element:
Wolfram Language code: ReplaceList[{a, b, c, a, d, b, d}, {___, x_, y__, x_, ___} -> g[x, {y}]]
Replace[expr,rules]
apply rules in one way only
ReplaceList[expr,rules]
apply rules in all possible ways
Applying rules in one way or all possible ways.
Manipulating Sets of Transformation Rules
You can manipulate lists of transformation rules in the Wolfram Language just like other symbolic expressions. It is common to assign a name to a rule or set of rules.
This assigns the "name" sinexp to the trigonometric expansion rule:
Wolfram Language code: sinexp = Sin[2 x_] -> 2 Sin[x] Cos[x]
You can now request the rule "by name":
Wolfram Language code: Sin[2 (1 + x) ^ 2] /. sinexp
You can use lists of rules to represent mathematical and other relations. Typically you will find it convenient to give names to the lists, so that you can easily specify the list you want in a particular case.
In most situations, it is only one rule from any given list that actually applies to a particular expression. Nevertheless, the /. operator tests each of the rules in the list in turn. If the list is very long, this process can take a long time.
The Wolfram Language allows you to preprocess lists of rules so that /. can operate more quickly on them. You can take any list of rules and apply the function Dispatch to them. The result is a representation of the original list of rules, but including dispatch tables which allow /. to "dispatch" to potentially applicable rules immediately, rather than testing all the rules in turn.
Here is a list of rules for the first five factorials:
Wolfram Language code: facs = Table[f[i] -> i!, {i, 5}]
This sets up dispatch tables that make the rules faster to use:
Wolfram Language code: dfacs = Dispatch[facs]
You can apply the rules using the /. operator:
Wolfram Language code: f[4] /. dfacs
Dispatch[rules]
create a representation of a list of rules that includes dispatch tables
expr/.drules
apply rules that include dispatch tables
Creating and using dispatch tables.
For long lists of rules, you will find that setting up dispatch tables makes replacement operations much faster. This is particularly true when your rules are for individual symbols or other expressions that do not involve pattern objects. Once you have built dispatch tables in such cases, you will find that the /. operator takes a time that is more or less independent of the number of rules you have. Without dispatch tables, however, /. will take a time directly proportional to the total number of rules.
Making Definitions
The replacement operator /. allows you to apply transformation rules to a specific expression. Often, however, you want to have transformation rules automatically applied whenever possible.
You can do this by assigning explicit values to Wolfram Language expressions and patterns. Each assignment specifies a transformation rule to be applied whenever an expression of the appropriate form occurs.
expr/.lhs->rhs
apply a transformation rule to a specific expression
lhs=rhs
assign a value which defines a transformation rule to be used whenever possible
Manual and automatic application of transformation rules.
This applies a transformation rule for x to a specific expression:
Wolfram Language code: (1 + x) ^ 6 /. x -> 3 - a
By assigning a value to x, you tell the Wolfram Language to apply a transformation rule for x whenever possible:
Wolfram Language code: x = 3 - a
Now x is transformed automatically:
Wolfram Language code: (1 + x) ^ 7
You should realize that except inside constructs like Module and Block, all assignments you make in a Wolfram Language session are permanent. They continue to be used for the duration of the session, unless you explicitly clear or overwrite them.
The fact that assignments are permanent means that they must be made with care. Probably the single most common mistake in using the Wolfram Language is to make an assignment for a variable like x at one point in your session, and then later to use x having forgotten about the assignment you made.
There are several ways to avoid this kind of mistake. First, you should avoid using assignments whenever possible, and instead use more controlled constructs such as the /. replacement operator. Second, you should explicitly use the deassignment operator =. or the function Clear to remove values you have assigned when you have finished with them.
Another important way to avoid mistakes is to think particularly carefully before assigning values to variables with common or simple names. You will often want to use a variable such as x as a symbolic parameter. But if you make an assignment such as x=3, then x will be replaced by 3 whenever it occurs, and you can no longer use x as a symbolic parameter.
In general, you should be sure not to assign permanent values to any variables that you might want to use for more than one purpose. If at one point in your session you wanted the variable c to stand for the speed of light, you might assign it a value such as 3.*10^8. But then you cannot use c later in your session to stand, say, for an undetermined coefficient. One way to avoid this kind of problem is to make assignments only for variables with more explicit names, such as SpeedOfLight.
x=.
remove the value assigned to the object x
Clear[x,y,…]
clear all the values of x, y, …
Removing assignments.
This does not give what you might expect, because x still has the value you assigned it above:
Wolfram Language code: Factor[x ^ 2 - 1]
This removes any value assigned to x:
Wolfram Language code: Clear[x]
Now this gives the result you expect:
Wolfram Language code: Factor[x ^ 2 - 1]
Special Forms of Assignment
Particularly when you write procedural programs in the Wolfram Language, you will often need to modify the value of a particular variable repeatedly. You can always do this by constructing the new value and explicitly performing an assignment such as x=value. The Wolfram Language, however, provides special notations for incrementing the values of variables, and for some other common cases.
i++
increment the value of i by 1
i--
decrement i
++i
pre‐increment i
--i
pre‐decrement i
i+=di
add di to the value of i
i-=di
subtract di from i
x*=c
multiply x by c
x/=c
divide x by c
Modifying values of variables.
This assigns the value 7x to the variable t:
Wolfram Language code: t = 7x
This increments the value of t by 18x:
Wolfram Language code: t += 18x
The value of t has been modified:
Wolfram Language code: t
This sets t to 8, multiplies its value by 7, then gives the final value of t:
Wolfram Language code: t = 8;t *= 7;t
The value of i++ is the value of i before the increment is done:
Wolfram Language code: i = 5;Print[i++];Print[i]
The value of ++i is the value of i after the increment:
Wolfram Language code: i = 5;Print[++i];Print[i]
x=y=value
assign the same value to both x and y
{x,y}={value1,value2}
assign different values to x and y
{x,y}={y,x}
interchange the values of x and y
Assigning values to several variables at a time.
This assigns the value 5 to x and 8 to y:
Wolfram Language code: {x, y} = {5, 8}
This interchanges the values of x and y:
Wolfram Language code: {x, y} = {y, x}
Now x has value 8:
Wolfram Language code: x
And y has value 5:
Wolfram Language code: y
You can use assignments to lists to permute values of variables in any way:
Wolfram Language code: {a, b, c} = {1, 2, 3};{b, a, c} = {a, c, b};{a, b, c}
When you write programs in the Wolfram Language, you will sometimes find it convenient to take a list, and successively add elements to it. You can do this using the functions PrependTo and AppendTo.
PrependTo[v,elem]
prepend elem to the value of v
AppendTo[v,elem]
append elem
v={v,elem}
make a nested list containing elem
Assignments for modifying lists.
This assigns the value of v to be the list {5,7,9}:
Wolfram Language code: v = {5, 7, 9}
This appends the element 11 to the value of v:
Wolfram Language code: AppendTo[v, 11]
Now the value of v has been modified:
Wolfram Language code: v
Although AppendTo[v,elem] is always equivalent to v=Append[v,elem], it is often a convenient notation. However, you should realize that because of the way the Wolfram System stores lists, it is usually less efficient to add a sequence of elements to a particular list than to create a nested structure that consists, for example, of lists of length 2 at each level. When you have built up such a structure, you can always reduce it to a single list using Flatten.
This sets up a nested list structure for w:
Wolfram Language code: w = {1};Do[w = {w, k ^ 2}, {k, 1, 4}];w
You can use Flatten to unravel the structure:
Wolfram Language code: Flatten[w]
Making Definitions for Indexed Objects
In many kinds of calculations, you need to set up "arrays" that contain sequences of expressions, each specified by a certain index. One way to implement arrays in the Wolfram Language is by using lists. You can define a list, say a={x,y,z,…}, then access its elements using a[[i]], or modify them using a[[i]]=value. This approach has a drawback, however, in that it requires you to fill in all the elements when you first create the list.
Often, it is more convenient to set up arrays in which you can fill in only those elements that you need at a particular time. You can do this by making definitions for expressions such as a[i].
This defines a value for a[1]:
Wolfram Language code: a[1] = 9
This defines a value for a[2]:
Wolfram Language code: a[2] = 7
This shows all the values you have defined for expressions associated with a so far:
Wolfram Language code: ? a
You can define a value for a[5], even though you have not yet given values to a[3] and a[4]:
Wolfram Language code: a[5] = 0
This generates a list of the values of the a[i]:
Wolfram Language code: Table[a[i], {i, 5}]
You can think of the expression a[i] as being like an "indexed" or "subscripted" variable.
a[i]=value
add or overwrite a value
a[i]
access a value
a[i]=.
remove a value
?a
show all defined values
Clear[a]
clear all defined values
Table[a[i],{i,1,n}]
or
Array[a,n]
convert to an explicit List
Manipulating indexed variables.
When you have an expression of the form a[i], there is no requirement that the "index" i be a number. In fact, the Wolfram Language allows the index to be any expression whatsoever. By using indices that are symbols, you can for example build up simple databases in the Wolfram Language.
This defines the "object" area with "index" square to have value 1:
Wolfram Language code: area[square] = 1
This adds another result to the area "database":
Wolfram Language code: area[triangle] = 1 / 2
Here are the entries in the area database so far:
Wolfram Language code: ? area
You can use these definitions wherever you want. You have not yet assigned a value for area[pentagon]:
Wolfram Language code: 4 area[square] + area[pentagon]
Making Definitions for Functions
"Defining Functions" discusses how you can define functions in the Wolfram Language. In a typical case, you would type in f[x_]=x^2 to define a function f. (Actually, the definitions in "Defining Functions" use the := operator, rather than the = one. "Immediate and Delayed Definitions" explains exactly when to use each of the := and = operators.)
The definition f[x_]=x^2 specifies that whenever the Wolfram Language encounters an expression that matches the pattern f[x_], it should replace the expression by x^2. Since the pattern f[x_] matches all expressions of the form f[anything], the definition applies to functions f with any "argument".
Function definitions like f[x_]=x^2 can be compared with definitions like f[a]=b for indexed variables discussed in "Making Definitions for Indexed Objects". The definition f[a]=b specifies that whenever the particular expression f[a] occurs, it is to be replaced by b. But the definition says nothing about expressions such as f[y], where f appears with another "index".
To define a "function", you need to specify values for expressions of the form f[x], where the argument x can be anything. You can do this by giving a definition for the pattern f[x_], where the pattern object x_ stands for any expression.
f[x]=value
definition for a specific expression x
f[x_]=value
definition for any expression, referred to as x
The difference between defining an indexed variable and a function.
Making definitions for f[2] or f[a] can be thought of as being like giving values to various elements of an "array" named f. Making a definition for f[x_] is like giving a value for a set of "array elements" with arbitrary "indices". In fact, you can actually think of any function as being like an array with an arbitrarily variable index.
In mathematical terms, you can think of f as a mapping. When you define values for, say, f[1] and f[2], you specify the image of this mapping for various discrete points in its domain. Defining a value for f[x_] specifies the image of f on a continuum of points.
This defines a transformation rule for the specific expression f[x]:
Wolfram Language code: f[x] = u
When the specific expression f[x] appears, it is replaced by u. Other expressions of the form f[argument] are, however, not modified:
Wolfram Language code: f[x] + f[y]
This defines a value for f with any expression as an "argument":
Wolfram Language code: f[x_] = x ^ 2
The old definition for the specific expression f[x] is still used, but the new general definition for f[x_] is now used to find a value for f[y]:
Wolfram Language code: f[x] + f[y]
This removes all definitions for f:
Wolfram Language code: Clear[f]
The Wolfram Language allows you to define transformation rules for any expression or pattern. You can mix definitions for specific expressions such as f[1] or f[a] with definitions for patterns such as f[x_].
Many kinds of mathematical functions can be set up by mixing specific and general definitions in the Wolfram Language. As an example, consider the factorial function. This particular function is in fact built into the Wolfram Language (it is written n!). But you can use Wolfram Language definitions to set up the function for yourself.
The standard mathematical definition for the factorial function can be entered almost directly into the Wolfram Language, in the form f[n_]:=n f[n-1];f[1]=1. This definition specifies that for any n, f[n] should be replaced by n f[n-1], except that when n is 1, f[1] should simply be replaced by 1.
Here is the value of the factorial function with argument 1:
Wolfram Language code: f[1] = 1
Here is the general recursion relation for the factorial function:
Wolfram Language code: f[n_] := n f[n - 1]
Now you can use these definitions to find values for the factorial function:
Wolfram Language code: f[10]
The results are the same as you get from the built‐in version of factorial:
Wolfram Language code: 10!
The Ordering of Definitions
When you make a sequence of definitions in the Wolfram System, some may be more general than others. The Wolfram System follows the principle of trying to put more general definitions after more specific ones. This means that special cases of rules are typically tried before more general cases.
This behavior is crucial to the factorial function example given in "Making Definitions for Functions". Regardless of the order in which you entered them, the Wolfram System will always put the rule for the special case f[1] ahead of the rule for the general case f[n_]. This means that when the Wolfram System looks for the value of an expression of the form f[n], it tries the special case f[1] first, and only if this does not apply, it tries the general case f[n_]. As a result, when you ask for f[5], the Wolfram System will keep on using the general rule until the "end condition" rule for f[1] applies.
■ The Wolfram System tries to put specific definitions before more general definitions.
Treatment of definitions in the Wolfram System.
If the Wolfram System did not follow the principle of putting special rules before more general ones, then the special rules would always be "shadowed" by more general ones. In the factorial example, if the rule for f[n_] was ahead of the rule for f[1], then even when the Wolfram System tried to evaluate f[1], it would use the general f[n_] rule, and it would never find the special f[1] rule.
Here is a general definition for f[n_]:
Wolfram Language code: f[n_] := n f[n - 1]
Here is a definition for the special case f[1]:
Wolfram Language code: f[1] = 1
The Wolfram System puts the special case before the general one:
Wolfram Language code: ? f
In the factorial function example used above, it is clear which rule is more general. Often, however, there is no definite ordering in generality of the rules you give. In such cases, the Wolfram System simply tries the rules in the order you give them.
These rules have no definite ordering in generality:
Wolfram Language code: log[x_ y_] := log[x] + log[y];log[x_ ^ n_] := n log[x]
The Wolfram System stores the rules in the order you gave them:
Wolfram Language code: ? log
This rule is a special case of the rule for log[x_y_]:
Wolfram Language code: log[2 x_] := log[x] + log2
The Wolfram System puts the special rule before the more general one:
Wolfram Language code: ? log
Although in many practical cases, the Wolfram System can recognize when one rule is more general than another, you should realize that this is not always possible. For example, if two rules both contain complicated /; conditions, it may not be possible to work out which is more general, and, in fact, there may not be a definite ordering. Whenever the appropriate ordering is not clear, the Wolfram System stores rules in the order you give them.
Immediate and Delayed Definitions
You may have noticed that there are two different ways to make assignments in the Wolfram Language: lhs=rhs and lhs:=rhs. The basic difference between these forms is when the expression rhs is evaluated. lhs=rhs is an immediate assignment, in which rhs is evaluated at the time when the assignment is made. lhs:=rhs, on the other hand, is a delayed assignment, in which rhs is not evaluated when the assignment is made, but is instead evaluated each time the value of lhs is requested.
lhs=rhs
(immediate assignment)
rhs is evaluated when the assignment is made
lhs:=rhs
(delayed assignment)
rhs is evaluated each time the value of lhs is requested
The two types of assignments in the Wolfram Language.
This uses the := operator to define the function ex:
Wolfram Language code: ex[x_] := Expand[(1 + x) ^ 2]
Because := was used, the definition is maintained in an unevaluated form:
Wolfram Language code: ? ex
When you make an assignment with the = operator, the right‐hand side is evaluated immediately:
Wolfram Language code: iex[x_] = Expand[(1 + x) ^ 2]
The definition now stored is the result of the Expand command:
Wolfram Language code: ? iex
When you execute ex, the Expand is performed:
Wolfram Language code: ex[y + 2]
iex simply substitutes its argument into the already expanded form, giving a different answer:
Wolfram Language code: iex[y + 2]
As you can see from the example above, both = and := can be useful in defining functions, but they have different meanings, and you must be careful about which one to use in a particular case.
One rule of thumb is the following. If you think of an assignment as giving the final "value" of an expression, use the = operator. If instead you think of the assignment as specifying a "command" for finding the value, use the := operator. If in doubt, it is usually better to use the := operator than the = one.
lhs=rhs
rhs is intended to be the "final value" of lhs (e.g. f[x_]=1-x^2)
lhs:=rhs
rhs gives a "command" or "program" to be executed whenever you ask for the value of lhs (e.g. f[x_]:=Expand[1-x^2])
Interpretations of assignments with the = and := operators.
Although := is probably used more often than = in defining functions, there is one important case in which you must use = to define a function. If you do a calculation, and get an answer in terms of a symbolic parameter , you often want to go on and find results for various specific values of . One way to do this is to use the /. operator to apply appropriate rules for in each case. It is usually more convenient, however, to use = to define a function whose argument is .
Here is an expression involving x:
Wolfram Language code: D[Log[Sin[x]] ^ 2, x]
This defines a function whose argument is the value to be taken for x:
Wolfram Language code: dlog[x_] = %
Here is the result when x is taken to be 1+a:
Wolfram Language code: dlog[1 + a]
An important point to notice in the example above is that there is nothing special about the name x that appears in the x_ pattern. It is just a symbol, indistinguishable from an x that appears in any other expression.
f[x_]=expr
define a function which gives the value expr for any particular value of x
Defining functions for evaluating expressions.
You can use = and := not only to define functions, but also to assign values to variables. If you type x=value, then value is immediately evaluated, and the result is assigned to x. On the other hand, if you type x:=value, then value is not immediately evaluated. Instead, it is maintained in an unevaluated form, and is evaluated afresh each time is used.
This evaluates RandomReal[] to find a pseudorandom number, then assigns this number to r1:
Wolfram Language code: r1 = RandomReal[]
Here RandomReal[] is maintained in an unevaluated form, to be evaluated afresh each time r2 is used:
Wolfram Language code: r2 := RandomReal[]
Here are values for r1 and r2:
Wolfram Language code: {r1, r2}
The value of r1 never changes. Every time r2 is used, however, a new pseudorandom number is generated:
Wolfram Language code: {r1, r2}
The distinction between immediate and delayed assignments is particularly important when you set up chains of assignments.
This defines a to be 1:
Wolfram Language code: a = 1
Here a+2 is evaluated to give 3, and the result is assigned to be the value of ri:
Wolfram Language code: ri = a + 2
Here a+2 is maintained in an unevaluated form, to be evaluated every time the value of rd is requested:
Wolfram Language code: rd := a + 2
In this case, ri and rd give the same values:
Wolfram Language code: {ri, rd}
Now the value of a is changed:
Wolfram Language code: a = 2
Now rd uses the new value for a, while ri keeps its original value:
Wolfram Language code: {ri, rd}
You can use delayed assignments such as t:=rhs to set up variables whose values you can find in a variety of different "environments". Every time you ask for t, the expression rhs is evaluated using the current values of the objects on which it depends.
The right‐hand side of the delayed assignment is maintained in an unevaluated form:
Wolfram Language code: t := {a, Factor[x ^ a - 1]}
This sets a to 4, then finds the value of t:
Wolfram Language code: a = 4;t
Here a is 6:
Wolfram Language code: a = 6;t
In the example above, the symbol a acts as a "global variable", whose value affects the value of t. When you have a large number of parameters, many of which change only occasionally, you may find this kind of setup convenient. However, you should realize that implicit or hidden dependence of one variable on others can often become quite confusing. When possible, you should make all dependencies explicit, by defining functions which take all necessary parameters as arguments.
lhs->rhs
rhs is evaluated when the rule is given
lhs:>rhs
rhs is evaluated when the rule is used
Two types of transformation rules in the Wolfram Language.
Just as you can make immediate and delayed assignments in the Wolfram Language, so you can also set up immediate and delayed transformation rules.
The right‐hand side of this rule is evaluated when you give the rule:
Wolfram Language code: f[x_] -> Expand[(1 + x) ^ 2]
A rule like this is probably not particularly useful:
Wolfram Language code: f[x_] -> Expand[x]
Here the right‐hand side of the rule is maintained in an unevaluated form, to be evaluated every time the rule is used:
Wolfram Language code: f[x_] :> Expand[x]
Applying the rule causes the expansion to be done:
Wolfram Language code: f[(1 + p) ^ 2] /. f[x_] :> Expand[x]
In analogy with assignments, you should typically use -> when you want to replace an expression with a definite value, and you should use :> when you want to give a command for finding the value.
Functions That Remember Values They Have Found
When you make a function definition using :=, the value of the function is recomputed every time you ask for it. In some kinds of calculations, you may end up asking for the same function value many times. You can save time in these cases by having the Wolfram Language remember all the function values it finds. Here is an "idiom" for defining a function that does this.
f[x_]:=f[x]=rhs
define a function which remembers values that it finds
Defining a function that remembers values it finds.
This defines a function f which stores all values that it finds:
Wolfram Language code: f[x_] := f[x] = f[x - 1] + f[x - 2]
Here are the end conditions for the recursive function f:
Wolfram Language code: f[0] = f[1] = 1
Here is the original definition of f:
Wolfram Language code: ? f
This computes f[5]. The computation involves finding the sequence of values f[5], f[4], … f[2]:
Wolfram Language code: f[5]
All the values of f found so far are explicitly stored:
Wolfram Language code: ? f
If you ask for f[5] again, the Wolfram Language can just look up the value immediately; it does not have to recompute it:
Wolfram Language code: f[5]
You can see how a definition like f[x_]:=f[x]=f[x-1]+f[x-2] works. The function f[x_] is defined to be the "program" f[x]=f[x-1]+f[x-2]. When you ask for a value of the function f, the "program" is executed. The program first calculates the value of f[x-1]+f[x-2], then saves the result as f[x].
It is often a good idea to use functions that remember values when you implement mathematical recursion relations in the Wolfram Language. In a typical case, a recursion relation gives the value of a function with an integer argument in terms of values of the same function with arguments , , etc. The Fibonacci function definition used above is an example of this kind of recursion relation. The point is that if you calculate say by just applying the recursion relation over and over again, you end up having to recalculate quantities like many times. In a case like this, it is therefore better just to remember the value of , and look it up when you need it, rather than having to recalculate it.
There is of course a trade‐off involved in remembering values. It is faster to find a particular value, but it takes more memory space to store all of them. You should usually define functions to remember values only if the total number of different values that will be produced is comparatively small, or the expense of recomputing them is very great.
Associating Definitions with Different Symbols
When you make a definition in the form f[args]=rhs or f[args]:=rhs, the Wolfram Language associates your definition with the object f. This means, for example, that such definitions are displayed when you type ?f. In general, definitions for expressions in which the symbol f appears as the head are termed downvalues of f.
The Wolfram Language however also supports upvalues, which allow definitions to be associated with symbols that do not appear directly as their head.
Consider for example a definition like Exp[g[x_]]:=rhs. One possibility is that this definition could be associated with the symbol Exp, and considered as a downvalue of Exp. This is however probably not the best thing either from the point of view of organization or efficiency.
Better is to consider Exp[g[x_]]:=rhs to be associated with g, and to correspond to an upvalue of g.
f[args]:=rhs
define a downvalue for f
f[g[args],…]^:=rhs
define an upvalue for g
Associating definitions with different symbols.
This is taken to define a downvalue for f:
Wolfram Language code: f[g[x_]] := fg[x]
You can see the definition when you ask about f:
Wolfram Language code: ? f
This defines an upvalue for g:
Wolfram Language code: Exp[g[x_]] ^:= expg[x]
The definition is associated with g:
Wolfram Language code: ? g
It is not associated with Exp:
Wolfram Language code: ??Exp
The definition is used to evaluate this expression:
Wolfram Language code: Exp[g[5]]
In simple cases, you will get the same answers to calculations whether you give a definition for f[g[x]] as a downvalue for f or an upvalue for g. However, one of the two choices is usually much more natural and efficient than the other.
A good rule of thumb is that a definition for f[g[x]] should be given as an upvalue for g in cases where the function f is more common than g. Thus, for example, in the case of Exp[g[x]], Exp is a built‐in Wolfram Language function, while g is presumably a function you have added. In such a case, you will typically think of definitions for Exp[g[x]] as giving relations satisfied by g. As a result, it is more natural to treat the definitions as upvalues for g than as downvalues for Exp.
This gives the definition as an upvalue for g:
Wolfram Language code: g/:g[x_] + g[y_] := gplus[x, y]
Here are the definitions for g so far:
Wolfram Language code: ? g
The definition for a sum of g’s is used whenever possible:
Wolfram Language code: g[5] + g[7]
Since the full form of the pattern g[x_]+g[y_] is Plus[g[x_],g[y_]], a definition for this pattern could be given as a downvalue for Plus. It is almost always better, however, to give the definition as an upvalue for g.
In general, whenever the Wolfram Language encounters a particular function, it tries all the definitions you have given for that function. If you had made the definition for g[x_]+g[y_] a downvalue for Plus, then the Wolfram Language would have tried this definition whenever Plus occurs. The definition would thus be tested every time the Wolfram Language added expressions together, making this very common operation slower in all cases.
However, by giving a definition for g[x_]+g[y_] as an upvalue for g, you associate the definition with g. In this case, the Wolfram Language only tries the definition when it finds a g inside a function such as Plus. Since g presumably occurs much less frequently than Plus, this is a much more efficient procedure.
f[g]^=value
or
f[g[args]]^=value
make assignments to be associated with g, rather than f
f[g]^:=value
or
f[g[args]]^:=value
make delayed assignments associated with g
f[arg1,arg2,…]^=value
make assignments associated with the heads of all the argi
Shorter ways to define upvalues.
A typical use of upvalues is in setting up a "database" of properties of a particular object. With upvalues, you can associate each definition you make with the object that it concerns, rather than with the property you are specifying.
This defines an upvalue for square which gives its area:
Wolfram Language code: area[square] ^= 1
This adds a definition for the perimeter:
Wolfram Language code: perimeter[square] ^= 4
Both definitions are now associated with the object square:
Wolfram Language code: ? square
In general, you can associate definitions for an expression with any symbol that occurs at a sufficiently high level in the expression. With an expression of the form f[args], you can define an upvalue for a symbol g so long as either g itself, or an object with head g, occurs in args. If g occurs at a lower level in an expression, however, you cannot associate definitions with it.
g occurs as the head of an argument, so you can associate a definition with it:
Wolfram Language code: g/:h[w[x_], g[y_]] := hwg[x, y]
Here g appears too deep in the left‐hand side for you to associate a definition with it:
Wolfram Language code: g/:h[w[g[x_]], y_] := hw[x, y]
f[…]:=rhs
downvalue for f
f/:f[g[…]][…]:=rhs
downvalue for f
g/:f[…,g,…]:=rhs
upvalue for g
g/:f[…,g[…],…]:=rhs
upvalue for g
Possible positions for symbols in definitions.
As discussed in "The Meaning of Expressions", you can use Wolfram Language symbols as "tags", to indicate the "type" of an expression. For example, complex numbers in the Wolfram Language are represented internally in the form Complex[x,y], where the symbol Complex serves as a tag to indicate that the object is a complex number.
Upvalues provide a convenient mechanism for specifying how operations act on objects that are tagged to have a certain type. For example, you might want to introduce a class of abstract mathematical objects of type quat. You can represent each object of this type by a Wolfram Language expression of the form quat[data].
In a typical case, you might want quat objects to have special properties with respect to arithmetic operations such as addition and multiplication. You can set up such properties by defining upvalues for quat with respect to Plus and Times.
This defines an upvalue for quat with respect to Plus:
Wolfram Language code: quat[x_] + quat[y_] ^:= quat[x + y]
The upvalue you have defined is used to simplify this expression:
Wolfram Language code: quat[a] + quat[b] + quat[c]
When you define an upvalue for quat with respect to an operation like Plus, what you are effectively doing is to extend the domain of the Plus operation to include quat objects. You are telling the Wolfram Language to use special rules for addition in the case where the things to be added together are quat objects.
In defining addition for quat objects, you could always have a special addition operation, say quatPlus, to which you assign an appropriate downvalue. It is usually much more convenient, however, to use the standard Wolfram Language Plus operation to represent addition, but then to "overload" this operation by specifying special behavior when quat objects are encountered.
You can think of upvalues as a way to implement certain aspects of object‐oriented programming. A symbol like quat represents a particular type of object. Then the various upvalues for quat specify "methods" that define how quat objects should behave under certain operations, or on receipt of certain "messages".
Defining Numerical Values
If you make a definition such as f[x_]:=value, the Wolfram Language will use the value you give for any f function it encounters. In some cases, however, you may want to define a value that is to be used specifically when you ask for numerical values.
expr=value
define a value to be used whenever possible
N[expr]=value
define a value to be used for numerical approximation
Defining ordinary and numerical values.
This defines a numerical value for the function f:
Wolfram Language code: N[f[x_]] := Sum[x ^ -i / i ^ 2, {i, 20}]
Defining the numerical value does not tell the Wolfram Language anything about the ordinary value of f:
Wolfram Language code: f[2] + f[5]
If you ask for a numerical approximation, however, the Wolfram Language uses the numerical values you have defined:
Wolfram Language code: N[%]
You can define numerical values for both functions and symbols. The numerical values are used by all numerical Wolfram Language functions, including NIntegrate, FindRoot, and so on.
N[expr]=value
define a numerical value to be used when default numerical precision is requested
N[expr,{n,Infinity}]=value
define a numerical value to be used when n‐digit precision and any accuracy is requested
Defining numerical values that depend on numerical precision.
This defines a numerical value for the symbol const, using 4n+5 terms in the product for n‐digit precision:
Wolfram Language code: N[const, {n_, Infinity}] := Product[1 - 2 ^ -i, {i, 2, 4n + 5}]
Here is the value of const, computed to 30‐digit precision using the value you specified:
Wolfram Language code: N[const, 30]
The Wolfram Language treats numerical values essentially like upvalues. When you define a numerical value for f, the Wolfram Language effectively enters your definition as an upvalue for f with respect to the numerical evaluation operation N.
Modifying Built‐in Functions
The Wolfram Language allows you to define transformation rules for any expression. You can define such rules not only for functions that you add to the Wolfram Language, but also for intrinsic functions that are already built into the Wolfram Language. As a result, you can enhance, or modify, the features of built‐in Wolfram Language functions.
This capability is powerful, but potentially dangerous. The Wolfram Language will always follow the rules you give it. This means that if the rules you give are incorrect, then the Wolfram Language will give you incorrect answers.
To avoid the possibility of changing built‐in functions by mistake, the Wolfram Language "protects" all built‐in functions from redefinition. If you want to give a definition for a built‐in function, you have to remove the protection first. After you give the definition, you should usually restore the protection, to prevent future mistakes.
Unprotect[f]
remove protection
Protect[f]
add protection
Protection for functions.
Built‐in functions are usually "protected", so you cannot redefine them:
Wolfram Language code: Log[7] = 2
This removes protection for Log:
Wolfram Language code: Unprotect[Log]
Now you can give your own definitions for Log. This particular definition is not mathematically correct, but the Wolfram Language will still allow you to give it:
Wolfram Language code: Log[7] = 2
The Wolfram Language will use your definitions whenever it can, whether they are mathematically correct or not:
Wolfram Language code: Log[7] + Log[3]
This removes the incorrect definition for Log:
Wolfram Language code: Log[7]=.
This restores the protection for Log:
Wolfram Language code: Protect[Log]
Definitions you give can override built‐in features of the Wolfram Language. In general, the Wolfram Language tries to use your definitions before it uses built‐in definitions.
The rules that are built into the Wolfram Language are intended to be appropriate for the broadest range of calculations. In specific cases, however, you may not like what the built‐in rules do. In such cases, you can give your own rules to override the ones that are built in.
There is a built‐in rule for simplifying Exp[Log[expr]]:
Wolfram Language code: Exp[Log[y]]
You can give your own rule for Exp[Log[expr]], overriding the built‐in rule:
Wolfram Language code: (Unprotect[Exp];Exp[Log[expr_]] := explog[expr];Protect[Exp];)
Now your rule is used, rather than the built‐in one:
Wolfram Language code: Exp[Log[y]]
Manipulating Value Lists
DownValues[f]
give the list of downvalues of f
UpValues[f]
give the list of upvalues of f
DownValues[f]=rules
set the downvalues of f
UpValues[f]=rules
set the upvalues of f
Finding and setting values of symbols.
The Wolfram Language effectively stores all definitions you give as lists of transformation rules. When a particular symbol is encountered, the lists of rules associated with it are tried.
Under most circumstances, you do not need direct access to the actual transformation rules associated with definitions you have given. Instead, you can simply use lhs=rhs and lhs=. to add and remove rules. In some cases, however, you may find it useful to have direct access to the actual rules.
Here is a definition for f:
Wolfram Language code: f[x_] := x ^ 2
This gives the explicit rule corresponding to the definition you made for f:
Wolfram Language code: DownValues[f]
Notice that the rules returned by DownValues and UpValues are set up so that neither their left‐ nor right‐hand sides get evaluated. The left‐hand sides are wrapped in HoldPattern, and the rules are delayed, so that the right‐hand sides are not immediately evaluated.
As discussed in "Making Definitions for Functions", the Wolfram Language tries to order definitions so that more specific ones appear before more general ones. In general, however, there is no unique way to make this ordering, and you may want to choose a different ordering from the one that the Wolfram Language chooses by default. You can do this by reordering the list of rules obtained from DownValues or UpValues.
Here are some definitions for the object g:
Wolfram Language code: g[x_ + y_] := gp[x, y];g[x_ y_] := gm[x, y]
This shows the default ordering used for the definitions:
Wolfram Language code: DownValues[g]
This reverses the order of the definitions for g:
Wolfram Language code: DownValues[g] = Reverse[DownValues[g]]

Related Guides

    ▪
  • Attributes
Top
Introduction for Programmers
Introductory Book
Wolfram Function Repository | Wolfram Data Repository | Wolfram Data Drop | Wolfram Language Products
Top
  • Products
  • Wolfram|One
  • Mathematica
  • AI Access
  • Compute Services
  • System Modeler

  • Wolfram|Alpha Notebook Edition
  • Wolfram|Alpha Pro
  • Mobile Apps

  • Wolfram Engine
  • Wolfram Player

  • Volume & Site Licensing
  • Server Deployment Options
  • Consulting
  • Wolfram Consulting
  • Repositories
  • Data Repository
  • Function Repository
  • Community Paclet Repository
  • Neural Net Repository
  • Prompt Repository

  • Wolfram Language Example Repository
  • Notebook Archive
  • Wolfram GitHub
  • Learning
  • Wolfram U
  • Wolfram Language Documentation
  • Webinars & Training
  • Educational Programs

  • Wolfram Language Introduction
  • Fast Introduction for Programmers
  • Fast Introduction for Math Students
  • Books

  • Wolfram Community
  • Wolfram Blog
  • Public Resources
  • Wolfram|Alpha
  • Wolfram Problem Generator
  • Wolfram Challenges

  • Computer-Based Math
  • Computational Thinking
  • Computational Adventures

  • Demonstrations Project
  • Wolfram Data Drop
  • MathWorld
  • Wolfram Science
  • Wolfram Media Publishing
  • Customer Resources
  • Store
  • Product Downloads
  • User Portal
  • Your Account
  • Organization Access

  • Support FAQ
  • Contact Support
  • Company
  • About Wolfram
  • Careers
  • Contact
  • Events
Wolfram Community Wolfram Blog
Legal & Privacy Policy
WolframAlpha.com | WolframCloud.com
© 2026 Wolfram
© 2026 Wolfram | Legal & Privacy Policy |
English