Microsoft Research sites tend to be based in collaborations with university research labs.
Oh that should help with the project's stability and funding.
https://github.com/facebookincubator/cinder
cinder includes changes for immutable module objects. I wonder if the implementation is similar? Or is cinder so old that it would be incompatible with the future noGil direction?
1: https://www.microsoft.com/en-us/research/wp-content/uploads/...
so when you create a new call stack ( generator, async sth, thread) you can create a twig/branch, and that is modified in-place, copy on write.
and you decide when and how to merge a data branch,there are support frameworks for this, even defaults but in general merging data is a deliberate operation. like with git.
locally, a python with this option looks and feels single threaded, no brain knots. sharing and merging intermediate results becomes a deliberate operation with synchronisation points that you can reason about.
Maybe not as performant as if you designed your data structures around it. But certainly achievable.
however it's not what I have in mind
the point is not being able to dog and patch object graphs
the point is copy on write of data that isn't local to the current call stack, automatic immutability with automatic transients per call stack.
a delta will then guide the merge of branches. but the Delta emergency from the CoW, instead of being computed as in deepdiff.
It’s also amazing how much work goes into making Python a decent platform because it’s popular. Work that will never be finished and could have been avoided with better design.
Get users first, lock them in, fix problems later seems to be the lesson here.
Sure, maybe a committee way back in 1990 could have shaved off of some the warts and oopsies that Guido committed.
I’d imagine that said committee would have also shaved off some of the personality that made Python an enjoyable language to use in the first place.
People adopted Python because it was way nicer to use compared to the alternatives in say, 2000
Or with a less cynical spin: deliver something that's useful and solves a problem for your potential users, and iterate over that without dying in the process (and Python suffered a lot already in the 2 to 3 transition)
This is why taxi drivers should run the country!
If it was just slow because it was interpreted they could easily have added a good JIT or transpiler by now, but it's also extremely dynamic so anything can change at any time, and the type mess doesn't help.
If it was just slow one could parallelise, but it has a GIL (although they're finally trying to fix it), so one needs multiple processes.
If it just had a GIL but was somewhat fast, multiple processes would be OK, but as it is also terribly slow, any single process can easily hit its performance limit if one request or task is slow. If you make the code async to fix that you either get threads or extremely complex cooperative multitasking code that keeps breaking when there's some bit of slow performance or blocking you missed
If the problem was just the GIL, but it was OK fast and had a good async model, you could run enough processes to cope, but it's slow so you need a ridiculous number, which has knock-on effects on needing a silly number of database/api connections
I've tried very hard to make this work, but when you can replace 100 servers struggling to serve the load on python with 3 servers running Java (and you only have 3 because of redundancy as a single one can deal with the load), you kinda give up on using python for a web context
If you want a dynamic web backend language that's fast to write, typescript is a much better option, if you can cope with the dependency mess
If it's a tiny thing that won't need to scale or is easy to rewrite if it does, I guess python is ok
See Smalltalk, Common Lisp, Self.
Their dynamism, image based development, break-edit-compile-redo.
What to change everything in Smalltalk in a single call?
a becomes: b
Now every single instance of a in a Smalltalk image, has been replaced by b.
Just one example, there is hardly anything that one can do in Python that those languages don't do as well.
Smalltalk and Self are the genesis of JIT research that eventually gave birth to Hotspot and V8.
An additional asset was the friendliness of the language to non-programmers, and features enabling libraries that are similarly friendly.
Python is also unnecessarily slow - 50x slower than Java, 20x slower than Common Lisp and 10x slower than JavaScript. It’s iterative development is worse than Common Lisp’s.
I’d say that the biggest factor is simply that American higher education adopted Python as the introductory learning language.
But Java is too bureaucratic to be an introductory language, especially for would-be-non-programmers. Python won on “intorudctoriness” merits - capable of getting everything done in every field (bio, chem, stat, humanities) while still being (relatively) friendly. I remember days it was frowned upon for being a “script language” (thus not a real language). But it won on merit.
Feature is what you want, and performance, and correctness, and robustness; not code
Older code is tested code, that is known to work, with known limitations and known performances
And if you already have some code, simplifying it is also an option.
Any fool can write code.
So...a new language? I get it except for borrow checking, just make it GC'ed.
But this doesn't work in practice, if you break compatibility, you are also breaking compatibility with the training data of decades and decades of python code.
Interestingly, I think as we use more and more LLMs, types gets even more and more important as its basically a hint to the program as well.
It is similar to how Assembly developers thought about their relevance until optimising compilers backends turned that into a niche activity.
It is a matter of time, maybe a decade who knows, until we can produce executables directly from AI systems.
Most likely we will still need some kind of formalisation tools to tame natural language uncertainties, however most certainly they won't be Python/Rust like.
We are moving into another abstraction layer, closer to the 4GL, CASE tooling dreams.
I think, as happens in the AI summer before each AI winter, people are fooling themselves about both the shape and proximity of the “AI dominated future”.
If, as you seem to imply and as others have stated, we should no longer even look at the "generated" code, then the LLM prompts are the programs / programming language.
I can't think of a worse programming language, and I am not the only one [2]
However, it does indicate that our current programming languages are way to low-level, too verbose. Maybe we should fix that?
[1] http://www.softwarepreservation.org/projects/FORTRAN/BackusE...
[2] https://www.cs.utexas.edu/~EWD/transcriptions/EWD06xx/EWD667...
https://en.wikipedia.org/wiki/Programming_language_generatio...
But speaking more seriously, how to get this deterministic?
Probably some kind of formal methods inspired approach, declarative maybe, and less imperative coding.
We should take an Alan Kay and Bret Victor like point of view where AI based programming is going to be in a decade from now, not where it is today.
The right distinction is that assemblers and compilers have semantics and an idea of correctness. If your input doesn't lead to a correct program, you can find the problem. You can examine the input and determine whether it is correct. If the input is wrong, it's theoretically possible to find the problem and fix it without ever running the assembler/compiler.
Can you examine a prompt for an LLM and determine whether it's right or wrong without running it through the model? The idea is ludicrous. Prompts cannot be source code. LLMs are fundamentally different from programs that convert source code into machine code.
This is something like "deterministic" in the colloquial sense, but not at all in the technical sense. And that's where these arguments come from. I think it's better to sidestep them and focus on the important part: compilers and assemblers are intended to be predictable in terms of semantics of code. And when they aren't, it's a compiler bug that needs to be fixed, not an input that you should try rephrasing. LLMs are not intended to be predictable at all.
So focus on predictability, not determinism. It might forestall some of these arguments that get lost in the weeds and miss the point entirely.
> Most likely we will still need some kind of formalisation tools to tame natural language uncertainties, however most certainly they won't be Python/Rust like
We are already on the baby steps down that path,
https://code.visualstudio.com/docs/copilot/copilot-customiza...
Granted, lot's of different compilers and arguments depending on packages. But you need to match this reproducibility in a fancy pants 7GL
That is why on high integrity computing all layers are certified, and any tiny change requires a full stack re-certification.
"It means same source, same flags, same output", it suffices to change the CPU and the Assembly behaviour might not be the same.
Yes, it's true that computer systems are nondeterministic if you deconstruct them enough. Because writing code for a nondeterministic machine is fraught with peril, as an industry we've gone to great lengths to move this nondeterminism as far away from programmers as possible. So they can at least pretend their code code is executing in a deterministic manner.
Formal languages are a big part of this, because even though different machines may execute the program differently, at least you and I can agree on the meaning of the program in the context of the language semantics. Then we can at least agree there's a bug and try to fix it.
But LLMs bring nondeterminism right to the programmer's face. They make writing programs so difficult that people are inventing new formalisms, "prompt engineering", to deal with them. Which are kind of like a mix between a protocol and a contract that's not even enforced. People are writing full-on specs to shape the output of LLMs, taking something that's nondeterministic and turning into something more akin to a function, which is deterministic and therefore useful (actually as an aside, this also harkens to language design, where recently languages have been moving toward immutable variables and idempotent functions -- two features that combined help deal with nondeterministic output in programs, thereby making them easier to debug).
I think what's going to happen is the following:
- A lot of people will try to reduce nondeterminism in LLMs through natural language constrained by formalisms (prompt engineering)
- Those formalisms will prove insufficient and people will move to LLMs constrained with formal languages that work with LLMs. Something like SQL queries that can talk to a database.
- Those formal languages will work nicely enough to do simple things like collecting data and making view on them, but they will prove insufficient to build systems with. That's when programming languages and LLMs come back together, full circle.
Ultimately, my feeling is the idea we can program without programming languages is misunderstanding what programming languages are; programming languages are not for communicating with a computer, they are for communicating ideas in an unambiguous way, whether to a computer or a human or an LLM. This is important whether or not a machine exists to execute those programs. After all, programming languages are languages.
And so LLMs cannot and will not replace programming languages, because even if no computers are executing them, programs still need to be written in a programming language. How else are we to communicate what the program does? We can't use English and we know why. And we can't describe the program to the LLM in English for the same reason. The way to describe the program to the LLM is a programming language, so we're stuck building and using them.
Lemme ELI5
https://github.com/llvm/llvm-project/tree/main/llvm/test/Cod...
You see how this folder has folders for each target? Then within each target folder there are tests (thousands of tests)? Each of those tests is verified deterministically on each commit.
Edit: there's an even more practical way to understand how you're wrong: if what you were saying were true, ccache wouldn't work.
If we're one year away from realizing a brave new world where everyone is going straight from natural language to machine code or something similar, then any work to make a "python 4" - or any other new programming languages / versions / features - is rearranging deck chairs on the Titanic. But if that's 50 years away, then it's the opposite.
It's hard to know what to work on without being able to predict the future :)
They already can.
If you're even luckier it will perform the desired function fast enough.
Why not spend the money on lottery tickets instead?
Consider a language designed only FOR an LLM, and a corresponding LLM designed only FOR that language. You'd imagine there'd be dedicated single tokens for common things like "class" or "def" or "import", which allows more efficient representation. There's a lot to think about ...
Lots of people had predicted that we wouldn’t have a single human-driven vehicle by now. But many issues happened to be a lot more difficult to solve than previously thought!
Oh, there's a bug in this test case, deletes test case.
Oh, now we're missing a test case, adds test case.
Lather, rinse, repeat.
My feeling is unless you are using a formal language, then you're expressing an ambiguous program, and that makes it inherently buggy. How does the LLM infer your intended meaning otherwise? That means programmers will always be part of the loop, unless you're fine just letting the LLM guess.
Kernighan's Law - Debugging is twice as hard as writing the code in the first place.
So what happens when an LLM writes code that is too clever for it to debug? If it weren’t too clever to debug it, it would have recognized the bug and fixed it itself.
Do we then turn to the cleverest human coder? What if they can’t debug it, because we have atrophied human debugging ability by removing them from the loop?
Rust only does this because it targets low-level use cases without automatic memory management, and makes a conscious tradeoff against ease of programming.
Code in the spirit of rust with python syntax and great devx. Give up on C-API and backward compat with everything.
Re: lifetimes
Py2many has a mojo backend now. You can infer lifetimes for simple cases. See the bubble sort example.
Beyond that, a Python with something like lifetimes implies doing away with garbage-collection - there really isn't any need for lifetimes otherwise.
What you are suggesting has nothing to do with Python and completely misses the point of why python became so widely used.
The more general point is that garbage collection is very appealing from a usability standpoint and it removes a whole class of errors. People who don't see that value should look again at the rise of Java vs c/c++. Businesses largely aren't paying for "beautiful", exacting memory management, but for programs which work and hopefully can handle more business concerns with the same development budget.
Also a reminder that Rc, Arc, and Box are garbage collection. Indeed rust is a garbage collected language unless you drop to unsafe. It’s best to clarify with tracing GC which is what I think you meant.
On the contrary, having both allows the productivity of automatic resource management, while providing the necessary tooling to squeeze the ultimate performance when needed.
No need to worry about data structures not friendly to affine/linear types, Pin and Phantom types and so forth.
It is no accident that while Rust has been successful bringing modern lifetime type systems into mainstream, almost everyone else is researching how to combine linear/affine/effects/dependent types with classical automatic resource management approaches.
Just want you to know this heart monitor we gave you was engineered with vibe coding, that's why your insurance was able to cover it. Nobody really knows how the software works (because...vibes), but the AI of course surpasses humans on all current (human-created) benchmarks like SAT and bar exam tests, so there's no reason to think its software isn't superior to human-coded (crusty old non "vibe coded" software) as well. You should be able to resume activity immediately! good luck
Vibe coding will be normalized because the vast, vast majority of code is not life or death. That literally what “normal” means.
Exceptional cases like pacemakers and spaceflight will continue to be produced with rigor. Maybe even 1% of produced code will work that way!
Things that used to work just fine are already breaking badly because of AI.
By the way, wouldn't it be possible to have a garbage-collecting container in Rust? Where all the various objects are owned by the container, and available for as long as they are reachable from a borrowed object.
There are alternatives out there
Besides the effects type system initially introduced to support multicore OCaml, Jane Street is sponsoring the work for explicit stack allocation, unboxed types, modal types.
See their YouTube channel.
Who are we trying to fool?
There’s no way they would move to, say, PyPy as the official implementation - let alone to a VM designed for a completely different language.
So they sounded out the Faster CPython team, which is now fired (was van Rossum fired, too?):
"Over the last two years, we have been engaging with the Faster CPython team at Microsoft as a sounding board for our ideas."
And revive the subinterpreter approach yet again.
Being afraid of concurrency, or pointers or whatever; makes no sense.
Being aware, on the other hand, is a very good idea.