# Import expression for function definition inside a Module of a Package

I've been struggling on this problem for quite a while, but I still don't understand why Mathematica is unable to recognize a function definition where the rhs is an Import command.

Let me introduce the problem.

Consider the following Mathematica Package

(*Package v1*)
BeginPackage["test"]

testFun::usage = "testFun[]";

Begin["Private"]

packageDirectory = $InputFileName // DirectoryName; fModule[] := Module[{}, f[x_] = Import[FileNameJoin[{packageDirectory,"fun.m"}]]; ]; testFun[xx_] := Module[{}, fModule[]; Table[f[i], {i, xx}] ]; End[] (* Private *) EndPackage[]  where the file fun.m acts as simple container for the definition of the body of f, e.g. x^2  When testFun[5] is called in Mathematica Notebook the result is {x^2, x^2, x^2, x^2, x^2}  which means that the pattern x_ is not recognized when fModule[] is called. The weird fact is that moving the defintion of f[x] outside the module, i.e. like (*Package v2*) BeginPackage["test"] testFun::usage = "testFun[]"; Begin["Private"] packageDirectory =$InputFileName // DirectoryName;

f[x_] = Import[FileNameJoin[{packageDirectory,"fun.m"}]];

fModule[] := Module[{},
f[x_] = Import[FileNameJoin[{packageDirectory,"fun.m"}]];
];

testFun[xx_] := Module[{},
(*fModule[];*)
Table[f[i], {i, xx}]
];

End[] (* Private *)

EndPackage[]


the definition of f[x] is properly recognized!

Also, everything works if I run the code (Package v1) directly in the FrontEnd!

In my actual code I need the definition of f[x] to happen inside the module using the Import. That's because the expression to be used in the definition is quite big and I prefer to keep it in a dedicated .m file.

Does anyone know why I can't define a function using an Import inside a module? Again, the problem exist in the Package only.

Thanks a lot in advance, and happy new year! :)

Ps: I apologize for the criptic title.

• Look at the output of ?? testPrivatef - you'll see that the x returned from Import is not in the same context as f – Jason B. Jan 3 '18 at 20:10
• Hi Jason! You're right, the output shows that they are not in the same context: testPrivatef[testPrivatex_]=x^2. – Giovanni Bordiga Jan 3 '18 at 20:32
• The problem is that when you finally call testFun, you are no longer in the testPrivate  context, you are now in the global context. A quick fix is to modify the body of fModule to use f[ Globalx_] = .... . This assumes that when you actually call testFun you will be in the global context. Someone else will have to provide a more robust solution. – Jason B. Jan 3 '18 at 20:34
• Better may be to call BeginPackage and EndPackage inside the Module. As an aside, using Module[{}, ...] is less efficient than just using (...). You're not using Module for scoping so you can drop it. – b3m2a1 Jan 3 '18 at 20:48
• @JasonB. thanks for the quick fix, I'll try it on my code soon! @b3m2a1 the Package test is just an example to explain the problem, in my code I really need Module because I have several local variables. – Giovanni Bordiga Jan 3 '18 at 21:52

The problem, as stated in the comments, is that when you define fModule in the private context of your package,

fModule[] := Module[{},
f[x_] = Import[FileNameJoin[{packageDirectory,"fun.m"}]];
];


The x symbol will have the FullForm

Pattern[testPrivatex,Blank[]]


but since the file fun.m is read in when the function is called, the x present in that file is parsed as Globalx (or another context depending on when you call the function).

A hack to get it to work would be to redefine the f function to be of the form f[Globalx_], but this is not robust since you could be calling the function from within another package.

A better workaround is to define f as a Function, rather than a symbol with DownValues. In test.m, use

fModule[] := Module[{},
f = Import[FileNameJoin[{packageDirectory,"fun.m"}]];
];


then modify the fun.m function to be

Function[ x,
x^2
]


This ensures that x is scoped correctly regardless of context.

• Thanks a lot Jason! I'll try this as soon as I get access to my computer. 😉 – Giovanni Bordiga Jan 4 '18 at 15:46
• Using Function[{x}, ...] inside fun.m` everything works! Again thanks a lot @JasonB. – Giovanni Bordiga Jan 4 '18 at 20:51