Looks very interesting! I remember chatting with one of the creators of PyPy (not the author of TFA) a number of years ago at HPI. He had just given a talk about how RPython was used in PyPy development, and I was fascinated. To me, it seemed completely obvious that RPython itself seemed like a really interesting standalone language, but he would have none of it. Whenever I suggested that RPython might have advantage…
SPy: An interpreter and compiler for a fast statically typed variant of Python
51–60 of 133 posts
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#52It's weird, but the pain of moving to a whole new language seems less than the pain of using one of these language subsets. I guess it might be because of "loss aversion": we dislike losing something we have more the value we put on gaining it. In a new language each newly added feature is a gain, but in a language subset you're always encountering things you would have in the full language. So no matter how good the…
Exactly. I once pitched the idea of a Python subset (with a different focus, not performance like SPy), and almost every reaction was "will it support ".
For example, a new language can build its own solution for array math, or maybe that's not something its users need. OTOH many consider a Python subset to be unacceptable if it doesn't specifically support NumPy.
In the end I came to agree with https://pointersgonewild.com/2024/04/20/the-alternative-impl...:
> positioning your project as an alternative implementation of something is a losing proposition
> don't go trying to create a subset of Python [...] Do your own thing. That way, you can evolve your system at your own pace and in your own direction, without being chained by expectations that your language should have to match the performance, feature set, or library ecosystem of another implementation.
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#53> The following silly example happily passes mypy
In fairness that's because Mypy is shit. Pyright catches this mistake.
> As such, we need to treat Python type checkers more like linters than actual theorem provers
Again I think this is true of Mypy but Pyright is much closer to a sound type checker.
> redshifting
This is just constant propagation isn't it? C compilers have been doing this for decades. I don't think we need a silly new term for it. Let's not cause another "tree shaking" situation.
> So far, this is not different than usual constant folding, with the difference that it's guaranteed to happen. What makes it more powerful is the ability to mark some functions as @blue.
That's not different. It's just constant folding with C++'s `consteval`. And @blue is an absolutely abysmal name.
It would be much clearer if @blue were changed to @consteval or @comptime (either's good I think), and you just call it "compile time evaluation" or "constant propagation" instead of "redshifting".
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#54i work a lot in python and tried to build a runtime type checker for it that basically acted as automatic assertions on all stated types at function boundaries, and it worked really well to bring all TypeErrors in my code to the surface on first run.
but, my knowledge is woefully short on compilers and languages. this definitely gave me a great frame of understanding, so thanks again for writing it
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#55Common Lisp also allows you to redefine everything at runtime but doesn't suffer from the same performance issues that Python has, does it? Doe anyone have insight into this?
Common Lisp is not a runtime, it’s a specification. Implementations are free to compile everything to fast native code, or to interpret everything. Various available implementations do that and everything in between. That said , SBCL and the commercial implementations can be extremely fast, especially if you specify types on tight loops. SBCL comes with a disassembler that shows you right in the REPL the Assembly a f…
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#56It's weird, but the pain of moving to a whole new language seems less than the pain of using one of these language subsets. I guess it might be because of "loss aversion": we dislike losing something we have more the value we put on gaining it. In a new language each newly added feature is a gain, but in a language subset you're always encountering things you would have in the full language. So no matter how good the…
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#57Earlier quoted context omitted.
Common Lisp doesn't use (expensive) CLOS dispatch in the core language, e.g. to add two numbers or find the right equality operator. That's one known pain point due to CLOS having been "bolted-on" rather than part of the language which makes the divide between internal (using typecase and similar) and external (generic functions) dispatch pretty ugly; and gave use the eql/equal/equalp/etc... hell. Thing is that you n…
> and gave use the eql/equal/equalp/etc... hell. You don't like those? I've always considered them a fairly elegant deconstruction of the problem domain of equality checking. DWIM languages can get very confusing when they DWIM or don't DWIM.
Which is why https://cdr.common-lisp.dev/document/8/cleqcmp.html exists, really; all the "copy-x" would benefit from the same fix, in my opinion.
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#58But why limit to an interpreter? Translate to other excellent compiled languages and benefit from the optimization work there.
Giving up on C-API and the dynamic parts of python that 1% of the people use is a good trade-off.
In the age of cursor and windsurf it's not hard to auto replace incompatible code with something that works in the static-py ecosystem.
Would love to participate in an effort to standardize such a subset.
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#59One of the things I've spent a lot of time thinking about are the ways to avoid a lot of the dynamic features of Ruby without affecting actual, real code much.
There's a lot that can be done there - e.g. all of the research on Self and JS VMs is highly applicable.
But I say "real code" because a lot of the "worst" dynamic features of Ruby (and Python) either doesn't appear in production code very often, or at all (there are still aspects of Ruby I have never seen used in real-life use despite having used Ruby for 20 years), or could be mitigated trivially, so I still believe you can do quite decently without a lot of the more complex optimisations.
As an example (from Ruby): You can re-open the Integer class and override +:
ruby -e 'class Integer; def +(other); 42; end; end; p 2 + 2'
(don't do this in IRB; it crashes)But nobody does that. The problem with a lot of these features isn't that people use them, but that people might use them.
That leaves two main avenues: We can do like the author of thise post and strip away the costly features that are rarely used.
Or we can provide ways of promising not to use them through code or options.
The first option is perfectly valid, but I quite like the second:
In Ruby, it turns out a lot of the optimisation challenges goes away if you get an app to freeze the most important system classes after setup, because even most of the most horrific examples of Ruby monkeypatching tends to do most of it only during startup, and you then tend to get to a stable state where you can let applications opt in to additional optimisations just by calling "freeze" on a number of objects.
Ruby programs will also do things like dynamically decide which files to load based on reading the directory, but if you compile an application, most of the time you want that to happen ahead of time with a few exceptions (e.g. plugins), and so similarly, if you freeze as many classes as possible at a given point, you can partially evaluate manipulation of the runtime up until that point, and treat it as mostly static afterward, and fall back to slow paths for anything you can't statically resolve the names of, and still end up with lots of optimisation potential for most of the low level code.
I think a lot of the same would work for Python, and might bridge the gap between the categories of alternative implementations the author mentions with more predictability than relying on a JIT doing the right analysis.
E.g. your compiler can eat least potentially guarantee under which circumstances it can statically determine that an Integer can inline the fast path if Integer is frozen so that you can in fact reason about the code.
Re: SPy: An interpreter and compiler for a fast statically typed variant of Python
#60++spy ethos and ideas But why limit to an interpreter? Translate to other excellent compiled languages and benefit from the optimization work there. Giving up on C-API and the dynamic parts of python that 1% of the people use is a good trade-off. In the age of cursor and windsurf it's not hard to auto replace incompatible code with something that works in the static-py ecosystem. Would love to participate in an effor…
> 3. We have a compiler for deployment and performance. The interpreter and the compiler are guaranteed to produce the exact same results at runtime.