rh@smds.UUCP (Richard Harter) (11/25/90)
Recently I wrote asking for opinions on handling globals (or equivalent concepts). The specific context is the lakota language, which I am working on. However the issue is of general interest (IMHO). The most common suggestion is some variation of nested cumulative scope. Modula-2 and ML were cited. There seems to be a consensus that a combination of named global name spaces (e.g. labelled commons in fortran and the mechanisms used in C) are not terribly satisfactory. At least they are not so wonderful that anyone advocated them :-). One of the advantages of the module/submodule approach is that procedures within modules have a duration and scope which is restricted to the life time of the containing module. This is important (to me) because the intended usage includes running sequences of programs which, potentially, can have naming conflicts at the procedure level. In any case I have written a first draft proposal which draws on many of the observations that have been (many thanks to all) plus some original thoughts. Would it be that these are not the weakest part of the scheme. I am posting it for those who might be interested. Again, any comments are welcome. ---- DRAFT PROPOSAL ---- Currently Lakota has mini-processes (threads), procedures, and variables with each thread being an "independent" execution environment. The only provision it has for globals (or equivalent) currently is to declare a variable as being global to the current thread; procedures are always global. It should be mentioned that threads can have an indefinitely long lifetime. This scheme is even worse than the old versions of Fortran which only had blank common since globals and procedures remain in the namespace indefinitely unless explicitly deleted. The proposal is to add a new category of object called a context. A context can contain variables, procedures, and sub-contexts. One can think of a context as a dictionary. When a procedure is invoked it inherits the contexts above it. The proposed rules are: (1) The thread always has an un-named context associated with it. (2) At any point there is a current context list. (3) The general name search rule is to search the local level, and then work back up the context list from the most recent up to the anonymous thread context. (4) At any point we can create a sub context. (5) At any point we can switch to any available leaf context. (6) At any point there is a default context list. For the thread this is the anonymous master context. Within procedures it is the context list that was in effect at the time the procedure was invoked. (7) Contexts created during a procedure invocation vanish when the procedure exits. (8) Name searches for procedures and contexts succeed if the name can be found in the context list. (9) Variables taken from the context list must be explicitly imported. (10) When a procedure is defined it is entered in the context that is in force at that time. In particular there can be more than one procedure extant with the same name. (11) The tentative list of commands associated with context manipulation is (command arguments are shown as $1, etc): create-context $1...$n use-context $1 use-default-context delete-context $1...$n add-to-current-context $1...$n delete-from-current-context $1...$n import-from-current-context $1...$n The create-context command creates leaf contexts relative to the current terminal context in the context list. The latter three commands are variable placement commands. We also need two functions, one which returns the current context list, and one which returns the leaf contexts currently available. ----------------------------------------------------------------- INITIAL COMMENTS FROM ME A. Is this scheme too complicated? My first reaction is that it is -- it may be too daunting for the average programmer, particularly one who is faced with maintaining scripts in a relatively strange language. Upon reflection I opine that the machinery will not be needed for typical moderate size applications which (for transient code) will simply read create-context foobar use-context foobar ... define procedures ... execute main entry point delete-context foobar However that's really not the point. Is this more machinery than is needed for heavy duty problems? Is it elegant or is it a kludge? I'm still undecided. B. Does it handle the friendship problem? What I mean here is package programming where you have a collection of procedures sharing a private name space or spaces. It seems to imply that a program using such a package needs to create a leaf node context at its top level. Upon reflection this doesn't seem to be a problem (in lakota) because the program will have to load the package (execute the file containing the package) into memory. The package file can contain the requisite context declarations. C. What about context name conflicts? The difficulty is that, within a procedure, one might attempt to create a context with the same name as an existing current context. It occurs to me that it might be better to have the processor create the names and ask it for the name it created. D. Should I use different terms? After writing the above it occurs to me that it would be better to use a word like dictionary instead of context and reserve the word context for the current list of dictionaries. -- Richard Harter, Software Maintenance and Development Systems, Inc. Net address: jjmhome!smds!rh Phone: 508-369-7398 US Mail: SMDS Inc., PO Box 555, Concord MA 01742 This sentence no verb. This sentence short. This signature done.