r/learnpython • • 1d ago

why do we need cpython and Python virtual machine ( that executes bytecode )?

why do we need a cpython that converts source code to bytecode and then another python virtual machine that executes this byte code? why do we have this multi layer flow? why cant just compile every code to binary and execute the binary?
Also if possible can someone explain the flow to python code from start to end ( with example and scenrio on why do we need them)
+
what advantages does python have compared to c++, javascript or java?

0 Upvotes

11 comments sorted by

3

u/vicspidy 1d ago edited 1d ago

What I have understood is this...

  1. Cross-platfrom support. You write code once and it executes on all supported platforms in similar manner.

  2. That's the role CPython plays. It hides all the complexities and work you had to do, if you wanted to run you code on all platfroms.

  3. if CPython was not there you would have to compile your code for each platform, you wanted to run your code on, every time you change your code. Like C or C++.

Basically, In case of compiled languages, you need to compile for your target os. If you target multiple OS. You need to compile multiple times

But in case of python, you can visualise CPython as your OS You write for CPython OS. It handles the rest. You don't need to know about windows, linux etc..

1

u/DueBid3298 12h ago

u/vicspidy Compiled languages also support cross-platform development; you generally compile the same source code separately for each target platform right? so what advantage does python has over compiled languages?

1

u/vicspidy 11h ago

You never need to compile your python code for different platforms because you write your code for CPython (you can assume this is your OS)

This time it is python itself which gets compiled for different OS

9

u/LayotFctor 1d ago edited 1d ago

There's nothing inherent to the Python language that forces it to be interpreted. The developers envisioned python as an interpreted language so they released Cpython interpreter as a reference implementation, but there's no reason why a compiler couldn't exist.

And there are indeed python compilers available, like micropython.

Python's advantage was always to be simple and inviting for users. It indeed is one of the most simple and nicest languages around. However, user simplicity required the interpreter to do some of the heavy lifting on the user's behalf, which often made it slightly slower. Those tools would also need to be included in any compiled binary as well, whereas a binary written in C++ wouldn't need it.

1

u/Vegetable_Soil_6707 4h ago

right, the language itself doesnt mandate interpretation, its just that the reference implementation went that route

3

u/lfdfq 1d ago

cpython is both, you don't need 'another' thing if you have cpython.

The way to think about it is that almost all implementations are going to have many layers anyway: something that turns text into tokens (lexers), something that turns tokens into more structured syntax (parsers), something that turns syntax into either machine code (codegen) or bytecode or other syntax (optimisations) and then something that executes the output machine code (the h/w) or bytecode (vm) or syntax (interpreter).

You could compile Python to machine code. I'm not sure why you say 'just' though, would it be easier or simpler to do that? If anything it'd make it more complicated, you'd have to have multiple backends for different machine architectures, or use something like LLVM (like clang does). In the end, you probably wouldn't gain much either. Python is very dynamic, so any compiler would basically have to generate a little interpreter as the output, to do all the dynamic dispatching. [EDIT: Although, if you give it enough information to remove those dispatches, a compiler could do better, and such things exist like mypyc.]

A bytecode VM is a nice middle ground for languages like Python: it strips away the syntax so you're executing something more straight-line rather than tree-shaped, and reduces a lot of complex high-level language structure to simpler blocks. Then the VM is a simple interpreter for that bytecode language, with just one implementation (cpython) and not one per architecture or something like that.

2

u/No-Dentist-1645 1d ago

Cpython does not just convert source code to bytecode. Cpython is the interpreter/virtual machine that executes this code itself, it does both things. It first converts things to bytecode because it is a more efficient representation of the instructions for itself to run.

2

u/zanfar 1d ago

why do we need a [CPython] that converts source code to bytecode and then another python virtual machine that executes this byte code?

  1. "Another virtual machine" is pretty inaccurate. The interpreter and executive (amongst may other layers you haven't named) can be implemented however the developer wants. CPython is both those layers you mentioned in one.

  2. Because it's easier.

  3. You can't make something that ends up as binary compatible across platforms. Hence why both JavaScript and Java will have differing interpreter implementations, and why C++ uses platform-specific compilers.

Also if possible can someone explain the flow to python code from start to end (with example and [scenario] on why do we need them)

This question lacks a subject. Please rephrase. Flow of what, what comes before Python? Need what?

what advantages does python have compared to c++, [JavaScript] or java?

Easy and capable.

1

u/Designer-Ad-2136 1d ago

In a compiled language, your code is converted to native binary. In CPython, the VM is converted to native binary but your code is not.

As for why the bytecode representation is needed? Bytecode is usually pretty similar to assembly/binary so it naturally maps well to the implementations of the bytecode instructions. It is also a well understood pattern and quite elegant. 

It helps a lot to look at the vm code 

1

u/CelebrityChess 1d ago

part of why it's hard to just compile python straight to a binary is that nothing has a fixed type until it runs. a + b could be ints, strings, lists, whatever, so the machine code would have to check that every single time anyway. the bytecode step is mostly there so the interpreter doesn't re-parse your text on every line, and then the vm loop runs the bytecode. you can see it yourself with the dis module, try import dis then dis.dis on a small function. tools like nuitka or cython do compile it to native but you don't get a giant speedup unless you add type info