System requirements

Welcome to
a π-calculus
Language and Platform


Pint is a π-calculus language platform which provides a translator written in SML/NJ and a hardware emulator written in Erlang. The platform is intended for investigation at the microprogramming level rather than for use as yet another high level language.

The language is similar to, but simpler than, Vasconcelos' TyCO, or Wojciechowski's Nomadic Pict which is based on Turner and Pierce's Pict; it is automatically typed, asynchronous, higher-order, concurrent and distributed. It is not deterministic or sequenced. It is non-linear and has no polymorphism except for a few list operations. The semantics are taken from Pict.

The Pint language includes document type definition facilities for recursive element and attribute declarations but these are type based rather than syntax based as in SGML/XML. Pint supports the Oasis catalogue. The library provides a graphics system which offers functionality similar to Erlang's GS through an interface based on passing elements to six built-in paths. A demonstration microprogram simulates and displays an ant raiding party.

The emulated hardware offers up to 228 hardware channels on which the program's paths are to be placed. We show examples of programming for the small footprint imposed by this hardware. The emulator provides trace and debugging facilities and will operate at up to 10000 reductions per second on a 1GHz PC. The translator, emulator and documentation, a 260 page book, are GPLed.

A sample program: Hello World

Here is that favourite among favourites: Hello World.

<!DOCTYPE Pint PUBLIC "-//Pint//NOTATION Pint//EN" >
import "-//Pint//DTD Input output library//EN"
              %%%%% hello.pint %%%%%
