Learning Question
What do language tools do between source files and running behavior?
Language tools read source or code artifacts and either produce another artifact, start runtime execution, or coordinate both.
The word “tool” is broad here. It includes compilers, interpreters, assemblers, linkers, launchers, build tools, package tools, and managed runtimes.
The shared role is that a tool knows how to read one representation and move it to the next step.
Tools Are Readers With Contracts
A language tool does not read a file as generic bytes. It reads the file according to a contract.
For example:
- a C compiler reads C source code
- an assembler reads assembly source
- a linker reads object files and libraries
- a Java compiler reads Java source
- a JVM reads class files and related runtime inputs
- a Python interpreter reads Python source or cached bytecode
Each tool expects a certain kind of input. Giving the wrong artifact to the wrong reader usually fails because the format, language rules, or execution contract does not match.
Not Every Tool Produces the Same Kind of Result
Some tools mainly create stored artifacts. Some mainly start execution. Some do both.
| Tool role | Example input | Example result |
|---|---|---|
| compiler | main.c | object file or executable pipeline input |
| assembler | assembly source | object file |
| linker | object files and libraries | native executable |
| launcher | command-line request | process startup |
| interpreter | source file | runtime execution inside interpreter process |
| managed runtime | class files or bytecode | runtime-managed execution inside a process |
The boundary is not always visible to the user. A command may hide several tools behind one name.
For example, a build command may compile source files, link objects, package artifacts, and then run tests. That does not make those steps the same thing. It only means a higher-level tool coordinated them.
A Tool Can Be Both a Producer and a Consumer
Language tooling often forms a chain:
source file
compiler
object file
linker
native executable
loader
processThe compiler consumes one artifact and produces another. The linker consumes object files and produces an executable. The loader consumes the executable and creates a process image.
Managed runtimes have a different shape:
source file
compiler
class file or bytecode
runtime process
runtime-managed behaviorThe exact chain varies, but each step still has a reader, an input contract, and a result.
Why This Prevents Confusion
If you say “the compiler runs the program”, you may hide the fact that a compiler usually creates an artifact rather than hosting the final behavior.
If you say “the interpreter is just reading the file”, you may hide the fact that the interpreter process is also the runtime container where behavior happens.
If you say “the build tool made it run”, you may hide the separate roles of compiler, linker, loader, process, and runtime.
The clearer question is:
At this step, is the tool transforming representation, starting execution, or managing runtime behavior?Mental Model
Treat language tools as transition owners.
They stand between representations:
input artifact -> tool or runtime -> next artifact or runtime stateOnce you know the input and the transition owner, the next question becomes easier: what execution target is this artifact meant for?