RPython¶
There is an introduction to RPython in the RPython language documentation, which explains what subset of Python constitutes valid RPython.
It is not critical that you read that page from top to bottom (yet, probably not even at all at least for today).
The most important things to remember from the start are:
- You cannot mix objects of “un-unifyable” types in the same collection.
Lists must contain all strs, or all instances of a class. It does not
have to be the same exact class, the classes just have to be unifyable,
which means that there is some common base class between them (at the
RPython level this cannot be
object
, so you can’t mix ints with instances of your RPython class). Relatedly, you can mixNone
with some types, but not others. See the documentation page above for details. - Most of the (Python) standard library (and similarly external modules) are not valid RPython. There is a separate, smaller RPython standard library. With a few exceptions, it comprises the external RPython code you have available.
- Write simple code and it is likely to be easily converted to RPython even if it is invalid. If your code is complex, it will likely need untangling once you try and translate it.
Unfortunately the most important rule though is the one at the top of the documentation, that if it translates, it’s valid, and if it ain’t, it isn’t.
Two Specific Notes¶
Besides the above, there are two specific things which you might find surprising initially that are worth learning upfront.
Firstly, the RPython toolchain will expect an entry point similar to
the one expected when writing C code. By default it will expect a
function called main
in the file you pass to the rpython
binary
(explained shortly). The function should return an int
as main
would in C. This is where the translation process which we’ll discuss
(as well as your interpreter) will begin.
Secondly, the assert
statement in RPython has special semantics. Whereas in
Python it is generally used to describe invariants that should never be false
in a piece of code, in RPython it additionally makes an assertion of that
invariant to the toolchain itself so that the toolchain can make use of that
information.
As a quick example, you’ll likely soon notice once we begin writing our parser that the toolchain will complain during translation if for instance you have:
class Parent(object):
...
class ChildA(Parent):
attr_only_on_this_child = 12
class ChildB(Parent):
...
and you try and access attr_only_on_this_child
even if you only pass in
instances of ChildA
. You will need to tell the toolchain that you are
guaranteeing that only instances of ChildA
will be there, and not
ChildB
, and the way to do so is by saying assert isinstance(myinstance,
ChildA)
, which signals that exact fact.