new c
   ( io.file.uwrite!�Uwrite stdOut "Hello World\n" c c�
  || c?_ = �die

A detailed look at "Hello World"

Let's look at this line by line.

All Pint programs are identified as such by an SGML/XML document type declaration [SGML prod 110, XML prod 28] just as HTML documents should be identified. The keyword DOCTYPE is always upper case and the document type name Pint is always mixed case as written here.

"Why", you may ask, "do we need an SGML/XML declaration on top of something which is neither SGML nor XML?" Pint shares a lot of characteristics with SGML and XML: it allows the declaration of elements and their attributes in a structured way. It calls for conformance of the elements to a DTD, and may be used to markup structured documents. Yet it is does not conform to SGML/XML and is not designed to do so — on the contrary, it is intended as a vehicle to explore alternative markup techniques. The formal declaration at the top of every Pint program says that this is not SGML/XML and that it cannot be processed by an SGML/XML processor. It requires a Pint processor. This makes it clear to all markup specialists that Pint is not to be confused with SGML or XML.

PUBLIC "-//Pint//NOTATION Pint//EN" >
This is called the external identifier [SGML prod 73] and says that the rest of the document is written according to version 0.3.1 of the Pint language specification. The part between quotes is called the formal public identifier (FPI) [SGML prod 79]. The keyword NOTATION says that the document content requires a non-SGML/XML processor to handle it — specifically it requires a Pint processor.

The ">" terminates the document type declaration.

import "-//Pint//DTD Input output library//EN"
Use the paths of the input output library to provide output.

The library is identified by a formal public indentifier (FPI). What this FPI means is specified by a site specific OASIS catalogue which associates a local file name with the FPI. Pint includes a suggested OASIS catalogue which you can adapt to your needs.

%%%%% hello.pint %%%%%
Anything between the first "%" and the end of the line is a comment. You may also use ML style comments (* ... *).
new c
We need a path which we decide to call "c". This path is different to every other path, even if some other path defined previously was also called "c".
Offer the following process to the π-calculus hardware. In this case the process consists of two concurrent processes, separated by a "||".
io.file.uwrite!�Uwrite stdOut "Hello World\n" c c�
The first of the two concurrent processes sends (that's what the "!" means) a value «...» on the library path io.file.uwrite. Sending a value on a path is one of the two basic processes in Pint. The other is receiving a value on a path. In the case of the library path io.file.uwrite the reception is inside the library program "io".

Let's take a closer look at the value:

This is the element's start tag, and Uwrite is more correctly known to SGML/XML specialists as a generic identifier, which has been previously specified in a document type definition (DTD) in the library. In Pint the start tags have no closing "»" and the element content consists entirely of attributes which may, unlike SGML/XML, be marked up. Note that the familiar "<" and ">" could be used in place of "«" and "»".

The U in Uwrite means "Unicode" since the characters are represented internally by their Unicode numbers.

The first attribute says that the output is to the user's screen.
"Hello World\n"
The second attribute is the text to be displayed.
The third attribute is the name of a path on which the value "{}" is sent if the output succeeds.
The fourth attribute is the name of a path on which the value "{}" is sent if the output fails.
This is the element's end tag. As you see, its simpler than SGML/XML.
|| c1?_ = �die
Concurrently, that's what the "||" means, we expect to receive (that's what the "?" means) a value on the path c, but we do not care what that value is, so it's represented by a don't care wildcard "_".

When the "send" and "receive" successfully communicate on path c, we say that a π-calculus reduction occurs, and this is the basic action of the π-calculus machine. During the reduction, the process written after the "=" is offered in turn to the hardware. In this case it's the pre-defined process �die which means "stop the machine".

It should be clear by now that Pint is a lower level language than say C, Scheme, ML or TyCO. That's why it's better to think of working in Pint as microprogramming — low level coding very close to the hardware, providing the hardware with a personality which in turn may allow further higher-level "programming" or other human use.

Another sample program: Na�ve factorial

Here is another old favourite: Factorial n. This is a na�ve program which is very inefficient in its use of the "hardware". The book explains why, and gives the correct solution.

<!DOCTYPE Pint PUBLIC "-//Pint//NOTATION Pint//EN" >
import "-//Pint//NONSGML Formatted input output library//EN"
                    %%%%% fac.pint %%%%%
%% Template fac receives a pair containing the argument:
%% a positive integer n, and a path on which to send the result.
def fac {n r} =
    let new neq0 new ngt0             % Paths for n=0, n>0
        val nlt0 = neq0               % Path for n<0
    out (!{n 0 nlt0 neq0 ngt0} % Choose n<0 n=0 n>0
       || neq0 ? {} = r!1         % If n=0 then send 1 on path r
       || ngt0 ? {} = 
          let new kn1                 % Path for n-1
              new kf1                 % Path for fac(n-1)
          out ( % Send n-1 on path kn1
       ! {n 1 kn1}
                % When n-1 is available, send fac(n-1) on kf1
             || kn1 ? n1 = fac ! {n1 kf1}
                % When fac(n-1)is ready, send product on r
             || kf1 ? f1 =� ! {n f1 r}


The Pint language and platform are documented in a 270 page book, available as a PDF download, 1.4 MBytes.

For the brave, there is an alternative version of the same book in PostScript, as a set of 4 sheet (16 page) signatures. The PostScript files for the language description, 3.6 MBytes and the library, 9.9 Mbyte, are to be printed recto-verso on ISO A4 paper. You then have to peel off the signatures, 4 sheets (16 pages) at a time, and fold the four sheets together with the consecutive page numbers on the inside of the fold. Finally you have to bind the signatures together to get an ISO A5 sized book. Hint: Practice on a few pages before sending the whole file to the printer; it will save you a lot of ink.

Although the book is intended for ISO A4 paper, it should still be readable when printed on US letter.


It's free, as in "freedom". The translator and the emulator are available under the terms of the GNU General Public License (GPL). The book is available under the terms of the GNU Free Documentation License (FDL).

System requirements

The Pint translator and emulator have been developed and tested on SuSE Linux 8.1 and 9.1. The principal prerequisites are


The current version is 0.3.1 2005-08-25. No previous versions have been published.

Download the Pint translator, emulator and documentation from 2.8MByte.


The translator and emulator are currently installed in user space, but if one day Pint becomes more stable and (gasp!) more widely used, this may change.

Since the installation is into user space, no root privileges are needed to install and run Pint, but if several people on a system are using Pint, there are at least as many copies of Pint on the system.

The Pint system is built by attempting to run it. The shell detects that pieces are missing and builds them as required. Maybe, one day when the language becomes more stable, the translator and run-time emulator will be pre-built, but that hasn't happened yet.


Why is Pint called "Pint"?

It's intended to be a small, "pint sized" language.

Why is Pint so verbose?

Debugging concurrent microcode is difficult — you need all the help you can get.

Why were versions 0.1 and 0.2 kept confidential?

Because of an ongoing contract, I needed a copyright assignment to publish this work. I received the copyright assignment for release 0.3.1.

My first implementation, version 0.1, was back in 1999. It was a denotational semantics based interpreter in SML/NJ at 30 reductions/sec on a 1GHz Intel PC. Version 0.2 was when I re-wrote the interpreter in John Reppy's Concurrent ML and achieved 300-500 reductions/sec. To be fair, Concurrent ML is a synchronous language and the additional engineering I added for asynchronous one-way communication really slowed things down.

For version 0.3, I again re-wrote the translator to issue Erlang source code and achieved 10000 reductions per second for simple programs such as factorial(n), n=1000. On a more ambitious program with heavy animated graphics such as ant raids, version 0.3 gets up to 3000 reductions per second.

Why work on something as useless as π-calculus microprogramming?

I needed a very low level language platform, so low that all the language bigots out there could truly say "My language is better", and I could happily agree with them. I could then demonstrate a proposal avoiding all emotional reaction. We could all agree that the XYZ language would be even better — for the same idea.

What are all these wierd signs like � and � ?

Pint is an ISO Latin 9 language in that the source programs are encoded in the ISO Latin 9 character set. ISO Latin 9 is a slight modification of the familiar ISO Latin 1 with the currency symbol replaced by the Euro symbol and seven other changes.

If your printer or screen shows character U+00a4, "�", as a Euro symbol, then you are using ISO Latin 9, no matter what that pull-down menu said when you selected your character set. It is common to find ISO Latin 1 announced when what is implemented is ISO Latin 9, since a lot of programmers seem to treat ISO Latin 9 as a "bug fix" release for ISO Latin 1. Maybe this is what the ISO should have done, but ISO politics are such that is is sometimes easier to produce a new standard that to fix an existing one,

ISO Latin 9 is intended for general purpose applications in typical office environments in at least the following languages of European origin: Albanian, Basque, Breton, Catalan, Danish, Dutch, English, Estonian, Faeroese, Finnish, French, Frisian, Galician, German, Greenlandic, Icelandic, Irish Gaelic (new orthography), Italian, Latin, Luxemburgish, Norwegian, Portuguese, Rhaeto-Romanic, Scottish Gaelic, Spanish, and Swedish. There are several official written languages outside Europe that are covered by Latin alphabet No. 9. Examples are Indonesian/Malay, Tagalog (Philippines), Swahili, Afrikaans.

How do I type a character like � ?

The Emacs editor and others provide techniques for entering ISO Latin 9 characters which are not on your keyboard. The simplest way for Emacs users is to use Mule and toggle the input method to ISO Latin 9. However this does not cover all the possible ISO Latin 9 characters. The remaining characters such as � may be entered by following the instructions given for "Inserting text" by the Emacs documentation:

If you need to insert a control character or a character whose code is above 200 octal, you must "quote" it by typing the character `Control-q' (`quoted-insert') first. (This character's name is normally written `C-q' for short.) There are two ways to use `C-q':

When multibyte characters are enabled, the octal codes 0200 through 0377 are not valid as characters; if you specify a code in this range, `C-q' assumes that you intend to use some ISO Latin-N character set, and converts the specified code to the corresponding Emacs character code. You select which ISO Latin character set though your choice of language environment.

To use decimal or hexadecimal instead of octal, you should set the variable `read-quoted-char-radix' to 10 or 16. If the radix is greater than 10, some letters starting with `a' serve as part of a character code, just like digits.

A numeric argument to `C-q' specifies how many copies of the quoted character should be inserted.

If you are an Emacs user and you wish to enter ISO Latin 9 characters in hexadecimal rather than octal, add the following lines to your file .emacs.

;; Enter hexadecimal characters using C-q
(setq read-quoted-char-radix 16)

For further details, see the documentation for Emacs.

Do you intend to do more work on Pint?

I shall fix bugs in the current release, but further work depends on the level and direction of interest. Further work on the Pint language system might include

  1. Deeper type analysis needed to detect deadlocks and livelocks.
  2. It would be very useful to have a fully automatic garbage collection. This will probably require a much more serious analysis of the program code.
  3. I would like to address the support of time and time based data. Among the issues to be considered are:
    1. A foreign function interface with examples of its use in manipulating audio and video hardware.
    2. New built-in paths to provide access to the audio and video hardware.
    3. The introduction of paths that behave as pipes, carrying data streams possibly lasting for a long time.
    4. Re-consideration of the type system to support time and time dependent data structures.
    5. An extension of Pint to include the φ-calculus — a hybrid extension of the π-calculus to embedded systems.
  4. The Pict programming language appeared to be headed towards a higher level language that looked like Scheme. However Scheme is not specifically intended as a language for concurrent working. It would be interesting to develop a high level language influenced by Erlang.
    1. How should an Erlang variable be modelled? A value cell seems too complex — is there a simpler approach?


Please send comments, suggestions and bug reports to rprice at cs dot uml dot edu.

© Copyright 2005 Roger Price
In order to facilitate access from all browsers, now and in the future, these pages conform to the International Standard ISO/IEC 15445 and the corresponding W3C Recommendations. Last change: Sat Mar 21 17:03:13 CET 2015
Valid HTML 4.01! Valid CSS! Level A conformance icon,            W3C-WAI Web Content Accessibility Guidelines 1.0 Valid ISO 15445!