The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Project Development

The Parrot project is specially organized to be light-weight and efficient. The project is governed like a meritocracy--people who make valuable contributions are offered more responsibility. Communication is relaxed and informal, often intermittent through email and on IRC. As Dan is so fond of saying, "This is far too important to take seriously." The Parrot developers act a bit like a special forces unit--the objective is pursued not because of tight control from the top, but because the whole team knows the task at hand and does it.

Development Cycles

The Parrot development cycle centers on regular "point releases." A point release is a version change, such as 0.4.x to 0.5.x. The architect and project manager decide when point releases happen and what features are included. Usually one or two solid new features trigger a point release.

Development proceeds at a steady pace with bugs reported, patches submitted, and patches applied. The pace isn't so much a result of careful planning as it is the law of averages--on any given day, someone, somewhere, is working on Parrot. In periods of high activity there are often many more people working on Parrot then just one. A release represents a spike in that activity, but since Parrot tends to follow the "release early, release often" strategy, these spikes are relatively small.

Typically, the release manager for the month declares a feature freeze several days before each release. During these freezes all development efforts are redirected to testing and bug fixing. This periodic cleanup is one of the most valuable aspects of a release.

Getting Involved

The first step to getting involved in the Parrot project, whether you want to hack code, write documentation, or help in other ways, is to join the Parrot-porters (p2) mailing list. The topics on p2 tend to revolve around practical matters: bug reports, patches, notifications of changes committed to the subversion repository, and questions on coding style. Occasionally there are discussions about how to implement particular features, although such discussions are often better-suited for other communications media, such as IRC.

The Parrot developers, along with other volunteers and well-wishers tend to congregate on IRC as well. They maintain a chatroom #parrot on the irc://irc.perl.org server. To get real-time answers to questions, or just to see how things are progressing, the chatroom is invaluable.

Use the source

The second step to participating in Parrot development is to get a copy of the source code. If you just want to try it out--experiment with a few features and see how it feels--you're probably best off downloading a tarball. For the most stable copy, grab the latest point release from CPAN. The sure way to get the most recent release is at http://search.cpan.org/dist/parrot/ (or search for "parrot" in "Distributions"). If you want something a little more cutting edge than the packaged release, a new snapshot of the subversion repository is created every eight hours. The most recent snapshot is always available at http://cvs.perl.org/snapshots/parrot/parrot-latest.tar.gz.

If you plan to get involved in development, you'll want to check out the source from the subversion repository. Anyone can get anonymous access, committers use their http://auth.perl.org username.

  svn co https://svn.perl.org/parrot/trunk parrot

There's also a web interface for viewing files in the repository at http://svn.perl.org/viewcvs/parrot/.

Now that you've got the source, take a moment to look around. The code changes constantly, so a detailed description of every file is impossible. But a few road signs are helpful starting out.

The most important top-level directory is docs/. The content isn't always up to date, but it is a good place to start. parrot.pod provides a quick overview of what's in each documentation file. If you're a capable writer and know a thing or two about how Parrot works, the documentation is a great place to start contributing.

The languages/ directory contains the code that implements various language compilers: Perl 6, Python ("Pynie"), Ruby ("Cardinal"), PHP ("Pipp"), Lisp, Lua, Tcl ("partcl"), WMLScript, Forth, Scheme, Befunge, BASIC, and many others. These language compilers are in various stages of partial completion. The file LANGUAGES.STATUS provides meta information on the included languages and on the many language projects that are being developed and maintained outside the Parrot repository. If you have a language you're particularly interested to see implemented on Parrot, you can see how far along the effort is, or you can start the work to implement it yourself.

The lib/ directory contains Perl 5 classes currently used in developing Parrot. The src/pmc/ directory contains the C source code for Parrot classes (PMCs, which you'll read more about in CHP-9Chapter 9). The examples/ directory contains some example Parrot assembler code, as well as benchmarks.

Building Parrot

The first step before you start playing with Parrot's PASM and PIR code is to get a copy of the source code and compile it. PASM is the Parrot assembly language and is introduced in CHP-5Chapter 5. PIR, an intermediate-level language that is used most often in compiler development, is discussed in CHP-3Chapter 3.

The basic steps involved in building Parrot from the source code from the command line are: Not all operating systems have make. Check the documentation for instructions for systems that aren't Unix-based.

  $ perl Configure.pl
  $ make
  $ make test

Once you've compiled Parrot, create a small test file in the main parrot directory. We'll call it fjord.pasm.

  print "He's pining for the fjords.\n"
  end

.pasm is the standard extension for Parrot assembly language source files. Now you can run this file with:

  $ ./parrot fjord.pasm

And watch the result of the program execution. Instead of executing the program immediately, you could also compile it to bytecode:

  $ ./parrot --output fjord.pbc fjord.pasm

You specify the name of the output bytecode file with the --output (or -o) switch. .pbc is the standard extension for Parrot bytecode. To execute the compiled bytecode, run it through the parrot interpreter:

  $ ./parrot fjord.pbc

This is, of course, a simple and contrived example. In the next few chapters we will discuss more aspects of Parrot programming using both PASM and PIR, and we will discuss some of the more advanced features of Parrot that make it an interesting and attractive programming platform.

Patch submission

Parrot development proceeds through a continuous stream of patches. Patches are the currency of exchange in the project--the unit of work. Patches can fix bugs, add features, modify capabilities, remove cruft, and improve the suite of tests and the project documentation. If something needs to change, it will typically require the submission of a new patch.

While anyone is free to submit a patch, only a small number of people have the ability to apply patches to the central Parrot repository. These people are called committers. By allowing all people to get involved through patch submission and testing, the project can harness the efforts of a large group but still keep the same high quality as a small group of experienced developers.

Every submitted patch is automatically forwarded to the p2 list where it's subject to peer review. Small patches typically spark little debate, and can be well-tested on many platforms before being committed to the repository. Patches tend to be small modular changes, which makes for easy testing and evaluation. Occasionally a large feature such as an entire language implementation is submitted in a single patch, but these are the exceptions.

Submitting a patch is fairly straightforward. You create a file that lists all your changes, a diff or a patch, and email it to the ticket tracking system at parrotbug@parrotcode.org. It's important to make sure your patch and your email have descriptive titles so that the committers and testers have a better idea about what it does. The body of your email should also include a good description about what you changed and why.

It's important that you create your patches from a checked-out subversion repository, not from a tarball or or snapshot. This way, you can ensure that your diff is made against the latest version of the files. If you patch an old version, the problem may have already been resolved! Make sure the paths listed in the patch match those in the repository. There are two methods of creating patches that will do this for you. You can make changes directly in your checked-out copy of the subversion repository and then create diffs using the command svn diff. Alternatively, you can make a copy of the repository and then create diffs between the two copies with the diff -u command:

  diff -u parrot/README parrot_changed/README

Either method is fine, and both are equally common on p2. Your working style and the types of changes you make--small and modular versus large and sweeping--will influence which method you choose.

Next, when you're making changes, take some extra time to consider how your patch affects the rest of the system. If your patch adds a new file, patch the main MANIFEST file to include it. If you add a new feature, make sure to write tests for it. If you fix a bug, add a test to prove that it's fixed. See CHP-9-SECT-13"Writing Tests" in Chapter 9 for more on writing tests for Parrot. Tests are very important for Parrot development, and writing good tests is a valuable skill for developers to have. Before you submit a patch always recompile the system yourself with the patch included and run all tests to prove that it works. You can build and test Parrot completely by running the following commands:

  make clean
  perl Configure.pl
  make
  make test

Consider the people who will review and apply your patch, and try to make their jobs easier. Patch filenames should be as descriptive as possible: fix_readme_aardvark_typo.patch is far better than README.patch. An attached file is better than a diff pasted into an email, because it can be applied without manual editing. The conventional extension for patch files is .patch.

In the email message, always start the subject with "[PATCH]", and make the subject as clear as possible: "[PATCH] misspelled aardvark in main README file" is better than "[PATCH] typo". The body of the message should clearly explain what the patch is supposed to do and why you're submitting it. Make a note if you're adding or deleting files so they won't be missed.

Here is a good example of a patch submission using the subversion diff method (an actual patch from p2). It's short, sticks to the point, and clearly expresses the problem and the solution. The patch filename and the subject of the message are both descriptive:

Possible alternates: ticket #23501, #24053 (not from top level)

  Subject: [PATCH] Pointers in List_chunk not initialized
  From: Bruce Gray
  
  On Win32, these tests are segfaulting due to invalid
  pointers in List_chunk structs:
  t/op/string.t             97-98
  t/pmc/intlist.t           3-4
  t/pmc/pmc.t               80
  
  The problem is caused by list.c/allocate_chunk not
  initializing the pointers. This patch corrects the problem.
  
  --
  Hope this helps,
  Bruce Gray

With the attached file list_chunk_initialize.patch:

  Index: list.c
  =========================================
  RCS file: /cvs/public/parrot/list.c,v
  retrieving revision 1.23
  diff -u -r1.23 list.c
  --- list.c        27 Dec 2002 09:33:11 -0000        1.23
  +++ list.c        28 Dec 2002 03:37:35 -0000
  @@ -187,6 +187,10 @@
       Parrot_block_GC_sweep(interpreter);
       chunk = (List_chunk *)new_bufferlike_header(interpreter, sizeof(*chunk));
       chunk->items = items;
  +    chunk->n_chunks = 0;
  +    chunk->n_items  = 0;
  +    chunk->next     = NULL;
  +    chunk->prev     = NULL;
       Parrot_allocate_zeroed(interpreter, (Buffer *)chunk, size);
       Parrot_unblock_GC_mark(interpreter);
       Parrot_unblock_GC_sweep(interpreter);

Bug tracking

Bug reports go to the same address as patch submissions (parrotbug@parrotcode.org). Similar conventions apply: make the subject and the message as clear and descriptive as possible. The subject line should start with "[BUG]" to make it immediately obvious what the message is about.

If you want to track a bug or patch you've submitted, the current queue of bugs and patches is publicly viewable at http://rt.perl.org. Bug tracking for Parrot is handled by the Request Tracker (RT) ticket tracking system from Best Practical Solutions.

19 POD Errors

The following errors were encountered while parsing the POD:

Around line 5:

A non-empty Z<>

Around line 18:

A non-empty Z<>

Around line 42:

A non-empty Z<>

Around line 55:

Deleting unknown formatting code U<>

Around line 63:

A non-empty Z<>

Around line 65:

Deleting unknown formatting code U<>

Deleting unknown formatting code U<>

Around line 77:

Deleting unknown formatting code U<>

Around line 83:

Deleting unknown formatting code U<>

Around line 107:

Deleting unknown formatting code A<>

Around line 115:

A non-empty Z<>

Around line 117:

Deleting unknown formatting code A<>

Deleting unknown formatting code A<>

Around line 124:

Deleting unknown formatting code N<>

Around line 165:

A non-empty Z<>

Around line 190:

Deleting unknown formatting code U<>

Around line 215:

Deleting unknown formatting code A<>

Around line 255:

=end for without matching =begin. (Stack: [empty])

Around line 297:

A non-empty Z<>

Around line 299:

Deleting unknown formatting code U<>

Around line 306:

Deleting unknown formatting code U<>