Re: symbol resolution (was:EuCOM : Attn Matt : String Return Value)

new topic     » goto parent     » topic index » view thread      » older message » newer message

CChris wrote:
> 
> I do not see how, within your framework, an application is protected from a
> new non interface global identifier popping in a lib's newer version and
> clashing
> with an existing symbol in the application. Could you explain how it does?

OK, I think I didn't make clear exactly which clashes it will prevent.  It
will prevent any namespace conflicts from happening within the third party
libraries.  Code that uses the different libraries will still have to
disambiguate which symbols they wish to use.  This can be easily done
with namespaces.  The assumption is that the third party libraries do
not use symbols in places where they are not directly or indirectly included.
 
> More generally, I'd like to see a precise documentation of the new working of
> namespaces you are suggesting. It would be much better than just exhibiting
> a dozen of contrivedly simple test files, however relevant and useful they may
> be.

Here's a shot at it:

Terms:
include directly: When one file (f1) includes another file (f2), f1 is
    said to include f2 directly
include indirectly:  A file (fx) is said to be included indirectly into 
    another file (f1) when there is a series of direct includes linking
    f1 and fx (e.g., f1->f2->...->fx)
included symbol: A symbol is said to be included into a file if it is
    a global symbol that has been either directly or indirectly included
    by the file

When the parser encounters a symbol that could resolve to multiple global
symbols, the parser will attempt to use included symbols over non-included
symbols.  Since the author included a file that exported a symbol with
the name being used, it is reasonable to assume that the desired symbol
is the one that was included.

If a namespace identifier is used, symbols in the file with the declared
namespace are checked for first.  If none exist, then the parser will
attempt to use symbols included by the namespaced file.  If multiple
included symbols match, then a compile error occurs.  To use these symbols,
additional namespaces must be used for the respective files.

If a non-included symbol is used, a warning will be generated.

> Most people run without warning anyway, if only to avoid the silly short
> circuit
> stuff, or "parameter not used" when they are not required in an actual routine
> but the prototype cannot change. They are practically useless, even though
> they
> convey useful information.

While I tend to run without warning, I usually at least attempt to get rid
of warnings before release.  Most of my warnings are relatively harmless
(unused variables--bad for maintenance, but probably not going to cause
any errors).  These warnings really do signify the possibility of bad
things ahead.

> > I was considering writing the additional wrappers to be equivalent to 
> > editing third party code.  I guess I just don't understand why anyone would
> > want to have to create these wrappers if there were no need.
> >  
> 
> As long as there is no clash, there is no need. 
> Even though it would be nicer for the user to have a wrapper supplied by the
> library maintainer, there is no obligation to do so. Either the application
> coder or any fourth party can supply one.

Yes, I understand that, but I'm saying that there's a better way to solve
this; one that doesn't require the new file in the first place.
 
> > I wasn't concerned as much with interpreter code.  As I see it, my 
> > proposal just does the obvious thing when resolving symbols, and warns when
> > there is no such obvious thing, or errors when there are conflicting 
> > obvious things.  There's not really any increased mental load for the
> > coder.  Having to manage import lists is just a way to make explicit
> > things that are actually pretty obvious, IMHO.
> 
> Except when they are not. Besides, my solution also makes it possible to
> extend/redefine
> routines, which is currently tricky and limited, and about which I don't see
> how your solution helps.

You're right.  That's not part of what it does.  I'd like for you to please
expand upon "Except when they are not."

> > Here's why I don't think it's counter-intuitive.  When looking at the file,
> > how can you tell where the symbol is meant to come from?  The file *does*
> > have a dependency on its parent file.  No more symbols are made visible
> > than already exist for the child file.
> 
> Sometimes you just cannot, because the file is meant to be included by several
> possible parent files. So at least you should provide a special syntax for
> "include
> parent file". Or have a reserved namespace to designate symbols known to come
> from some ancestor (in inclusion tree). Writing relations with parent in
> concrete
> runs counter to any code reuse strategy.

I disagree.  In fact, I think it improves code reuse.  If you take a look at 
what I've done with the interpreter code, you'll see that these issues have
been cleared up.  There are a couple of additional files used to declare
data.

I'd argue that not defining your dependencies (i.e., what external symbols 
do you depend upon?) make code reuse more difficult, since you end up
getting really tightly coupled modules that cannot be easily separated.

