# Transferring a function between two modules in a package

I have a first module which outputs as forth output a function G I want to transfer to another module. The specific function is

G = (72 (97 + 57 s))/(55 (55 + 96 s + 36 s^2))


Everything works before encapsulating. Here's a short version of the first module:

Rat[expr_, expc_, csi_: 1] :=
(* Fq is defined outside, hopefully global variable *)
Module[{nCLroots, nphases, sct, sc, ks, kss, kp, G, Gp, WE, WEp},
nCLroots = Length[expr];
nphases = Length[expc];
ϕ =
Product[(1 + #/expc[[i]]), {i, nphases}] /
Product[(1 + #/expr[[i]]), {i, nCLroots}] &;
rhmin =
1 - Simplify[
Product[expr[[i]], {i, nCLroots}] /
Product[expc[[i]], {i, nphases}]];
Print["input: ", Subscript[ϕ, "-"], " = ", ϕ[s], " q =", q = Fq csi (1 - rhmin)];
sct = Apart[Simplify[ϕ[#]/(csi (1 - rhmin) (# - Fq))], #] &;
(* k - q *) kss = ((1/sct[#]) + csi (1 - rhmin) Fq) &;
(* symbol, without q *);
ks = Apart[kss[#], #] &;
Print["symbol k = ", ks[s]];
kp = D[ks[s], s] /. s -> Fq;
WEp = FullSimplify[1/((ks[s] /. s -> # + Fq) - q)] &;
WE = Function[s, WEp[s]];
Gp = FullSimplify[1/(# kp) - WEp[#]] &;
G = Function[s, Gp[s]];
Print["WE = ", Factor[WE[s]]];
Print["G = ", Factor[G[s]]];
{ϕ, rhmin, ks, G}];


The following code works

exr = {1/2, 3/2};
exc = {1, 2};
Fq = 1/3;
cc = Rat[exr, exc];
G = cc[[4]][x]
Print[" G=", G]


but stops working when I encapsulate the modules in a Mathematica package and I guess it's because the way I transfer G

The structure of the RatC.wl package encapsulating the modules is

BeginPackage["RatC"]
Unprotect @@ Names["RatC*"];
ClearAll @@ Names["RatC*"];
Rat::usage="..."
Begin["Private"]
ClearAll["Global*"]
Copy-paste of Rat above
End[]
EndPackage[]


after encapsulation, the function G contains two Private variables and sends the second module into very long computations.

G =
1/
((1/2 - 1/(6 (1 + RatCPrivateFq)^2) -
7/(8 (2 + RatCPrivateFq)^2)) RatCPrivates) -
1 /
(-(2/3) + (RatCPrivateFq + RatCPrivates)/2 +
1/(6 (1 + RatCPrivateFq + RatCPrivates)) +
7/(8 (2 + RatCPrivateFq + RatCPrivates)))


The existence of two Private variables seemed to me to be significant, since functions with just one Private seemed to be usable just by plugging s; I wanted to make Fq a global variable by defining it outside the package, but G has still two Private variables

Any recommendations? Is it easier to transfer G as expression than as pure function?

• I understood your "modules" to be packages by themselves, so I updated the question for clarity. – C. E. Sep 19 '19 at 9:07
• At least closely related: 114769 – Kuba Sep 19 '19 at 9:36
• It is not clear to me what you're doing exactly. Some of the things that I don't understand: How does a package output a package? How do you transfer that to a module (and what is a module here)? How is what you're giving a function (that's just an expression)? How do you encapsulate the packages? Is a "Mathematica package" the same thing as a "package"? What does "sometimes accepted and sometimes not" mean? What happens in both cases? Please provide the full relevant code of your files, together with the necessary package directory structure to fully reproduce the problem. – Lukas Lang Sep 19 '19 at 10:51
• Your G is not a function but an expression. To use it elsewhere, consider returning a proper Function instead, such as G = Function[s, (72 (97 + 57 s))/(55 (55 + 96 s + 36 s^2))]. This way the dependent parameter is encapsulated and you will not have to deal with context issues like the one you're seeing here. – Sjoerd Smit Sep 20 '19 at 14:03
• We need to have the code for both modules and anything else that is defined in your package to be able answer this question. – m_goldberg Sep 21 '19 at 0:31