This post contains two parts. In the first part I will explain what I am trying to do. In the second part I will explain what I fear. My questions are about these fears. Are they justified and if yes how to deal with the problem?
I am developing a simple phraser package "structures`" to define structures (objects) that one can operate on. The package is to be used like this
Needs["structures`"]; beginStructure; defineField[f1,f2,f3]; defineMethod[ constructor[arg1_,arg2_]:=(THIS=newObject;THIS@f1=arg1;THIS@f2=THIS@f1+arg2) ]; defineMethod[ instanceMethod[arg1_,arg2_]:=(THIS@f1=arg1;THIS@f2=arg2) ]; ... endStructure;
I want to avoid this
Needs["structures`"]; beginStructure; ref = defineField[f1,f2,f3]; defineMethod[ref, constructor[arg1_,arg2_]:=(THIS=newObject;THIS@f1=arg1;THIS@f2=THIS@f1+arg2) ]; defineMethod[ref, instanceMethod[arg1_,arg2_]:=(THIS@f1=arg1;THIS@f2=arg2) ]; ... endStructure[ref];
The coding of the data structure should be as automatic as possible, thus the information flow between the define... methods is done in the background. They leave traces of what they do. I want to avoid passing things explicitly around (like with the ref version).
Essentially, what the functions defineMethod and defineFields do is that they operate on the body (the code) that is provided to them and they arrange things in the background. While doing that they leave traces of what they do so that all the methods (defineMethod, defineFields) can work in synergy (have to be called in the right order etc).
What worries me is multithreading (I know nothing about it, I have never used it). I would like to code all this in a safe way. I see a potential problem if the package is used in a parallel fashion, i.e. two instances of the package are run at the same time. Then it might happen that the following is effectively being executed
... beginStructure; ... beginStructyure; ... defineMethod[...]; endStructure;
which is a disaster, since the defineMethod does not know which environment it should operate within, or depends on. (beginStructure should prepare the stage for other calls).
I would like to know: are my fears justified? Is it possible that such a situation occurs that the package is beingn run at the same time, in the same kernel? If not, why is it not possible? If yes, how to prevent it?
I could have asked: How to make sure that a piece of code is never excecuted in parallel?, but that would be missleading. The environment is everything here.