Why Python is not both an interpreter and a compiler?

Ben Finney ben+python at benfinney.id.au
Mon Aug 31 13:41:33 CEST 2015


Mahan Marwat <mahanmarwat at gmail.com> writes:

> What I know about an interpreter and a compiler is: they both convert
> source code to machine code

Yes, Python implementations always compile the source code to machine
code. The target machine for the Python compiler, though, is a virtual
machine which then gets emulated by a Python runtime interpreter.

You can prove this by doing *only* the compile step, and later do
*only* the interpret step::

    $ python -m compileall foo.py
    Compiling foo.py ...

    $ python foo.pyc
    Hello, world!

So anything which is going to run your Python source code first needs
that source code to be compiled to machine code, and then later use an
interpreter to run that machine code.

That's true of pretty much every programming language today: To run it,
the source code is first compiled to a machine code, which is then
interpreted at run-time by some 

You might want to target some other machine code; ultimately, you might
want to the machine code of the CPU you intend to run the program. That
is a special case, though, and is by far not the only case of compiling
code.

> and the only difference is, an interpreter convert it, line by line
> while compiler convert the whole source file.

Hmm, by that definition, there are almost no language interpreters in
use today for running a program – not Python, not Ruby, not JavaScript,
not Perl – that meets your definition. They all need a compiler first to
produce machine code from the source code file.

> Now if we compile a C source file on C compiler, it will produce a
> small executable file. But if we compile (freeze) a Python source file
> on Python interpreter (using cx_freeze), it will produce a big
> executable file.

Yes, that's because the C language is low-level enough that a compiler
can target directly the host CPU's machine code. A Python program,
though, is written in a dynamic language, which is compiled to a virtual
machine code, which needs the Python virtual machine as well to
interpret that machine code.

> Now the thing is C compiler does not embed a C compiler inside our
> program, while the Python interpreter (cx_freeze, pytoexe) embed
> Python interpreter inside our program, what is the reason?

Because Python is a dynamic language. A great many facts about the
run-time state are deferred to be figured out at run-time, so can't be
decided at compile time. The resulting machine code assumes a very
powerful, dynamic machine language, which is not the same as the host
CPU's machine language.

> Cant we program a language, which is both interpreted and compiled?

I hope you see now that Python is both interpreted and compiled, by
necessity.

What you seem to want is a Python compiler that targets the host CPU;
but your target host CPU can't execute the dynamic runtime that Python
machine code needs.

In other words: The very dynamic nature that makes Python so expressive,
succinct, and efficient to write, makes it that much more distant from
the extremely low-level machine operations of the host CPU. That power
comes at the cost of a level of abstraction, in the Python virtual
machine interpreter.

-- 
 \       “Pray, v. To ask that the laws of the universe be annulled in |
  `\     behalf of a single petitioner confessedly unworthy.” —Ambrose |
_o__)                           Bierce, _The Devil's Dictionary_, 1906 |
Ben Finney



More information about the Python-list mailing list