Namespace solution?
- Posted by Irv Mullins <irvm at ellijay.com> Jun 24, 2001
- 453 views
What are globals? They are an attempt to allow the sharing of variables, routines, etc. between program files - something that is clearly necessary. Unfortunately, when you declare a global variable (X, for example) in an include file, you are laying claim to the use of the name X for variables, constants, and routine names, not only for your own program, but for ALL programs which want to make use of that include file. Even those written by others. You are, in effect, claiming a Universal Copyright on the name X. The result? Name collisions. It would be relatively easy to add two or three lines to a widely used Euphoria include (Win32Lib comes to mind) which would break 95% of the existing Euphoria programs worldwide. Most of us don't really want to do that. What we want to do is to be able to declare a variable (constant,routine...) in ONE place that is visible to all the files in OUR program, without affecting other programmer's efforts. More of a cooperative "export - import" scheme, as opposed the "pre-emptive strike" plan we have now. Here are some possibilities: I think, by far, #3 is the best.... 1. Deprecate the 'global' keyword, and introduce the new keywords: export and import.. example: export x,y -- in file a export x,y -- in file.b -- your program import x from file.a import y from file.b If x is not specifically imported, it will not clobber any x that you have in your program, even though it is exported by file a It would produce an error if you "import x" and also declare an x in your local file. just as it does now. The problem? You can still refer to only one x within your program file. The x in file.b is unavailable, and you can't declare an x of your own.. So we have to reject this scheme as being only a partial solution. 2. Expand the syntax of 'include' so that all globals may have a unique prefix attached by the programmer as they are included. example: include file.a as a include file.b as b ? a.x -- prints the x in file.a b.x = 33 -- sets x in file.b to 33 You would still be free to declare x in your own program file, which would be legal and would be referred to as just plain x (x = 34) Possible problems: What happens if you include an existing program which uses the plain 'include' syntax? These "unqualified" includes would prevent you from using variables of the same name in your code. And you might not have the ability or inclination to go into those include files to add the new syntax. Doing so would mean you'd have a 'customized' package, with all the problems that implies. What if that include file were shrouded? 3. Allow 'retroactive name decoration'. The interpreter is good at catching name collisions. The problem is that your only option, once a collision is found, is to halt with an error. This doesn't necessarily have to be the case. Consider this: global atom x -- declared in file.a --file.c include file.a integer x -- oops! ** Warning: Local integer x conflicts with global atom x in "file.a" ** So you go back in revise your code, not by changing your locally declared integer x, but by 'retroactively' changing the declarations as they are read in from file.a -- file.c name file.a~x a.x -- new directive -- instructs the interpreter: whereever you find a reference to x in file.a, -- convert it to a.x. (not in the source code, just in the internal representation) -- note that this directive must appear BEFORE the include it affects include file.a integer x ? x -- prints the local integer ?a.x -- prints the global x from file.a Since the directive must appear before the include, I 'think" that this approach would allow you to use two or more includes which now don't play well together, without making any change to either of the includes. You'd just have to keep adding name <filename>~<var> <newname> lines until Euphoria finds no more conflicts. You never have to change the source of the includes. Your main file - the one you CAN control - does all the work. Regards, Irv