Short explanation
It returns 0
because you are doing something like:
D[ Sin[Global`x1], MyP`Private`x1]
(*Global` or current $Context really*)
Why? Full answer would be long so I'm sending you to topics linked below, short answer for the most frequent case is:
x1
in notebook will be created in Global`
context while x1
from the package in MyP`Private`
. And this will happen whether you will use x1
before <<MyP`
or after. When MyLagrange[f_...
is parsed, $ContextPath
contains MyP` and System`
only. Also, tricks with putting Global`
inside the package won't work when the notebook you are working with has CellContext->Notebook
.
You can read more in a related topic: Behavior of Remove inside a Package and in the general one I'm encouraging you to become familiar with: How symbol lookup actually works
Handy tip to consider
MyPackage`Private`
context is used so that package implementation symbols won't interfere with outside world.
But the behavior you expect is exactly the opposite!
So if that package is only mean for you for daily research you can just delete Begin/BeginPackage/End/EndPackage
and leave a script which will just load some definitions into current context. That is not a general way to go with code meant for distribution but may be just fine for you.
Otherwise read further.
Generic solution
There are some tricks available to detect a variable that we need to differentiate with respect to but I'd say the safest thing is to provide it explicitly:
ClearAll["MyP`*"];
BeginPackage["MyP`"];
MyLagrange;
Begin["`Private`"];
MyLagrange[f_, var_] := Module[{a},
a = D[f, var];
a
];
End[];
EndPackage[];
MyLagrange[Sin[x1], x1]
Cos[x1]
I don't think it is too much of a hassle since all D
and Solve
functions are asking you for related symbols anyway.
Hairy shortcuts
Alternatively you could go with
a = D[f, Symbol[$Context <> "x1"]]
Probably the most stable from this section.
The problem here is that you force the user to always use x1
, does e.g. Solve
force you to always use x
?.
Another one is that the x1
could be on $ContextPath
but not in $Context
. The best example is a package. After Begin["`Private`"]
the $Context
is MyPackage`Private`
while x
could have been introduced in MyPackage`
earlier. That sounds artificial but still can happen and it is a straightforward way to break your code.
or
or
D[f, FirstCase[Level[f, {-1}], _Symbol]]
you never know what's inside f
and maybe there are some constant symbols that should just be ignored.
Global`x1
in betweenBeginPackage[]
andBegin[]
, and try again. $\endgroup$x
). Not to mention that if two packages exportx
the shadowing will be unavoidable. $\endgroup$