You know, Herman, I was trying to run this simple script the other day to analyze some local weather data—just a few CSV files and a basic regression model—and I spent two hours just trying to get the environment to stop screaming at me. It is the classic Python paradox. It is arguably the most readable, beginner-friendly language in the world, yet it requires what feels like a master’s degree in systems administration just to get your first line of code to execute without a dependency error. It is March eighth, twenty-twenty-six, and I feel like I am still fighting the same battles I was fighting a decade ago.
Ah, the rite of passage. Welcome to the club, Corn. It is a frustration every single developer in the AI space knows intimately. Our housemate Daniel actually sent us a prompt about this very thing this morning. He was asking about the history of Python and why this language, which was never really designed for high-performance computing, ended up becoming the undisputed king of artificial intelligence. And more importantly, why the setup is such a nightmare. It is a fundamental question because it touches on the very soul of how we build software today.
It is a great question because it feels like a massive contradiction. We are in twenty-twenty-six, we have these massive, multi-trillion parameter models that can basically pass the Turing test while writing poetry, and the "backbone" holding them together is a language that was started as a hobby project during a Christmas break in the late nineteen eighties. I am Corn Poppleberry, by the way, and joining me as always is my brother.
Herman Poppleberry here. And you are right, Corn. To understand why Python won the AI race, you have to look back at nineteen eighty-nine. Guido van Rossum, the creator of Python, was working at a research institute in the Netherlands. He wanted a language that was "beautiful, explicit, and simple." He was actually working on a language called ABC, which was designed for teaching, but it wasn't extensible enough. So, over his Christmas break, he started writing Python. At the time, if you wanted to do serious computing, you were using C or Fortran. Those languages are fast, but they are incredibly unforgiving. They require you to manage memory manually, and they take forever to write.
So Python was the "anti-C" in a way? It prioritized the human over the hardware. It was about making the developer's life easier rather than making the processor's life easier.
It was designed as a "glue language." That is a term we use a lot, but it is worth defining. The idea was that you would write your heavy, performance-critical logic in a low-level language like C, and then use Python to "glue" those pieces together into a coherent workflow. And that right there is the secret. That is the "Aha!" moment for why it dominates AI today. Python was never meant to be fast itself; it was meant to be the best possible interface for things that are fast. It was the ultimate middleman.
That is an interesting way to frame it. So, it is not that Python is the engine of the car; it is the steering wheel and the dashboard that makes the engine usable for a human being. But why did that specifically matter for AI? Why didn't something like C plus plus just stay the standard? If AI is all about heavy math, wouldn't you want to stay as close to the metal as possible?
Because AI research is fundamentally iterative. If you are a researcher in the early two thousands or even the early twenty-tens, you are constantly changing your model architecture. You are tweaking hyperparameters, you are swapping out layers, you are trying new activation functions. If you have to recompile your entire codebase every time you change a single line of code, your research slows to a crawl. Python allowed for rapid prototyping. You could write an idea in ten lines of Python that would take a hundred lines of C plus plus. The "time to market" for an idea was just so much faster in Python.
I remember we touched on some of this in episode one thousand one, when we were talking about the "invisible history" of AI. There was this long period where the hardware wasn't quite there—the "AI Winter"—but the software foundations were being laid. It seems like Python was the perfect tool for that "marathon" because it allowed researchers to focus on the math and the logic rather than the memory management and pointer arithmetic.
Precisely. And that leads us to the first big technical pillar of Python’s dominance: NumPy. Before NumPy, which really solidified in the mid-two thousands, Python was actually quite terrible at math. It was slow and clunky for large datasets. But NumPy introduced the "ndarray" or N-dimensional array. It was a Python interface, but underneath the hood, it was calling highly optimized C and Fortran libraries like BLAS, which stands for Basic Linear Algebra Subprograms, and LAPACK.
So when I am doing a matrix multiplication in a Jupyter notebook today, I am not actually using Python for the math? My computer isn't actually running Python code to multiply those millions of numbers?
Not at all. You are using Python to tell a very fast C-kernel to do the math. This is what we call the "C-extension" bridge. It is the reason Python survived. If Python had tried to do linear algebra in pure Python, it would have been a thousand times slower, and it would have died in the laboratory. But because it acted as a high-level API for low-level kernels, it gave researchers the best of both worlds: the speed of C and the ease of a scripting language. It solved the "Two-Language Problem" by simply embracing both languages.
That makes sense. But it still doesn't explain why we aren't all using Julia or something newer. I have heard people say Julia was built specifically to solve this "two-language problem" from the ground up—the need to write in both a slow, easy language and a fast, hard one. Why did Python keep the crown even when technically superior languages arrived?
Momentum and the "Batteries Included" philosophy. By the time Julia or even Mojo came around, the Python ecosystem was already too massive to ignore. You had libraries like Scikit-Learn for traditional machine learning, Pandas for data manipulation, and then eventually Theano. Theano is a name people forget now, but it was the pioneer. It was developed at the University of Montreal and it paved the way for TensorFlow and PyTorch. It introduced the idea of a computational graph that could be compiled to run on GPUs.
So Python was already the "lingua franca" by the time the deep learning revolution hit in twenty-twelve?
When AlexNet won the ImageNet competition in twenty-twelve, the world realized that neural networks were the future. And because all the researchers were already using Python for their data cleaning and their basic stats, the frameworks for deep learning were naturally built for Python. If you are an AI engineer, you don't just want a fast language; you want a language that already has every library you could ever need. Python became a social network—the value is in the number of people using it. It is the network effect for code.
It is a network effect for code. But this brings us to the second half of the question Daniel was asking about, and honestly, the part that drives me the most crazy. If Python is so "simple" and "beautiful," why is the environment management so notoriously difficult? Why do I need venv, and Conda, and Poetry, and Docker just to make sure a script I wrote six months ago still runs today? Why does it feel like I am building a house of cards every time I run "pip install"?
This is where the "feature, not a bug" argument comes in, though it certainly feels like a bug when your terminal is full of red text. The problem stems from Python’s greatest strength: its dynamic nature and its "global" philosophy. In the early days, Python expected you to install everything globally on your system. But as the AI field exploded, we started seeing what we call "Dependency Hell."
Right, where Library A needs Version One of a package, but Library B needs Version Two of that same package, and they both live in the same folder on your computer. And since they have the same name, they just overwrite each other.
And because Python is a dynamic, interpreted language, it doesn't "know" there is a conflict until you actually try to run the code. Unlike a language like Go or Rust, which compiles everything into a single, static binary where all the dependencies are baked in at the start, Python is constantly looking at your system’s folders at runtime to find what it needs. It is searching through paths. If those folders are a mess, or if a version has changed since you last ran the script, the whole thing collapses.
I see. So the reason we have all these "virtual environments" is basically to create a clean, isolated "sandbox" for every single project. It is like giving every project its own private little computer so they don't fight over the toys. But it feels so heavy. Why can't Python just be smarter about it?
Because in AI, we aren't just managing Python code. We are managing those C-extensions we talked about earlier. This is the "C-boundary" problem. When you install a library like PyTorch, you aren't just downloading Python files. You are downloading pre-compiled binary files—shared objects or DLLs—that have to be compatible with your specific operating system, your specific CPU architecture, and—most importantly in AI—your specific version of CUDA if you are using an NVIDIA GPU.
Oh, I have been there. The "CUDA version mismatch" is probably responsible for more lost productivity in the last decade than any other single technical issue. You have CUDA twelve point four installed, but the library wants twelve point one, and suddenly nothing works.
It is the "Arc of Deprecation" we talked about back in episode eight hundred eight. The pace of AI is moving so fast that a library from twenty-twenty-four might require a version of a driver that was deprecated by twenty-twenty-five. Because Python relies on these external, low-level drivers and C-libraries, the "glue" starts to peel off if the underlying surfaces change. Python is trying to manage things that are actually outside of its own control. It is like trying to manage a construction site where the bricks and the mortar are being updated by different companies every week.
So, when we say that the complex setup is a "feature," what we really mean is that it is a necessary consequence of the language's flexibility? If we wanted a language that was "easier" to set up, we would have to give up the ability to easily wrap all these high-performance C and C plus plus libraries. We would lose the very thing that made Python successful in the first place.
Precisely. Python is essentially an "orchestrator." It is managing a very complex dance between high-level logic and low-level hardware. The "setup" is you defining the rules of that dance. If you don't define them exactly right, the dancers crash into each other. Other languages avoid this by being more rigid—by forcing you to define everything upfront or by bundling everything together—but that rigidity is exactly what AI researchers didn't want. They wanted the freedom to experiment, to swap things out, to be messy.
It is almost a philosophical trade-off. You trade "Ease of Deployment" for "Ease of Expression." And for the last fifteen years, the industry has decided that Ease of Expression is more valuable. We would rather spend two hours setting up an environment if it means the actual coding takes two hours instead of two weeks. But Herman, we have to talk about the Global Interpreter Lock, or the GIL. I hear people complaining about that all the time when they talk about Python's limitations.
The GIL is the "boogeyman" of Python. It is a mechanism that prevents multiple native threads from executing Python bytecodes at once. This means that even if you have a sixty-four-core processor, a single Python process is mostly only using one core for the Python parts of the code. For a long time, this was a huge bottleneck. However, in the last couple of years—specifically with PEP seven hundred three—there has been a massive push to make the GIL optional. By twenty-twenty-six, we are finally seeing "No-GIL" Python builds becoming stable.
Does that change the game for AI?
It helps with data processing and multi-threaded tasks, but remember, the heavy lifting in AI happens on the GPU or in those C-extensions anyway. Those libraries already bypass the GIL. So while the GIL is a famous "flaw," it actually didn't stop AI from succeeding because the AI community figured out how to work around it decades ago. They just moved the work out of Python and into the C-layer.
It is fascinating. We have built this entire multi-billion dollar industry on a language that we are constantly trying to "bypass" or "work around." It is like building a skyscraper on a foundation of very flexible, very smart rubber. But I wonder if that is sustainable. As we move toward edge AI—putting these models on phones, on small devices, or even integrated into hardware—does the "Python tax" become too high? You can't exactly run a Conda environment on a smart watch very easily.
You are hitting on a very hot topic in the industry right now. There is a real push toward what people are calling "Production AI." This is where things like Mojo come in. Mojo, which was released a few years ago by Chris Lattner’s team, is really interesting because it claims to be a "superset" of Python. It looks like Python, it feels like Python, but it compiles down to machine code like C plus plus. It is designed to be the "fast" version of Python that doesn't need the "glue" because it is the engine and the dashboard all in one.
I have been watching Mojo closely. It feels like the natural evolution—taking the lessons of the last thirty years and trying to fix the architectural debt. But can it really displace Python?
It is the "English language" problem, Corn. Even if you designed a "better" version of English that was more logical and had fewer irregular verbs, good luck getting everyone to switch. Everyone already speaks English, so they keep using it. Python is the English of the technical world. It is messy, it has a million weird rules, and its "spelling"—or in this case, its environment management—is a nightmare. But it is how we all communicate. The sheer amount of data science knowledge, tutorials, and existing codebases in Python is a massive "moat."
So, for the listeners out there who are currently staring at a "ModuleNotFoundError" or a "Version Conflict" in their terminal, what is the practical takeaway? How do we stop fighting the environment and actually get to the code? Because it feels like we spend fifty percent of our time just "preparing to work."
My first piece of advice is: stop trying to be a hero and install things globally. Never, ever use "sudo pip install." Use virtual environments religiously. Whether it is the built-in "venv" module or something more robust like Poetry. If you are doing serious AI work, you really should be looking at Docker. Containerization is the only way to truly "freeze" an environment in time. It takes all those C-extensions, those CUDA drivers, and those Python packages and wraps them in a single image that will run the same way today as it will in five years.
I have started using Docker for more of my projects lately, and it does feel like a weight has been lifted. It is more overhead initially—you have to write the Dockerfile, you have to wait for the image to build—but it saves you so much "setup debt" down the road. It is basically the ultimate "version control" for your entire system, not just your code.
And the second takeaway is to respect the "C-boundary." Understand that when you are working in Python for AI, you are working on a very thin layer of ice over a very deep ocean of C plus plus and Fortran. When something breaks, it is often because that ice has cracked. Don't just blindly "pip install" everything. Look at the requirements. Look at the versions. Use "lock files."
Can you explain why "locking" dependencies is so critical? I think a lot of people just have a "requirements dot text" file and think that is enough.
Oh, this is a huge trap. If your "requirements dot text" file just says "torch" or "pandas," then every time you run "pip install," it grabs the latest version. But if the latest version of Torch changed a function name or dropped support for your specific GPU driver, your code breaks. A "lock file," like what you get with Poetry or Conda, records the exact version of every single sub-dependency. It ensures that the "graph" of your project never changes. It is the only way to ensure reproducibility in AI research.
It goes back to what we discussed in episode eight hundred nine, about "Context Engineering." It is not just about the prompt you give the AI; it is about the entire technical context in which that AI is running. If the underlying library version changes, the behavior of the model might change in subtle ways that are really hard to debug. You might get a slightly different result in a medical diagnosis or a financial prediction just because a linear algebra library was updated.
That is a very subtle but important point, Corn. People don't realize that a change in a library version can actually change the "floating point" math slightly. If you are doing mission-critical AI—say, in healthcare or defense—you cannot have that kind of variability. You need bit-for-bit reproducibility. Python’s environment tools are our only way to enforce that.
It is fascinating to think about. We think of code as this abstract, logical thing, but it is deeply tied to the physical reality of the hardware and the specific versions of the binaries. Python is just the "interface" that tries to hide that complexity from us, but it can only hide it for so long before it bubbles up to the surface. The "setup" is the moment where the abstraction fails and you have to face the reality of the machine.
And that is why we have this "setup" ritual. It is the price we pay for the power. I actually think it makes us better engineers, in a way. You have to understand your stack. You can't just be a "script kiddie" if you want to be a serious AI practitioner in twenty-twenty-six. You have to understand the interplay between the operating system, the drivers, the libraries, and the code.
I suppose it is a bit like being a professional photographer. You don't just point and shoot; you have to understand the lenses, the lighting, the sensor, and the post-processing. The "setup" is part of the craft. It is the "darkroom" of the digital age.
And honestly, it is part of why the AI community is so tight-knit. We have all suffered through the same CUDA errors. We have all spent Friday nights debugging a broken Conda environment. It is a shared struggle that has forged a very resilient ecosystem. When you see a fix for a specific dependency error on Stack Overflow, that is someone reaching out across the void to help you through the same "Dependency Hell" they just escaped.
So, looking forward to the rest of twenty-twenty-six and beyond... do you think Python stays at the top? Or do we see a "Great Migration" to something else as the "Python tax" becomes more apparent?
I think we see a "Hybrid Era." Python will remain the interface for research and high-level orchestration. But we will see more and more of the "heavy lifting" being moved into more specialized languages. You will see "Python wrappers" around Mojo kernels, or "Python interfaces" for Rust-based data pipelines. Python isn't going anywhere, but it might become a "thinner" layer as we focus more on efficiency and deployment. It is the "glue" that refuses to dry. It just keeps evolving to hold new things together.
It is the world’s most successful, messiest, most indispensable glue. It is the duct tape of the high-tech world.
That is a perfect analogy. You wouldn't build an entire airplane out of duct tape, but you’d be surprised how much of it is holding the non-structural parts together.
Well, I feel a lot better about my two-hour environment struggle now. It wasn't just me being incompetent; it was me participating in a thirty-year-old architectural tradition. I was "interacting with the abstraction layer," as you put it.
You weren't wasting time; you were performing the necessary maintenance on your technical stack.
I will tell that to Daniel next time he sees me yelling at my monitor. Speaking of which, we should probably wrap this one up. It has been a deep dive, but a necessary one for anyone trying to make sense of why the AI world looks the way it does. If you are listening to this and you have your own "Dependency Hell" horror stories—maybe you spent a whole weekend trying to get a twenty-twenty-three model to run on a twenty-twenty-six machine—we would love to hear them. You can get in touch with us through the contact form at myweirdprompts dot com.
And if you found this exploration of Python’s quirks and history helpful, please consider leaving us a review on your podcast app or on Spotify. It really does help the show reach more people who might be struggling with their own "ModuleNotFoundError" right now. It is the best way to support the show.
Yeah, a quick rating goes a long way. You can find our full archive of over a thousand episodes, including the ones we mentioned today like episode eight hundred eight on the "Deprecation Trap," at our website, myweirdprompts dot com. We have a full RSS feed there for subscribers as well.
It has been a pleasure as always, Corn. I think I am going to go see if I can break my own environment now, just for fun. I have a new experimental build of Python thirty-four I want to try out.
Spoken like a true nerd. Good luck with that, Herman. Thanks for listening to My Weird Prompts. I am Corn Poppleberry.
And I am Herman Poppleberry. We will see you in the next episode.
Take care, everyone. Stay curious, and maybe... just maybe... use a virtual environment.
Always use a virtual environment. Goodbye!