One question we occasionally hear is: "Can't we just ditch this Parrot thing and implement Perl 6 on .NET/Mono?" Jesse asked me to write up a few comments in response.
On the surface, the two are very similar. Both have the goal of acting as a host for multiple languages and allowing interoperability between those languages (that is, allowing libraries written in one language to be loaded and called from code written in another language). Both take the strategy of compiling source down to an intermediate form and then to bytecode (there's nothing original there).
Why is it important to develop Parrot?
Mozilla has a tagline that appears over and over again in their documentation and press releases: "promoting choice and innovation on the Internet". This is an important mission. In fact, I'd take it a step further: "promoting choice and innovation in technology". Parrot fills the same role in virtual machines and compiler tools that Firefox fills in browsers and Linux fills in operating systems.
I won't go into the potential legal issues of Mono/.NET here, except to note it as another reason for innovation. There are plenty of places you can read about the issues if you're interested.
What are some of the innovations of Parrot?
.NET's Common Language Infrastructure (CLI) addresses language interoperability by constraining the high-level semantics of the languages that run on it (defined in the Common Language Specification, or CLS). Individual compilers can choose to ignore the contstraints, but if they do they're marked as "non-compliant", and can give up hope of interoperability (as well as other privileges). These constraints hinder the natural evolutionary process of computer languages, thereby presenting an obstacle to innovation.
Parrot takes a very different approach to interoperability. Rather than constraining high-level semantics, Parrot's constraints are at the assembly language level. Basically, your high-level language can do anything you want, the compiler just breaks the steps down into a series of low-level operations. This isn't a terribly strenuous demand, as the semantics are constructed from low-level operations anyway (ultimately all languages compile down to machine code). The objects shared across languages have to be able to perform (or intelligently decide not to perform) a set of assembly language operations, but they don't have to guarantee any particular high-level semantics. As Larry put it when we were asked this question at Google recently, "We won't try to make every language into C#."
Parrot targets dynamic languages. .NET targets static languages. The JVM has just barely started to scratch the surface of dynamic languages by adding an opcode for dynamic dispatch, but they're still a long way off. It's certainly possible to implement a dynamic language in a static-centric VM. It's been done before and will be done again. But it's harder than it should be, and the compiler writer ends up reinventing wheels in several places where the VM could provide standard tools. With the technology available today, there's really no excuse for that. It's not even harder to write a dynamic-centric VM than a static-centric VM, just different.
While most VMs are stack-based, Parrot is register-based. This means Parrot can take advantage of decades of research in optimizing register-based (hardware) machines. It allows greater encapsulation and control in the internals of Parrot. As far as we can tell so far, it's also a speed advantage, as it significantly reduces the number of operations spent moving data around. One of the complaints about register-based machines has been that while stacks are virtually unlimited, you always run out of registers. Parrot solves this by allowing variable-sized register frames (that is, a virtually unlimited number of registers, with the number of registers varying from one compilation unit to another).
Parrot uses a continuation passing style (CPS) of control. Rather than pushing a return address onto a control stack before a call and popping it back off when the routine is done, CPS captures a continuation (containing all the lexical variables, control context, and meta-information about the caller's environment), passes it into the called routine, and invokes that continuation when the routine is done. For a detailed explanation, you can't do better than read Dan's blogs on CPS and why Parrot went with it. CPS has advantages for optimization, security, and for ease of implementing modern language features like coroutines, generators, exceptions, and backtracking in regular expressions.
One of the core goals of Parrot is cross-platform support. .NET targets Windows, Mono currently runs on Windows, Linux, Solaris, OpenBSD, FreeBSD, NetBSD, Mac OS X, and HP-UX. Perl 5, in various versions, runs on a much larger number of platforms, including AIX, BeOS, BSD/OS, Cygwin, DG/UX, DYNIX/ptx, Embedix, EPOC, FreeBSD, GNU Darwin, HP-UX, IRIX, Linux, LynxOS, Mac OS Classic, Mac OS X, Minix, MorphOS, MPE/iX, MS-DOS, NetBSD, NetWare, NonStop-UX, OpenBSD, OS/2, OS/400, Plan 9, PowerMAX, QNX, RISCOS (Acorn), Solaris, Syllable, Symbian, Tivo, Tru64, Ultrix, U/WIN, VMS, VOS, WinCE, Windows 3.1/95/98/Me/NT/2000/XP, z/OS. The highly portable nature of Perl isn't an accident of history, it's an important feature. Parrot will provide that portability to any language running on it, which is an appealing bonus for compiler writers.
And those are just a few points.