I'm new to the mathematica platform and I am developing a simulation framework as my first exercise and have been tearing my hair figuring how to make packages interact with each other. Ill explain a minimum package experiment I developed to understand my problems and please I would like a theoretical explanation of why this happens, if it is a bug or if I am just dumb with mathematica.
The thing is that if I have packages that use each others exported symbols or functions inside their functions, after the first package is loaded he loads the others declared as needed as well, but then only that package that was loaded first can reference all other exported stuff, and the others for some reason can only look at the exported data of later packages/contexts in the context path. To make every package able to see every other exports I need to load them again individually. This makes no sense to me, I thought the whole point of having needs in any package constructor is to avoid loading myself every package of my packages set. Is this a bug? Btw, the exported symbols from different packages are found right away by mathematica is just the symbols inside functions that cant reference each other.
So basically I defined three packages, ja1,ja2,ja3. All have the same structure like this:
Package ja1
BeginPackage["SimulationsSystem`ja1`", { "SimulationsSystem`ja2`", "SimulationsSystem`ja3`"}]
shadow::usage="shadow"
var1::usage = "var1"
pro1::usage = "pro1"
(* Exported symbols added here with SymbolName::usage *)
Begin["`Private`"] (* Begin Private Context *)
shadow=1;
var1=1;
pro1[]:=var1+var2+var3
End[] (* End Private Context *)
EndPackage[]
Package ja2
BeginPackage["SimulationsSystem`ja2`", { "SimulationsSystem`ja1`", "SimulationsSystem`ja3`"}]
shadow::usage="shadow"
var2::usage = "var2"
pro2::usage = "pro2"
(* Exported symbols added here with SymbolName::usage *)
Begin["`Private`"] (* Begin Private Context *)
shadow=2;
var2=1;
pro2[]:=var1+var2+var3
End[] (* End Private Context *)
EndPackage[]
Package ja3
BeginPackage["SimulationsSystem`ja3`", { "SimulationsSystem`ja1`", "SimulationsSystem`ja2`"}]
shadow::usage="shadow"
var3::usage = "var3"
pro3::usage = "pro3"
(* Exported symbols added here with SymbolName::usage *)
Begin["`Private`"] (* Begin Private Context *)
shadow=3;
var3=1;
pro3[]:=var1+var2+var3
End[] (* End Private Context *)
EndPackage[]
Commands run: so after defining the packages I tried to run each pro function, called each var and called shadow to see the nearest Package/context working. And here is the result:
In[2]:= << SimulationsSystem`ja2`
$ContextPath
Out[5]= {"SimulationsSystem`ja2`", "SimulationsSystem`ja1`", \
"SimulationsSystem`ja3`", "SimulationsSystem`SimulationsSystem`", \
"SimulationsSystem`Models`Basic`", \
"SimulationsSystem`SimulFunctions`", \
"SimulationsSystem`TurnPackages`", \
"SimulationsSystem`EventFunctions`", "SimulationsSystem`Classes`", \
"PacletManager`", "WebServices`", "System`", "Global`"}
In[6]:= pro1[]
Out[6]= 2 + SimulationsSystem`ja1`Private`var2
In[7]:= pro2[]
Out[7]= 3
In[8]:= pro3[]
Out[8]= 1 + SimulationsSystem`ja3`Private`var1 + \
SimulationsSystem`ja3`Private`var2
In[9]:= var1
Out[9]= 1
In[10]:= var2
Out[10]= 1
In[11]:= var3
Out[11]= 1
In[12]:= shadow
Out[12]= 2
In[13]:= << SimulationsSystem`ja3`
$ContextPath
Out[14]= {"SimulationsSystem`ja3`", "SimulationsSystem`ja2`", \
"SimulationsSystem`ja1`", "SimulationsSystem`SimulationsSystem`", \
"SimulationsSystem`Models`Basic`", \
"SimulationsSystem`SimulFunctions`", \
"SimulationsSystem`TurnPackages`", \
"SimulationsSystem`EventFunctions`", "SimulationsSystem`Classes`", \
"PacletManager`", "WebServices`", "System`", "Global`"}
In[15]:= pro1[]
Out[15]= 2 + SimulationsSystem`ja1`Private`var2
In[16]:= pro2[]
Out[16]= 3
In[17]:= pro3[]
Out[17]= 3
In[18]:= var1
Out[18]= 1
In[19]:= var2
Out[19]= 1
In[20]:= var3
Out[20]= 1
In[21]:= shadow
Out[21]= 3
In[22]:= << SimulationsSystem`ja1`
$ContextPath
Out[23]= {"SimulationsSystem`ja1`", "SimulationsSystem`ja3`", \
"SimulationsSystem`ja2`", "SimulationsSystem`SimulationsSystem`", \
"SimulationsSystem`Models`Basic`", \
"SimulationsSystem`SimulFunctions`", \
"SimulationsSystem`TurnPackages`", \
"SimulationsSystem`EventFunctions`", "SimulationsSystem`Classes`", \
"PacletManager`", "WebServices`", "System`", "Global`"}
In[24]:= pro1[]
Out[24]= 3
In[25]:= pro2[]
Out[25]= 3
In[26]:= pro3[]
Out[26]= 3
In[27]:= var1
Out[27]= 1
In[28]:= var2
Out[28]= 1
In[29]:= var3
Out[29]= 1
In[30]:= shadow
Out[30]= 1
You can see in the output that only after packages are loaded by themselves they are able to recognize every other packages' exported symbols and functions.