There are many different sources of information in a program, and a tool or a human interpreting code will not in general have full information, but will still want to draw conclusions about the code.
Different languages take different approaches to this problem. For example:
In Carbon, information is accumulated incrementally within each source file. Carbon programs are invalid if they would have a different meaning if more information were available.
Carbon source files can be interpreted top-down, without referring to information that appears substantially later in a file. Source files are expected to be organized into a topological order where that makes sense, with forward declarations used to introduce names before they are first referenced when necessary.
If a program attempts to use information that has not yet been provided, the program is invalid. There are multiple options for how this can be reported:
Disallowing programs from changing meaning in the context of more information ensures that the program is interpreted consistently or is rejected. This is especially important to the coherence of generics and templates.
impl needs to be resolved, only those impl declarations that
have that appear earlier are considered. However, if a later impl
declaration would change the result of any earlier impl lookup, the
program is invalid.Because a class is not complete until its definition has been fully parsed, applying this rule would make it impossible to define most member functions within the class definition. In order to still provide the convenience of defining class member functions inline, such member function bodies are deferred and processed as if they appeared immediately after the end of the outermost enclosing class, like in C++.