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 where the objective is pursued because the whole team knows the task at hand, not because of any tight control from above.

Development Cycles

The Parrot development cycle centers on regular "point releases." A point release corresponds to a version change, such as 0.4.x to 0.5.x. These releases typically happen monthly, which is good because nobody has to guess when the next one will be. The architect and release managers decide whether the release is a "major" or minor one, depending on the changes that have been made and the features that have been added in the previous month. Usually one or two solid new features trigger a major point release. The Parrot team has specified a general roadmap of major point releases, and the expected features and changes that will trigger each one.

Development proceeds at a steady pace with bugs reported, patches submitted, patches applied, and all sorts of other regular development tasks performed. 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 Or related tools, or high-level language compilers, etc. then just one. Activity tends to spike when a release is approaching as last minute bugs, especially bugs in the build system or bugs that cause segmentation faults, are found and fixed by the team. After the release, there is an influx of new bug reports and other feedback as the casual users and testers get their hands on the newest version. These regular swells of activity are one of the major reasons why Parrot has monthly releases.

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 to have more in-depth discussions. 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 the place to be.

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--the best options is to download the most recent point release for your system. Point releases are usually packaged up for easy download and install for various platforms, including Windows, Debian, and Redhat. Point releases are also available 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 directly. Anyone can get anonymous access to read the files and download a working copy to explore and test. For commit access, volunteers need a http://auth.perl.org username, and need to be approved by a Metacommiter. To download the most recent version from SVN, type this command into your terminal This is for Linux users, on Mac or Windows systems, follow the instructions from your SVN client:

  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/parrot/.

The repository is large and complex, so it's worth taking a little bit of time to explore. The code changes constantly, but most files and functions have informative descriptions to help keep track of things.

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. This book that you're reading right now was created in docs/book/ by ordinary contributors. Most other documentation files found here are parsed and converted to HTML for display at http://www.parrot.org.

The languages/ directory contains the code that implements various language compilers This isn't entirely true. As of the 1.0 release of Parrot, all HLLs are supposed to reside elsewhere, not in the Parrot repository. If the languages disappear from there, we'll probably be nice enough to leave a note telling you where it went: 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. We'll talk more about creating new compilers in Chapter 10: High-Level Languages, if you're interested.

The lib/ directory contains Perl 5 classes currently used in developing, building, and testing Parrot. The src/pmc/ directory contains the C source code for Parrot classes (PMCs, which you'll read more about in CHP-11Chapter 11).

Most Parrot development happens in src/ for the C source code, and include/parrot/ for the C development header files.

Libraries for use by programs running on Parrot are found in runtime/.

The examples/ directory contains some example Parrot PIR and Assembly code, as well as benchmarks. More discussions about these topics will be found in CHP-3 Chapter 3, CHP-5 Chapter 5, and CHP-7 Chapter 7 respectively.

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.

23 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 32:

Deleting unknown formatting code N<>

Around line 48:

A non-empty Z<>

Around line 61:

Deleting unknown formatting code U<>

Around line 69:

A non-empty Z<>

Around line 71:

Deleting unknown formatting code U<>

Deleting unknown formatting code U<>

Around line 85:

Deleting unknown formatting code U<>

Deleting unknown formatting code N<>

Around line 96:

Deleting unknown formatting code U<>

Around line 103:

Deleting unknown formatting code U<>

Around line 112:

Deleting unknown formatting code N<>

Around line 128:

Deleting unknown formatting code A<>

Around line 138:

Deleting unknown formatting code A<>

Deleting unknown formatting code A<>

Deleting unknown formatting code A<>

Around line 145:

A non-empty Z<>

Around line 147:

Deleting unknown formatting code A<>

Deleting unknown formatting code A<>

Around line 154:

Deleting unknown formatting code N<>

Around line 195:

A non-empty Z<>

Around line 220:

Deleting unknown formatting code U<>

Around line 245:

Deleting unknown formatting code A<>

Around line 285:

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

Around line 327:

A non-empty Z<>

Around line 329:

Deleting unknown formatting code U<>

Around line 336:

Deleting unknown formatting code U<>