Like others have mentioned, the terms compiled and interpreted are specific to how a particular programming language is implemented; they do not define the language itself. For instance, there are interpreters for C.
However, we often classify programming languages based on their predominant implementation. For example, C is commonly considered compiled.
To begin, let's clearly define what interpreters and compilers are:
An interpreter for language X is a program (or machine) that runs any program p written in language X according to the specifications of X.
A compiler from X to Y is a program that translates programs from language X to equivalent programs in language Y, ensuring that the results remain consistent.
It's worth noting that CPUs can be seen as interpreters for their respective machine languages.
We can now categorize programming languages into 3 groups based on their common implementations:
- Hard Compiled languages: Programs are compiled directly to machine code without interpretation. Example: Running a C program involves compiling source code to machine language for CPU execution.
- Interpreted languages: No compilation occurs to generate new machine code; existing code is interpreted by an interpreter program. Example: In Python, code is first compiled to bytecode before being executed by an interpreter like CPython.
- Soft Compiled languages: Parts of the original program may be compiled to machine language while still relying on an interpreter. Java follows this approach, compiling code to bytecode that can be further compiled or interpreted by the Java Interpreter and JIT compiler.
Sometimes, soft and hard compiled languages are simply referred to as compiled; hence, languages like C#, Java, C, C++ fall under this category.
In the past, JavaScript was considered an interpreted language. However, modern implementations now JIT-compile it to native machine code, placing it among soft compiled languages.