# How do I create and use Mathematica packages?

I have created a package following the tutorial in Mathematica 8 virtual book. However this tutorial is quite, let's call it, "short". I have a TestPackage.m file:

BeginPackage["TestPackage"];
TestPackage::usage = "Test package"

Begin["Private"]
TestPackage[1] := {1}
(*private functions and stuff*)
Mesg := Print["Private function of TestPackage"]
End[]

TestPackage f[x_] := Module[{a = 3, b = 3}, Mesg; a x^b]

EndPackage[]


and a file UseTestPackage.nb that uses the package:

ClearAll["Global*"]
dir = "C:/...and so on"
Get["TestPackage", Path -> dir]

f[2] (*this should give an output defined in TestPackage.m, but it doesn't*)

$ContextPath (* {"PacletManager", "WebServices", "System", "Global"}*) (*seems it didn't read the m file*)  but nothing happens. No symbols of functions are exported, despite the fact that Get[] doesn't throw an error. How do I make it work? - Should there be a  before Private? – Per Alexandersson Aug 17 '12 at 22:29 Take a look here and here - this may get you started. To test your package, place it in $UserBaseDirectory/Applications, at least temporarily. I suspect that you don't really load it. – Leonid Shifrin Aug 17 '12 at 22:37
Try also Names["TestPackage*"] - you should get {"TestPackagef"} or simply {"f"} if the package has been loaded. – Leonid Shifrin Aug 17 '12 at 22:44
Could you confirm if your issue is because of the typo above? I think it is. It runs fine for me if I fix the extra space. – R. M. Aug 17 '12 at 23:04
@R.M The problem is that either way, there should have been some error message generated, since with the space, that line is a syntax error, and if the file wasn't found, then Get should have complained. – Leonid Shifrin Aug 17 '12 at 23:10

Your specific problem looks like you somehow managed to not load the package properly (did you evaluate Get[...]?). There's also an excess space in your long-form call to f (just before EndPackage[]) that will give you an error.

Although your package will work if you fix the typo, this is not in general a good way to define your function. To see why, try:

<<"path/to/TestPackage.m"
Names["TestPackage*"]
(* {"a", "a$", "b", "b$", "f", "Mesg", "TestPackage", "x"} *)


In general, the way to do this is to put all your definitions and auxiliary symbols in the private context and "expose" only those that you need publicly. All that needs to be done for this is to just have the symbol in some definition before beginning the private context and this is typically done with a usage definition. Here's a modification of your example above:

BeginPackage["TestPackage"];
f::usage = "My function"

Begin["Private"]
Mesg := Print["Private function of TestPackage"]
f[x_] := Module[{a = 3, b = 3}, Mesg; a x^b]
End[]

EndPackage[]


Now, in a notebook, evaluate:

<< "path/to/TestPackage.m"
f[2]
(* Private function of TestPackage
24 *)


which gives you your desired result.

Note how I exposed only f and not Mesg, because the latter (as an example) is not essential to the outside world. You can see that indeed only this is "known" to the outside world:

Names["TestPackage*"]
(* {f} *)


However, all symbols can always be accessed with their full context path. For example, you can access Mesg as:

TestPackagePrivateMesg
(* Private function of TestPackage *)

-
+1. Accessing private symbols is often very handy for debugging (to me at least). Generally, I find the namespace / package system in Mathematica very well designed (to the point that I don't recall any flaws off the top of my head, for all the time I was using it), and also very hackable, since one can do a lot of non-standard tricks which allow for very flexible manipulations with namespaces. A more closed namespace model would rule out such uses, making encapsulation mechanism significantly less powerful. – Leonid Shifrin Aug 17 '12 at 23:43
Thank you R.M. Your answer works just fine :] – Misery Aug 18 '12 at 5:47