If you're really dependent on parent symbols, then you probably have a 
poor design (I've done this myself, and paid for it).  It's probably
better to remove the symbols to a third file, and have both parent and
child use that file.  Relationships are clearer, and you don't need to
do weird stuff like stick the include halfway down the parent file.

> > I'd note that it's not a required thing.  The difference is that it prevents
> > an entire class of bugs from occurring.  If the include statement is really
> > that odious, you could put "without warning" in the file.  Unlike your
> > approach, if you follow this rule, and don't let the warnings slide, then
> > you're *guaranteed* to avoid namespace conflicts with other third party
> > code.
> >
> 
> I don't think there is any guarantee, because there are just so many ways
> clashes
> can happen. Again, where are the complete docs? That's the only way one can
> tell.

Well, I think an audit/test of the code would be a better way to really tell,
but I think my docs do a decent job of describing the behavior.  I'd be
grateful if you could find holes in my approach.  A single counter-example
would suffice.
 
> > My problem is that it doesn't really prevent name clashes.  True, it gives
> > the user tools with which to fight back, but why require extra work
> > where it's not needed?
> 
> The advent of name clashes depends on a specific combination of libraries and
> application code. So, I don't believe a simple change of rules will prevent
> all cases. And user still cannot fignt back without editing third party code.

Again, please provide an example where my methodology fails.  I don't 
see it, but I may be too close.
 
> > 
> > I also disagree that my approach is a Band-Aid.  It is, rather, a fairly
> > comprehensive solution to getting code from multiple libraries to play
> > nicely.  No currently working code would break, but would allow code
> > out there that currently conflicts to work immediately (some libraries 
> > might require some minor changes--i.e., adding a few include statements).
> > 
> 
> Adding the include statements may well have other side effects under your
> scheme.
> So, assuming it would only take this amount of work (which I certainly don't
> believe), a few library maintainers will need to run another cycle of tests
> and release newer versions. Now you are a user and have been waiting for three
> years for the next release, how about that? My solution allows for things to
> start working (again) now, and the library updates, while welcome, will come
> when they may.

It's true that some third party (multi-file) libraries may require some
rework.  I didn't find any warnings with win32lib, however, which has to
be the most used and most complicated of them all.  My solution will solve
most cases where combinations of libraries will fail.  The only time it
won't prevent this is when the libraries use non-included symbols, which
I believe is probably not very common.  In those cases, some action is
required.  However, the action is the insertion of a few include statements.

It does not require anything nearly as complex as your method.  As an
example, how would you solve this issue:
-- app.ex
include libMatt.e
include libCChris.e
...

-- libMatt.e
include libMatt1.e
? x

-- libMatt1.e
global constant x = "Matt1"

-- libCChris.e
include libCChris1.e
? x

-- libCChris1.e
global constant x = "CChris1"

This is a simple demonstration of exactly the sort of problem I'm solving
here.  Line 2 of libCChris.e will error, because it doesn't know whether
it should use libMatt1:x or libCChris:x under current symbol resolution.
But I think that it's clear to anyone looking at the code that it's
really trying to use libCChris1:x.

This is a huge problem that shouldn't exist.  It makes it difficult to
use multiple libraries together, because you end up having to edit the
code...every time it's updated...

> And I still uphold that your solution, while it certainly improves on current
> Eu, addresses only part of the related issues, and will make the remainder
> more
> difficult to solve in the future. This is exactly what P. Robinson and I were
> calling "Band-Aid".

I have never said that it attempted to solve multiple problems, but I do
believe that its the best way to solve this particular problem.  Thinking
that something to hide information is going to solve this problem is
just wishful thinking.  I'd reply that your method for solving namespace
conflicts a Band-Aid approach to that problem.  

Please show me your solution to the above example, and we'll go from there,
and we'll be able to compare.  Note that my methodology requires no code
chages.

> > I now understand you.  As mentioned above, it just gives a coder a 
> > framework to solve the problems.  I just prefer a simpler approach.
> > 
> 
> It uses no new syntax, but is not simpler to handle and certainly leaves more
> issues standing.

I don't understand why it's not simpler to handle.  Once you've submitted
a response to the above problem, maybe we'll have a better basis for
comparison.  Feel free to post other problems, so that we can compare the
solutions (Pete: you, too...).  Well, I'd argue that they leave completely
different issues standing, because they're attacking different problems.

> > I was thinking about the problem differently, as something that could be
> > 95% solved by the interpreter, rather than 50%.  OK, numbers are made up,
> > but my real point is that under my system, you can write code that will
> > 100% play nicely with other code.  If anything conflicts, the user just
> > has to use a namespace to differentiate between your library and someone
> > else's.
> 
> This isn't even different of how it works now. The more I read, the less
> problems
> I see your scheme solving.

Actually, there are some important (subtle, perhaps) differences.  I hope
that the above example helps to illustrate this.

> > 
> > There are no new keywords.  No new syntax.  And coders get an extra warning
> > that is extremely valuable in pointing out a potential problem. 
> > Essentially,
> > as long as your library is error free, you can be confident that anyone
> > can simply include it into their code, and it won't cause any namespace
> > conflicts (of course, other, poorly written code might).
> 
> These statements are not backed by any evidence, and I simply don't think they
> are true. Actual, detailed documentation is required to assess the scheme; I
> tried to come up with one for mine: let me know what is missing. Of course I
> agree with poor code always causing trouble, but at least let give users tools
> to manage it, as the poor code sometimes is the only available one.

As I documented above, the change is simple, but powerful.  I stand behind
my assertion.  If anyone can post some (warning free) code as a counter
example, then I'll back down, of course.  There is a problem right now 
where you couldn't use libMatt and libCChris in the same application without
editing one or both of them.  It's simply impossible.  My change allows them
to live together without having to change them at all.

Matt

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu