This is outcome of Armin's and Samuele's ideas and our discussion, kept together by fijal.
Communication layer is the layer which takes care of explicit communication. Suppose we do have two (or more) running interpreters on different machines or in different processes. Let's call it local side (the one on which we're operating) and remote side.
What we want to achieve is to have a transparent enough layer on local side, which does not allow user to tell the objects local and remote apart (despite __pypy__.internal_repr, which I would consider cheating).
Because in pypy we have possibility to have different implementations for types (even builtin ones), we can use that mechanism to implement our simple RMI.
The idea is to provide thin layer for accessing remote object, lays as different implementation for any possible object. So if you perform any operation on an object locally, which is really a remote object, you perform all method lookup and do a call on it. Than proxy object redirects the call to app-level code (socket, execnet, whatever) which calls remote interpreter with given parameters. It's important that we can always perform such a call, even if types are not marshallable, because we can provide remote proxies of local objects to remote side in that case.
XXX: Need to explain in a bit more informative way.
Suppose we do have class A and instance a = A() on remote side and we want to access this from a local side. We make an object of type object and we do copy __dict__ keys with values, which correspond to objects on the remote side (have the same type to user) but they've got different implementation. (Ie. method calling will look like quite different).
Reminding hpk's example of 5-liner remote file server. With this we make:
f = remote_side.import(open) f("file_name").read()
We need: