I'm new to Mathematica and I spent the last hour trying to make the expression

expression = 
  3 + 2 cos[t] + 3 cos[2t] + 5 cos[3t] + 7 cos[4t] + 9 sin[t] +  4 sin[3t] + 5 sin[4t]

into a function of t. I tried

f[t_] := expression

but it didn't work.


4 Answers 4


Evaluate is your friend

expression = 
 3 + 2 Cos[t] + 3 Cos[2 t] + 5 Cos[3 t] + 7 Cos[4 t] + 9 Sin[t] + 
 4 Sin[3 t] + 5 Sin[4 t];
f[t_] := Evaluate[expression];


Edit: This is the same as

f[t_] = expression;
  • 8
    $\begingroup$ You can do f[t_] = expression which is the same thing. := delays evaluation because it has the HoldAll attribute, and Evaluate takes precedence over that, so in total it's just = $\endgroup$
    – ssch
    Sep 9, 2013 at 18:10
  • $\begingroup$ @ssch Oh yes, of course! $\endgroup$
    – ybeltukov
    Sep 9, 2013 at 18:15
  • 3
    $\begingroup$ +1. Just to mention one subtlety: the form lhs:=Evaluate[rhs] is, strictly speaking, not fully equivalent to lhs = rhs, in terms of how the rules are stored internally. In most cases this does not matter, but in some it does. For example: a := Evaluate[Range[10]] . Trying the Part assignment will result in an error. Try e.g. a[[2]] = 1. This won't happen for direct assignment. $\endgroup$ Sep 18, 2013 at 10:13
  • $\begingroup$ @LeonidShifrin is there any way to tell whether a has been assigned a value via := or via =, which, as you say, matters... In the terminology of General::noval's documentation: Is there a way to find out whether a is a delayed value or a has an immediate value? $\endgroup$
    – masterxilo
    Jul 3, 2016 at 18:07
  • 1
    $\begingroup$ @masterxilo, @Leonid Language`ExtendedDefinition[a] will have a delayed rule as value of OwnValues for immediate own value, and a list containing one delayed rule for delayed own value. $\endgroup$
    – jkuczm
    Jul 6, 2016 at 13:27

First, note that sin and cos are not built-in functions; I shall use Sin and Cos.

Please see: Scoping in assigning a derivative

Typically you do not want to make a definition for a parameter t without protecting t on the RHS. That is to say, using Evaluate or f[t] = can leave t to evaluate to its present global value.

If you define expression with := you will make sure t remains unevaluated there as well.

t = "Fail!";

expression := 
  3 + 2 Cos[t] + 3 Cos[2 t] + 5 Cos[3 t] + 7 Cos[4 t] + 9 Sin[t] + 4 Sin[3 t] + 5 Sin[4 t]

  f[t_] = expression;


The method above is automated in the abstraction localSet defined here:


Using Evaluate to make a function is not a robust solution. A true function is one which takes all its input from its arguments and return its result from its last return value and has no side effects out of this.

Here is an example why Evaluate does not make f[t] a true function

expression = Cos[t] + globalX;
globalX = 1;
f[t_] := Evaluate[expression];

In the above, f[t] took part of its input (the t only) via the argument, but the other part (x) was accessed by using a global variable. Accessing global variables from inside a function is not a good way to do things (tm).

It is better to do it the good old fashioned way, and put the body of the function inside the function, and pass it all its input via arguments

f[t_, x_] := Cos[t] + x

The difference is important. If one writes some Module and uses symbols not passed via arguments and also not local to the module, then the notebook interface will show this symbol with different color. This can be important in telling one something is wrong. This becomes more important when working with lots of functions and more complex program. By Evaluating an external expression, one does not have the advantage of this check.

Compare the color of x used by the function in these 4 cases:

Mathematica graphics


Mathematica graphics


Mathematica graphics

a black colored x will immediately tell one they are accessing a global x (a symbol with different context at least), and to correct this. The third and fourth examples above are true functions, while the first two are not.

  • $\begingroup$ The reason I did it like I presented is that I need to construct trigonometric polynomials starting from coefficients... $\endgroup$ Sep 9, 2013 at 19:42
  • 2
    $\begingroup$ "A true function is one.... " You mean a pure function. Functions in Mathematica do not have to be pure, and as such you can justifiably use Evaluate, however as you note it will not be pure (like a ton of other Mathematica functions are not mind you). But describing it as not a "true" function could cause confusion. Besides this point, purity in Mathematica is a much more complicated issue than in other languages, and an argument could be made that no functions are pure. Even f[x_]:=x^2 will depend on state and can have side effects. $\endgroup$
    – jVincent
    Sep 10, 2013 at 9:51
  • 1
    $\begingroup$ @jVincent no, I meant true function, not pure. true function in the mathematical sense. it only acts on its input via arguments, and has local variables and has no side effects other than its return value. A true function does not even allow passing argument by reference. Ada functions used to be true, until Ada 2012 where they relaxed allowing a function to be passed an argument by reference (called in-out). Many in Matematica write functions that are not true functions, where some of its input is passed by arguments and some of its input is global. $\endgroup$
    – Nasser
    Sep 10, 2013 at 16:10
  • $\begingroup$ ....on the side effect, it is done by documentation. Each function should document any side effects it makes. Things like creating a file, or updating a file, and such are considered a side-effect and can't be prevented by the language. But should be documented in the function header, so someone reading this function later on, can see right away what are its side-effects. $\endgroup$
    – Nasser
    Sep 10, 2013 at 16:16
  • 1
    $\begingroup$ "in the mathematical sense" Then you should add this. You where talking about Mathematica, which is a programming language, thus the correct definition of function is the contextual one. It's like arguing that a child's imaginary giraffe is not "truly" imaginary because you can't square it to yield a negative giraffe. While the names used overlap, the definitions are different, and neither is universally "true". $\endgroup$
    – jVincent
    Sep 10, 2013 at 17:06

While other answers are valid, I believe you could just use something as straightforward as

f = Function[t, Evaluate@expression]

Let's see how it works:

In[1]:= expression = 3 + 2 cos[t] + 9 sin[t]
                       + 3 cos[2t]
                       + 5 cos[3t] + 4 sin[3t]
                       + 7 cos[4t] + 5 sin[4t];
In[2]:= ClearAll[f]

In[3]:= f = Function[t, Evaluate@expression]
Out[3]= Function[t, 3 + 2 cos[t] + 9 sin[t]
                      + 3 cos[2t]
                      + 5 cos[3t] + 4 sin[3t]
                      + 7 cos[4t] + 5 sin[4t]]


In[4]:= f[0]


Out[4]= 3 + 17 cos[0] + 18 sin[0]

(Mathematica only has definitions for capitalized Cos and Sin, that's why no more simplifications for your expression are provided.)

You may skip the rest of the answer if this solution is enough for you, and you are not interested in Mathematica subtleties.

However, there is a subtle aspect that may cause unexpected problems in the future. In[3] would modify the “own values” of symbol f:

In[5]:= OwnValues[f]
Out[5]= {HoldPattern[f] :>
                       3 + 2 cos[t] + 9 sin[t]
                         + 3 cos[2t]
                         + 5 cos[3t] + 4 sin[3t]
                         + 7 cos[4t] + 5 sin[4t]]}

and if you try to add some modifications to your definition then, you could unexpectedly bump into error:

In[6]:= f[t_, shift_] := shift + f[t]

(Check out the Out[5] error message if you want.) Definitions like the one in In[5] deal with “down values” of f, contrary to “own values”.

You could use a bit more elaborate mechanism for assigning DownValues, in case you plan to use In[6]-like definitions for f extensively in the future:

In[7]:= nameToPattern = # :> Pattern[#, Blank[]] &;

In[8]:= defineWithExplicitArguments[listOfArgs_List, f_, expr_] :=
          With[{listOfPatterns = listOfArgs /. nameToPattern /@ listOfArgs}, (
            DownValues@f = DeleteCases[DownValues@f, _[_[_@@listOfPatterns], _], 1];
            Evaluate[f@@listOfPatterns] := expr)]

In[9]:= defineWithExplicitArguments[singleArgument_, f_, expr_] :=
          With[{pattern = singleArgument /. nameToPattern@singleArgument}, (
            DownValues@f = DeleteCases[DownValues@f, _[_[_@pattern], _], 1];
            Evaluate[f@pattern] := expr)]

Now, let's remove all definitions for f

In[10]:= ClearAll[f]

and we're free to use defineWithExplicitArguments for assigning “down values” to it:

In[11]:= defineWithExplicitArguments[t, f, expression]

In[12]:= f[0]
Out[12]= 3 + 17 cos[0] + 18 sin[0]

Additional definitions would work, too:

In[13]:= f[t_, shift_] := shift + f[t]

In[14]:= f[0, -3]
Out[14]= 17 cos[0] + 18 sin[0]

By the way, the In[13] definition could be added by means of defineWithExplicitArguments, as well. Let's check it:

In[15]:= f[t_, shift_] =.

Here, we redefined “two-arguments version” of f, and it does not calculate the shifted wave anymore:

In[16]:= f[0, -3]
Out[16]= f[0, -3]


In[17]:= defineWithExplicitArguments[{t, shift}, f, expression + shift]

makes it work again:

In[18]:= f[0, -3]
Out[18]= 17 cos[0] + 18 sin[0]
  • $\begingroup$ Note that at least your first form Function[t, Evaluate@expression] does not protect t from a global value, should one desire that. $\endgroup$
    – Mr.Wizard
    Sep 10, 2013 at 13:26
  • $\begingroup$ @Mr.Wizard I'm sorry, but I don't really understand the concept of “protecting from a global value”. :-/ I assume everything to be evaluated in a single context and could only add this note to the answer. For sure, almost anyone's edit regarding global vs local issues would be more reliable than mine. $\endgroup$
    – akater
    Sep 10, 2013 at 13:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.