Re: Namespace (Is that your final answer?)
- Posted by Irv Mullins <irvm at ellijay.com> Jun 27, 2001
- 360 views
On Wednesday 27 June 2001 02:24, Derek Parnell wrote: > > 2. Any references to a variable NOT declared in this file > > MUST have been declared in a previously included file > > (file.a) - if not, this is an error, which Euphoria > > already knows how to handle. > > Therefore, replace those references with the already > > qualified name from file.a <file.a.pi> > > Are you saying that if, say, delta is referenced in file.b but not defined > in file.b then the author assumes that it is being defined in another file? > That make sense. But why do you then leap to the conclusion that is must be > in file.a? The symbol called delta could be defined in any included file or > even in the file that is trying to include file.b for that matter. Does the > interpreter have to search all known global symbols to find which file > delta might have been defined in? What if was defined in more than one > file? Just exactly the same as it works now - if 'delta' is referenced, and there's no declaration of 'delta' somewhere earlier in the file, then there MUST have been a (global) declaration in a previously included file. If not, then it's an error now, an error in 2.3. No, I'm not leaping to any conclusion about where the variable was previously defined. Euphoria obviously allready keeps track of what variables have been defined. See any error message. So tracking the source file for such variables would only mean adding an index to that variable indicating the point at which it was defined. Also, Euphoria quite obviously already does a search of all known global variables - how else could it warn you about duplicates? As far your question re: "what if it was defined in more than one file?" - Euphoria already knows that too, and tells you. The problem is, once it tells you, it throws in the towel, and gives up. That's not really necessary. > > 3. If a variable IS declared in this file, and a variable with > > an identical suffix has ALREADY been declared in an > > earlier file, Euphoria needs to let you know, so you > > can write your code to refer to the desired variable. > > Possible message: > > Warning - Duplicate identifiers: > > file.a atom pi line 2 <file.a.pi> > > file.b sequence pi line 1 <file.b.pi> > > Now this is the next problem that arises once the reDEFINE problem is > fixed: If we can define a global symbol in more than one include file, how > do we now refer to individual "redefined" symbols? You don't seem to be > offering a solution here. You mention that we need to code to make the > ambiguity go away, but how do we do that? Are you suggesting that we > manually prefix our reference to pi with the file name? Such as ... You are quite correct, in a literal sense. I am not offering a solution "here", if by "here" you mean the current paragraph. If, however, you had read further, you would have discovered that I offer exactly the same solution as you do, in a later paragraph. > ----------------- > include file.a > include file.b > > x = sin(file.a.pi + a) * cos(file.a.pi + b) > ----------------- Well, you are going to have to manually pre-fix the variable with SOMETHING, unless you let Euphoria do it for you. There's no other option, other than letting Euphoria select at random. I certainly agree that the syntax 'file.a.pi' is awkward, which you would have discovered if you had read ahead. > I hope not, because I still feel that file names make poor namespace ids. > For example, if I have to code pi in many places, and prefix each the the > file name, I suspect that the file name would be something other than > "file.a", maybe "transandentals.e" which makes for one long prefix. Then > what if I change the file name to something else. I now have to edit my > code in many places to reflect the new file name. This might happen if yet > another author supplies a better transandental library! > I'd rather do this... > ----------------- > include transandental.e as tl > include file.b > > x = sin(tl:pi + a) * cos(tl:pi + b) > ----------------- Which is exactly what I suggested when I wrote: include file.b as B > then if I change the library ... > ----------------- > include new_improved_transandental_library.e as tl > include file.b > > x = sin(tl:pi + a) * cos(tl:pi + b) > ----------------- > > > One problem remains: > > Only one!?!?! I wish. > > >imagine the following scenario: > > file.a declares atom pi > > file.b declares sequence pi > > file.c includes file.a and file.b > > > > Which pi does file.c refer to? > > Maybe you didn't write file.c, and CANNOT change it. > > So how is Euphoria to know how to properly qualify > > the references to 'pi' in file.c? > > Well I presume this can only happen if a newer version of either file.a > and/or file.b was supplied after file.c was created. Otherwise the author > of file.c ought to have resolved this issue already. What if the author of file.c (let's call it Win32Lib), isn't also the author of file.a and file.b? Should he prevent the author(s) of those files from making changes / improvements / upgrades for the sake of his program? Or should he 'fork' their code and create new, incompatible with everything else versions of file.a and file.b to be reserved (and maintained) just for use in Win32Lib? Suppose the author(s) of file.a and file.b don't WANT unauthorized changes to be made to their code, because downloading an un-authorized copy might break their existing programs, and get undeserved complaints? > > Short answer; Euphoria CAN'T know - you have to tell it. > > If you can't modify either file.a, file.b or file.c, how do you > > do this? With advance instructions. > > Hang on. What makes you think I know which 'pi' file.c needs? If I can't > inspect file.c it might be a bit difficult to determine. Even if I come to > the conclusion that file.c was using the 'pi' in file.b because file.a is > the new one, how do I know if this the best choice. I'm not the author of > file.c, file.b or file.a so I'd be making an educated guess, but still a > guess. If you can't inspect file.c, then how are you using it? Pure guesswork? More likely, you have a list of the global variables and functions declared within and available for your use. (a.k.a. documentation), or you have the source to read. If it comes down to guessing, I am fully confident that your best guess would be better than Euphoria's, which is the only alternative I can see, other than contacting the authors of the other files to ask them. > It could be that I don't even know which files are being included inside > file.c! Reallly? Let's examine that possibility, with the assumption that you have neither the source nor the documentation for file.c: 1. You don't have the proper include. Here's what Euphoria currently reports: test.exu:1 can't open grump.e or /home/irv/euphoria/include/grump.e include grump.e Perfectly adequate, no changes needed, or possible. You just go get grump.e 2. You do have the needed include, and it's the only one which declares a global "pi". The program runs. Just like it does now. You don't need to do anything further. Again, no changes are needed in Euphoria. 3. You have the required includes, but two or more use the same global identifier. Here's what Euphoria says about that situation now: file.b:1 <== here's the second file which declares 'pi' attempt to redefine pi global sequence pi <== here's the type You'll note that in paragraph 3, I suggested the possibility of expanding this message to indicate not just the second instance, but both instances of the declaration: Possible message: Warning - Duplicate identifiers: file.a atom pi line 2 <file.a.pi> file.b sequence pi line 1 <file.b.pi> Is this not enough information to determine which includes are used? > > Before you include file.c, you've got to tell Euphoria > > how to qualify the pi in file.c, when it does read in file.c. > > Your syntax may vary, but I suggest: > > > > include file.c using pi from file.a -- simple, no? > > No. Not simple at all. If I pick the wrong 'pi' I could be causing other > problems. If you change or use any variable or function without knowing what you're doing, it could cause problems. Why are you picking the wrong "pi"? If you don't know which "pi" to USE, how on earth are we to trust you to CHANGE the SOURCE of the file where "pi" is declared - thus breaking not only your own program, but everyone else's as well? > However, I agree that this is a real issue that should be addressed. > > My "solution" is that the author of file.c should be more careful. That > author should have already resolved future clashes before they could > happen. > FILE.C is > ------------- > include file.a as a > include file.b as b > > x = y * a:pi > -------------- > > Now when a new version of file.b is introduced that has 'pi' in it, file.c > is already protected because it specifically refers to the version of pi it > wants. Call it defensive coding if you like. Here, I agree with you. That was what prompted my comment that library files should be required to use the extended "include ... as" syntax. The current alternative is to use names so obscure that no one else would ever dream of using them. We're finding that that's not a practical alternative. > I know that this doesn't resolve the situation you cite, and I don't really > know how to do that safely. I thought I explained that fairly clearly. I repeat: So how is Euphoria to know how to properly qualify the references to 'pi' in file.c? Short answer; Euphoria CAN'T know - you have to tell it. If you can't modify either file.a, file.b or file.c, how do you do this? With advance instructions. Before you include file.c, you've got to tell Euphoria how to qualify the pi in file.c, when it does read in file.c. Your syntax may vary, but I suggest: include file.c using pi from file.a -- simple, no? There's no other place where you can expect to control the names of globals, except AT THE TIME EUPHORIA LOADS THEM. And that's the appropriate place to do so, since you are the only one who is using that exact combination of files. You have, by electing to use a set of include files, created a unique situation. It's up to you to make that situation work, not by having others change their code, nor by you changing their code, but by YOU changing YOUR code. Euphoria should make this easy. I think the method described above is straightforward and simple. Best of all, it can't BREAK anything, AFAIK. If anyone sees how this will break things, please explain. Regards, Irv