1. 3.2, namespace and symbol resolution -- Matt?
- Posted by Jeremy Cowgar <jeremy at c?wgar.c?m> Apr 18, 2008
- 510 views
Matt, Can you expand on this a bit? I'm reading in the release notes about this and wondering if it's something I should be making use of w/the new standard library. -- Jeremy Cowgar http://jeremy.cowgar.com
2. Re: 3.2, namespace and symbol resolution -- Matt?
- Posted by Matt Lewis <matthewwalkerlewis at ?m?il.com> Apr 18, 2008
- 514 views
Jeremy Cowgar wrote: > > Matt, > > Can you expand on this a bit? I'm reading in the release notes about this and > wondering if it's something I should be making use of w/the new standard > library. Not really. It mostly means that things should just work most of the time. One of the big problems was if two third party libraries declare global symbols with the same name. If you write an app that uses either library, everything is fine. If you (in the 3.1.1 and before world) try to include both in your app, it won't work. Whichever library you included second will end up with a namespace conflict, unless the author use a namespace when he used the global symbol. Even if you always use namespaces in your code to refer to those symbols, you still have to modify the third party code, which is bad. The changes for 3.2 look at the way the files are included to see if it's possible to resolve the symbol. Since neither library includes the other, the interpreter knows to use the correct symbol. The namespace improvement allows you to use namespaces to refer to symbols included by the file you actually gave the namespace. This would allow you to, for example, use a single win32lib namespace to also refer to global symbols in other win32lib files (stuff like w32memory.ew). Matt
3. Re: 3.2, namespace and symbol resolution -- Matt?
- Posted by Derek Parnell <ddparnell at ?i?pond.com> Apr 18, 2008
- 505 views
Matt Lewis wrote: > One of the big problems was if two third party libraries declare global > symbols with the same name. Here's a thought or two ... Firstly, some principles ... (A) A file should only be able to 'see' global symbols that have been defined in another file, if the first file has actually included it (directly or indirectly). (B) A developer should never have to modify an included file in order to resolve a name clash. With these two principles in mind, most things will work out of the box. But there are a couple of situations that need special treatment. There are times though when a file actually needs to see a 'foreign' global symbol - usually one that has been declared in the file that is inclucing the file that wants access. (eg. FOO.EX includes BAR.E, and BAR.E wants to see a global defined in FOO.EX). Assuming that we can't alter BAR.E but we can alter FOO.EX, I propose a new statement - 'export'. The 'export' statement would make the exported symbol global and available to included files. So in our example, we would place lines like this in FOO.EX ... export constant magic_word = "xyzzy" include bar.e Now BAR.E can see the magic_word. If magic_wod was just a global, BAR.E should not be able to see it. I know this breaks existing functionality but it might be worth it. The other situation, which a lot more common, is when two included files happen to use the same name for a global symbol. The first suggestion I have for this is whenever a global constant has the same name and same value as another global constant, they should be considered to be the same thing - and not cause a name clash. So, when FOO.EX include BAR.E and includes NAT.E, and both BAR and NAT define a global symbol called 'cave' it only causes a problem for FOO.EX if that file access a 'cave' symbol. FOO.E can't see anything in BAR.E and visa versa. The current namespace concept works here for FOO.EX. include BAR.E as bar include NAT.E as nat . . . saveb = bar:cave saven = nat:cave The change that I think is need though is to have the namespace apply to all the globals that an included file can see. If we change our example slightly such that FOO.E doesn't define 'cave', but instead includes POT.E which defines 'cave'. From the point of view of FOO.EX, the 'cave' that BAT.E can see may as well been defined in BAT.E or any file that BAT.E gets to include (directly or indirectly). So, from FOO.EX's point of view, the namespace qualifier applies to all of BAT's globals. So we still do the code above to access the 'cave' defined in POT.E even though FOO.EX doesn't know about POT.E. It still uses the 'bar' namespace to get at it. One final problem is where NAT.E wants to get access to something in BAR.E but doesn't want to include BAR.E! This can happen when testing for the existance of global function names that may not exist (routine_id() returns -1). To solve this a variation of the 'export' statement might suffice... include bar.e export bar:fancy_rtn include nat.e Now code in NAT.E can see 'fancy_rtn' that is global within the BAR.E tree. Furthermore, the 'export' can be used to alias a global name ... include bar.e export bar:fancy_rtn as formatter include nat.e Now code in NAT.E can see a symbol called 'formatter' that is actually the global symbol 'fancy_rtn' defined within the BAR.E tree. So, what you all think of these ideas ??? -- Derek Parnell Melbourne, Australia Skype name: derek.j.parnell
4. Re: 3.2, namespace and symbol resolution -- Matt?
- Posted by Matt Lewis <matthewwalkerlewis at g?ail.c?m> Apr 18, 2008
- 510 views
Derek Parnell wrote: > > Matt Lewis wrote: > > > One of the big problems was if two third party libraries declare global > > symbols with the same name. > > Here's a thought or two ... > > Firstly, some principles ... > (A) A file should only be able to 'see' global symbols that have been > defined in another file, if the first file has actually included it > (directly or indirectly). As you noted below, this will break some code. I guess we need to weigh the breakage against the utility. I don't really have a problem with this. > (B) A developer should never have to modify an included file in order to > resolve a name clash. Yes. I believe that we're probably there, with the exception you noted. > With these two principles in mind, most things will work out of the box. But > there are a couple of situations that need special treatment. > > There are times though when a file actually needs to see a 'foreign' global > symbol - usually one that has been declared in the file that is inclucing the > file that wants access. (eg. FOO.EX includes BAR.E, and BAR.E wants to see a > global defined in FOO.EX). > > Assuming that we can't alter BAR.E but we can alter FOO.EX, I propose a new > statement - 'export'. The 'export' statement would make the exported symbol > global and available to included files. So in our example, we would place > lines > like this in FOO.EX ... > > export constant magic_word = "xyzzy" > include bar.e > > Now BAR.E can see the magic_word. If magic_wod was just a global, BAR.E should > not be able to see it. I know this breaks existing functionality but it might > be worth it. I agree that your solution works, but I'd like to hear a real example. Another way to solve this, which, BTW, the interpreter now uses, is to have a setter in bar.e that any including file can call to set the magic word within bar.e:
-- foo.ex global constant magic_word = "xyzzyx" include bar.e as bar bar:set_magic_word( magic_word )
Another benefit to this approach is that it's obvious that you're affecting bar.e, since you're making an explicit call. > The other situation, which a lot more common, is when two included files > happen > to use the same name for a global symbol. > > The first suggestion I have for this is whenever a global constant has the > same name and same value as another global constant, they should be > considered to be the same thing - and not cause a name clash. Hmm. This sounds like something that would have to be checked at runtime. That sounds slow. And possibly a cause of obscure bugs, because constants aren't always simple literal definitions. > One final problem is where NAT.E wants to get access to something in BAR.E but > doesn't want to include BAR.E! This can happen when testing for the existance > of global function names that may not exist (routine_id() returns -1). To > solve > this a variation of the 'export' statement might suffice... > > include bar.e > export bar:fancy_rtn > include nat.e > > Now code in NAT.E can see 'fancy_rtn' that is global within the BAR.E tree. > Furthermore, the 'export' can be used to alias a global name ... Again, I think you should some sort of setter for this. Matt