1. 3.2, namespace and symbol resolution -- Matt?

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

new topic     » topic index » view message » categorize

2. Re: 3.2, namespace and symbol resolution -- Matt?

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: 3.2, namespace and symbol resolution -- Matt?

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: 3.2, namespace and symbol resolution -- Matt?

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu