4 ms·
You have a very specific idea of what an "interpreter" is that I don't think matches the standard usage. The debate would be better served if we spoke in more c
by dvdkon 3y ago
You have a very specific idea of what an "interpreter" is that I don't think matches the standard usage. The debate would be better served if we spoke in more concrete terms such as local/global scope, parser, analyser, AST or runtime library.
- thaumasiotes 3y agoI've taken the word from the comment I responded to. It appears to refer to the part of the process that is responsible for determining what a line of code written by the programmer is supposed to do. The particular task of resolving references isn't necessarily handled by anything you mentioned - it is the job of the parser to determine that a reference is being made, but not whether that reference goes anywhere. Similarly, this information is not included in the abstract syntax tree, which is fundamentally the same thing as the parser. It's perfectly possible to form a syntax tree that calls for the invocation of a function that doesn't exist, or assignment to a variable that doesn't exist. In C writing an invocation of a function that doesn't exist will give you a compiler error, but in Python it won't; you'll get working code that trusts that whenever it happens to be invoked, the function will exist. And if, at invocation time, it doesn't, you'll get a runtime error instead. Since this is the problem being addressed by the "interpreter", it appears to be the case that the interpreter in C exists at a different point of the compilation-execution pipeline than the interpreter in Python. The logical steps of determining what a program does need not coincide with the physical steps that are taken to convert the program into an executable artifact - or more fastidiously, they don't need to occur in the same order from program to program, and might be bundled with different other steps. But what I've claimed is that the import facility, whatever it might be, is responsible for making changes to the state of the interpreter, wherever the interpreter might be active. It makes the difference between "the programmer has specified doing something meaningless" and "the programmer has specified doing something meaningful", and the meaning that it provides gets loaded into the state of the interpreter. It is not strictly necessary that this occur at the top level of the program, the global scope, but it is almost always the case because that is the scope where programmers almost always want imported code to be available to them. > In C, if I include "a.h" and then "b.h", "b.h" will have access to definitions from "a.h", even though lexically they were never brought into scope in that file. This actually appears to be the opposite of the normal concern with lexical scope. Lexical scope allows names defined at a higher scope to be accessed from a lower scope, but that's precisely what you're trying to prevent here. It's worth noting that b.c is compiled without any knowledge of a.h or a.c (assuming it doesn't itself #include a.h, which would make the problem you mention something intentional instead of a pitfall). "libb" doesn't suffer any problems from being #included after "liba". The problem occurs in your code, where you have access to definitions from both header files, which is what you wanted when you #included both of them.