A vision for Parrot

Benjamin Goldberg goldbb2 at earthlink.net
Fri Nov 8 04:00:45 EST 2002


Walter Roberson wrote:
> 
> In article <aqbimo$a36$1 at news.ox.ac.uk>, Frodo Morris  <""> wrote:
> :Perdantick bast.  :-)
> 
> Hmmm, according to OED, "bast" means "sanctuary, refuge, asylum".
> 
> :Imagine if parrot could understand all currently- and popularly-
> :implemented interpreted languages.
> 
> Such as Forth, Word Perfect Macros, Microsoft Visual Basic,
> and Befunge?? (You haven't been very specific on the meaning of
> 'popularly'.)

Is it (currently) possible to put Word Perfect macros into a file, and
run that file as a script?

And I think that it's actually highly probable that a translator from
MSVB to Parrot will be written... or rather, a translator from MSIL or
from .NET to Parrot.

> Now, Parrot is intended for interpreted languages, right? And
> the fundamental feature of such languages is that you should
> be able to compute a string and then execute the string as
> a statement. So Parrot will have to know how to execute statements
> in arbitrary source languages.

Well, not parrot *itself* ... you'll have a compiler (written in parrot)
which translates the other language to parrot bytecode.  When some piece
of code does eval $string, it calls to the translator, then runs the
resultant bytecode.

> This means that it isn't enough to have a (say) bash-to-parrot
> translator that translates the program and hands it off to parrotd:
> the entire translator is going to have to be input along with the
> translated source.

Fortuantly, parrot is able to defer loading of modules until they're
needed.  You hand off the translated source, and as soon as it runs into
an eval $string operation, it loads up the translator, then runs the
translator and continues on it's merry way.

> This indirectly raises an interesting point. If parrotd is glued into
> the operating system as part of exec() as has been proposed (as
> opposed to the counter proposal to just let #! do its standard job)
> then the implication is that there is only one parrot implimentation
> per system.

Yes, this does sound like what was being proposed.

However, nothing prevents you from having more than one parrot kernel
plugin, the selection of which would be distinguished by a version
number in the header of the bytecode file.

> How would one then test new versions of Parrot?

Well, instead of typing in "bytecodeprogram" at the commandline, you
would have to type in "parrot bytecodeprogram", where "parrot" is your
path to your newer version of parrot.

Or perhaps you would do:
   parrot_daemon --nokernel &
   parrot_send_to_daemon bytecodeprogram

(or something like that)

Obviously this won't be *quite* the same environment as the kernel's
plugged-in parrot interpreter daemon, but it will be sufficiently close
for *most* forms of testing.

> With #! it's easy: you just name the path to the alternative
> interpreter and the kernel invokes it. But if parrotd is built right
> into exec() then in order to support multiple versions of Parrot, you
> would have to build the new versions -in- Parrot and pass them in as
> yet another layer of interpreter.

I don't understand what you mean by this.

> e.g., parrotd version 6.302 is running and it has been passed a copy
> of the bash2parrot 4.19 translator

Err, no.  You would have a program which was originally written in bash,
then translated into parrot bytecode.  All places where strings need to
be translated at runtime (via the eval command) are set up to load up
the bash translator, then translate that string, then run the string.

The bash2parrot translator would not be *included* in the translated
bytecode, though -- only the name of the module, or maybe the filename
of the module.  Vaguely like how one shared object can depend on another
one, or even whole reams of other ones -- but they don't get loaded
until functions in them get called.

> in case it needs to interpret a computed string that invokes a program

Ok, at this point, stop, and take a breath.  When your translated bash
program wants to "invoke a program", *how* that program's guts work is
beyond it's concern -- it merely calls fork and exec and wait.

The fact that the exec() may send the filename and args and environment
to a different parrot daemon is irrelevant to that process.

> that needs to layer on the experimental parrotd 6.4.9 interpreter that

What do you mean 'layer on' ?

> has to be passed the perl2parrot translator in case it needs to

Again, nothing is passing around translators -- they only get loaded
when they are needed.

> interpret a computed string that invokes a program
> that needs to have -another copy- of parrotd 6.302 layered on [you
> can't count on parrotd 6.4.9 running parrotd 6.302 programs the same
> way that parrotd 6.302 would run them] that has the <etc.> interpeter
> layered on to run <etc.>.

Your confusion seems to mainly stem from three things:  You're not
paying attention to process boundaries, and you think that every
translated program in language X has the translator for X to parrot
embedded into it, and exec() doesn't invoke a sub-process, it replaces
the current process with a new process  (That's why you have to fork()
first if you want a sub-process).

Once you have a better understanding of the unix process model, the
problems you've sketched will disappear.

> Scheme is right at home at dealing with these kinds of layering
> issues, using a process called "reflection" [well developed by Brian
> Reid and Jeem Desriviers]. They aren't straight-forward issues: think
> about debugging, and think about re-entrancy, and think about problems
> in cross-layer pollution -- you don't want a wild pointer in the fifth
> layer down to affect your third layer, right?

Fortuantly for us, seperate processes have their own memory address
spaces, so this isn't a concern.

> Speaking of layers: I take it that some thought has been put into
> how to do operating-system escapes? So that one can (for example)
> handle graphics? Or even just sockets? Seeing as some of the most
> popular interpreted languages are by no means restricted to text-only
> and have networking capabilities?

Remember, the parrot interpreter is written in C... it has to be. 
Obviously, one would have parrot opcodes which result in calls to C
functions, which perform socket operations or graphics or whatever.

> But of course the appropriate calls could come within one of the
> computed strings, so any escape cannot be absolute and must instead be
> handled via the interpretation layer (c.f. the above in which I showed
> that parrotd must be built in Parrot if you want parrotd to be handled
> at the exec() level...)

You can't write parrotd in parrot -- you have to write it in something
which runs on the hardware (elf or a.out).

Writing parrotd in parrot is similar to writing a turing machine VM in
the language you use to write descriptions of turing machines, and then
having exec() detect when you're running a compiled turing machine and
handing it off to the turing machine VM ... if it doesn't get passed off
to *something* running on the actual hardware, it's going to loop
forever.

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]



More information about the Python-list mailing list