The major difference between =
and :=
is that the first one evaluates its right-hand side while :=
doesn't. All weird behavior can be explained by this. We start with your initial example
a[t_] := -Pi Sin[Pi/2*t]
Even if you gave t
a value before, this definition will work because the right part is not evaluated. Let's say you defined t=1
and you don't use :=
then the following would happen
t = 1;
aWrong[t_] = -Pi Sin[Pi/2*t];
?? aWrong
This is a useless function because the right side was evaluated using the global value for t
. This is the reason why in most cases, you want to use :=
for functions. However, there are situations when you need to evaluate the right side even for a function.
Here is what doesn't work
vWrong[t_] := Integrate[a[t], t];
?? vWrong
Now, imagine what happens if you call vWrong[3]
. The problem is that every instance of t
will be replaced with 3 and you end up with
So what you really want is to solve the integral for an unknown t
first and then use this inside your function definition. Several ways are possible but none of them are particularly beginner-friendly. Remember that we gave t
a global value of 1, so we need to prevent that this is used in the integration.
Here is one way that blocks t
so that it has no value, calculates the integral and then injects the solution into the function definition with :=
.
Block[{t},
(v[t_] := #) &[Integrate[a[t], t]]
]
Of course, you can do the same thing using =
because it will evaluate the right side anyway. You just have to be aware that in the evaluation, global variables like our t=1
are used. Therefore, we wrap this code in Block
too
Block[{t},
v2[t_] = Integrate[a[t], t]
]
You can define s[t]
in a similar way, but maybe this all is not necessary if you just want to work with the expressions and you don't need function definitions.
This here works too, is much more beginner-friendly and usually used
ClearAll[t];
at = -Pi Sin[Pi/2*t];
vt = Integrate[at, t]
I hope that helps in understanding the situation. The main thing you need to be aware of is when you need to evaluate expressions.
Edit
Regarding your comment
When you say, I need to be aware of when to evaluate an expression, is there a list of scenarios when I should and shouldn't evaluate an expression?
There are too many different situations to give a list. However, the general rule is to use :=
for functions. One of the exceptions is the problem you had. Here it helps if you ask yourself the question
Is there something on the right side of my definition that needs to be (can be) calculated upfront?
One famous example that broke the necks of many many users is the following. Assume you have a function that calculates the area of an expression up to a certain value tend
:
func[tend_] := Integrate[-Pi Sin[Pi/2*$t], {$t, 0, tend}]
With your newly acquired knowledge, you know that the Integrate
will not be evaluated during the definition, but each time you call func
. This is disastrous when you try to plot it because func
is called so many times
Plot[func[tend], {tend, 1, 10}]; // AbsoluteTiming
(* {6.35437, Null} *)
However, in this case, we can precalculate the integral even for an unknown tend
. So when we use (note the =
)
func2[tend_] = Integrate[-Pi Sin[Pi/2*$t], {$t, 0, tend}]
the integral is solved and calling func2
is extremely fast
Plot[func2[tend], {tend, 1, 10}]; // AbsoluteTiming
(* {0.034309, Null} *)
There are far too many people who waited hours for their plots to finished because they did not realize they can pre-calculate some things.
My final tip is, just try to be aware of these things and if in doubt, check your definitions with ??
and think about what gets evaluated.
v[t_]:= 2Pi*Cos[pi/2*t]
. Note the underscore aftert
in the lefthand side. $\endgroup$