Objective-Smalltalk runs on the Objective-C runtime, so Objective-Smalltalk methods look like Objective-C methods accessed via objc_msgSend() to the entire rest of the system, including to other Objective-Smalltalk code.
That means it doesn't really matter to the rest of the system if any particular method is interpreted, AOT-compiled or JIT-compiled. They can't tell, except for execution speed.
And of course the execution model includes machine primitives, which the interpreter also deals with but doesn't make faster, but the native compilers do.
On another note, I'm working on a (big) PEP for python, and looking for maintainers and sponsors (as per python's rules). Do someone know where I could find such amazing persons? (I already have the code, works in cython,graalVM and pypy, and it's kind of a big change but I believe it will help a lot the language)
Python already compiles to bytecode (the .pyc files are a cache thereof). It's just that interpreting even the simple bytecode instructions can take dozens of clock cycles each. I imagine that a lot of this is not in the interpreter loop (which has seen quite a bit of optimization, IIRC up to the level of "predictive" gotos within a big switch statement within a loop) but just unwrapping objects and moving values to and from registers, dealing with the fact that there is basically never any cache coherency for anything etc.
Basically I'm not convinced that writing out the set of machine-code instructions needed to interpret the bytecodes would be a big win, because it takes too many instructions for simple tasks.
[EDIT - I assume you are commenting on Dartmouth BASIC.]
Since we have to prove everything on Internet forums,
https://archive.org/details/bitsavers_dartmouthB_3679804/mod...
=> Saving of Compiled Programs
A pain point that is big enough that at least two programming languages, Julia and Mojo, were created to move beyond it.
Which would not even be an issue, if Lisp, Scheme and Prolog had not lost their aura among AI devs.
Mojo in particular recognized to compete with Python they'd have to be a superset, then they backed of that goal when they realized it would be too hard.
So at the end of the day, Python has a value proposition and it cannot be entirely subsumed by other languages, because those languages make tradeoffs that move away from Python's value.
Python has a known set of trade-offs, mostly related to loop performance. But if you understand the trade-offs and available mitigations, it should not stop you from building good software. You know, just like any other ecosystem.
Maybe also then, importing module as Cython?
import django with Cython
compiles on first run? https://github.com/py2many/py2many
https://github.com/adsharma/fquery/blob/main/tests/django_example_model.pyFolks, numba is great. To first approximation: write your python function to "look like C"[1] and work over the numpy arrays you probably already have and understand, put a "@jit" decorator on it, and you're done. It JITs and runs your code natively at native performance.
With some extra effort, there are features for SIMD vectorization and thread parallelism, and even GPU backends (that, full disclosure, I've been pretty frustrated by -- but they do work).
[1] Which is to say, don't touch Python interpreter data structures. No dicts or objects or lists or strings, etc... If you're bound by the interpreter[2] you're bound by the interpreter and nothing is going to help you.
[2] A corrolary here is that the kind of C code numba is NOT good for is "following pointers between structs", which is something that can't be expressed in either python or numpy.
That's a really intense restriction. Sounds like the name fits; it's not general purpose, it's jit for number crunching and little else.
I'm not sure exactly what you mean by "bound by the interpreter" but there's nothing about touching those data structures that requires the interpreter to be involved in most cases. The problem of slow APIs can be solved by the JIT having intimate knowledge of python's internals, can't it?
Is it? An object field access in python is a dynamic hash lookup followed by a method call as a fallback (itself involving hashed lookups up the class hierarchy). That's not an "interpreter vs. native" kind of thing, that's just the semantics of the language that have to be preserved. And that's just not going to be "fast" in the way that the user of a JIT would want. Code dominated by Python datastructures is going to be "slow" in ways that JITs can't fix, ever.
Which is why Python appears to have given up on the effort in this space. PyPy too[1] really never delivered on the desired performance gains (like 5x or so on typical code) without forcing the user into careful optimization.
Numba, to its credit, doesn't even try. It falls back to python if it must for python stuff, but is quite clear that it's providing no benefit if that's what you're doing. And the stuff it does do is obvious and clean and extremely useful.
[1] PyPy is also looking pretty moribund recently.
Maybe, but the world is still waiting for the counterexample. Python is simply not a runtime well-suited to optimization.
In the meantime, those of us who actually enjoy real HPC problems are using numba and rolling our eyes about all the confuffery around JITs. Maybe one will arrive that proves us wrong, but numba is fast today.
I don't have enough experience with PyPy to say much about it.
I don’t know how people who’ve worked with Python and been frustrated with its performance don’t know about Numba.