Namespace AutoTyping
From dis-Emi-A
Since everything can be autotyped namespaces place a very interesting role. We are working on the assumption that namespaces are needed in order to remove ambiguity, though it is not certain that we absolutely need them, at least not in the traditional sense.
Contents |
Traditional Namespace Lookup
The way namespaces usually work (taking C++ as an example), is that you need to explicitly refer to the namespace (or import it) in order to use functions/classes from it. There is however a significant exception to this rule, one needed to make templating work. Consider the following example:
namespace one
{
class BigDecimal
{
...
bool operator<(const BigDecimal& o) const { ... }
}
}
template<class T>
T max( const T& a, const T& b )
{
if( a < b )
return b;
return a;
}
This looks like it would work fine, except that in order for the max function to work it needs to be able to see the less than operator, which unfortunately for BigDecimal is not in the same namespace as max is. In order to resolve such cases (and in general to make programming not a pain) C++ will look in the namespace of the declarations of the argument types, thus since a is a BigDecimal it is allowed to look in the BigDecimal class for an operator, and also in the namespace one. Note that this is a difficult topic, the C++ standard takes several pages to explain the lookup rules, which most programmers never think about since they generally work the way would expect.
Top Down Typing
In the the top-down typing phase the C++ style of lookup is fairly easy to implement, since you know what types you are trying to match, it is easy to determine in which namespaces you need to look.
Even within an auto-typed language, assuming the bottom-up typing has been completed, it is easy to look through the list of possible function calls and simply discard those that don't match the existing scope conditions.
Bottom Up Typing
In the bottom up typing phase lookup through namespaces becomes a particular problem. Consider a simple function like Java's toString, and then the following function.
DebugObj :> x
{
print( "Log " ++ x.toString() );
}
There is one scenario for DebugObj for every single class defined in the system. This particular step is okay to handle, but now think about the callers of DebugObj and you have a massive number of scenarios that need to be considered. Further to that the compiler then needs to consider whether it is to compile all those various forms, or simply produce an abstracted form and use an interface to the classes -- or a bit of both in various situations.
But, relating back to namespaces, if you look at C++'s rules for lookup you may realize that since we don't know the type yet, we have no idea in which namespaces we need to look for matching functions. Therefore we have no choice but to look for all matching functions in all possible namespaces and then rely on the top-down typing to select the one which is valid. This again may yield compiler situations with too many possible scenarios, so we'll have to define veyr clear rules and think of some efficient selection algorithms.
Exclusion Principle
Seeing as though, from bottom-up typing, we'll need to consider all items across all namespaces/scopes in at least one step, we might as well state that this is just the way it works always: namespaces by default do not create different scopes for the items they contain.
Refer to Example:Need for Global Function Name Lookup
No Explicit Inclusion
In general, from auto-typing, we don't actually need to select namespaces, consider the following:
namespace A
{
class AA
{
title;
}
}
namespace B
{
class BA
{
nextNode;
}
}
...
obj1.title //obj1 must be of type A::AA since it has the title member and B::BA does not
...
Through the auto-typing one can see that for the most part only one type will be applicable in most circumstances, or you are generally creating a parametric function in which both types can work. Therefore you in general don't need to specifc the namespaces.
Exclusion
Though the eventuality will come that one needs to resolve ambiguities with which the compiler just doesn't have enough information to resolve. In such cases some kind of limiting use is needed.
Obviouslly the fully typed name will always be allowed on a declartion, but since the language doesn't usually need declarations we don't want to leave that as the only system (otherwise we'll lose that nice benefit of auto-typing).
So we can introduce keywords, some possibilities are:
- exclude namespace
- Do not consider anything with the given namespace within the current "scope"
- limit namespace
- Consider only items from the listed namespaces
We can look more closely at what is required as we get to some examples of more complex programs.
