MiniLab: occam

occam is a reasonably old language, with occam1 first appearing on the scene in 1981. Grounded in the CSP algebra, it provides constructs for writing SEQuential code, PARallel code, and for ALTernating over inputs from other processes. While the language has evolved (into what is now called occam-pi), the extensions are poorly documented and their semantics largely undefined. As a result, we will constrain our explorations to the core language as of 1991, occam2.

Resources

There are a number of resources you can consult when working with occam2.

Daniel Hyde has written a good primer (PDF) that provides additional history and an introduction to the basics of the language.

Pountain and May's text (PDF) on the subject is concise. Burns (PDF) is a bit more verbose, but not overly so. Both are good books on the language.

Other resources may be found about the WWW, but those are where I would begin. I will provide a brief primer here for your first MiniLab.

Getting Started

You'll need a plain text editor. Emacs will work. As will vi. GEdit, JEdit, KEdit, and any other <LETTER>Edit will probably work, too.

Second, save your programs with the extension .occ, because it will probably make the compiler happy. For now, create a file called first.occ, and we'll go from there.

Saying "Hello World"

Type the following program into your editor:

#INCLUDE "course.module"
PROC main (CHAN BYTE kyb?, scr!, err!)
  SEQ
    out.string("Hello, ", 0, scr!)
    out.string("world!*n", 0, scr!)
:


Then, on the command line, compile and run your program.

[mreynolds:~]  kroc first.occ
[mreynolds:~] ./first

If all goes well, you should see the words "Hello, world!" printed to the screen. The *n is a newline character in an occam string.

Break some stuff

Next, break a few things. This will help you learn a few syntax errors early, so when you encounter variants of them later, they won't surprise/baffle you. With your partner, make note in your lab book what the error is, and what you think it means. Note: these are not meant to be cumulative. Fix each break after you introduce it before proceeding.

  1. There are two spaces before the SEQ, and four spaces before each of the calls to out.string. Try removing one of the spaces before the SEQ. Then, try indenting either (or both) of the out.string lines.
  2. Remove the ! from the use of scr in one of the calls to out.string.
  3. Replace one of the uses of scr with kyb instead. Keep the ! for the moment.
  4. Flip the ! to a ?, and see if the error changes.
  5. Get rid of the SEQ, and outdent each of the out.string lines two spaces.
  6. Change the SEQ to a PAR.


A few notes

A few notes about the code:

  • The SEQ means sequence. If you want to do more than one thing in a row, you need to have a SEQ. The body of a PROCess definition, therefore, can be said to only contain one process (in this case, a SEQ).
  • The last PROC in a file is the one that is executed. It is called the top-level process. It can grab three channels from the environment: an input channel from the keyboard, and two output channels (one to standard out, and one to standard error). They are channels of bytes, as denoted by the type declaration CHAN BYTE, and they have directions: ? for input, ! for output.
  • The PROC defines a process that will run. The header of the PROC "main" indicates that it expects to receive three channel ends. 

Making Changes

To send data over a channel, we use the ! operator. It is a binary operator. On the left-hand side is the name of the channel we want to communicate on, and on the right-hand side is data matching the channel's protocol

For example, the PROC "main" gets three channel ends: the read (or input) end of the channel kyb, and the write (or output) ends of both scr and err. The protocol of these three channels is simple: they communicate single BYTEs.

So, to send a single byte, you could do something like:

scr ! 65


This says to communicate the BYTE with the value 65 over the channel scr. Of course, we might rather say:

scr ! 'A'


simply because it is easier to read. The process out.string is defined in course.module

Add a few bits

Lets add a few bits to this program.

  1. First, print a witty message (like "Press a key to continue"), and then read from the keyboard. This will require you to declare a variable of type BYTE outside the SEQ, and to do a read operation using the ? operator. After the user presses a key, your program should say "Hello, world!" or similar.
  2. Write a new PROC. Call it "hello", and make it take the output end of a BYTE channel as a parameter. Call that end s. Your new PROC should do nothing more than send the string "Hello, world!*n" down the channel. 
  3. In the PROC "main", replace the execution of the out.string processes with the execution of your new process, "hello". 
  4. Although apparently unnecessary, wrap the execution of the "hello" process in a SEQ.
  5. Modify your SEQ so it is instead SEQ i = 0 FOR 10. This is called a replicated SEQ. It is, in some ways, like a for loop in other languages.
  6. Replace the replicated SEQ with a WHILE TRUE statement.


None of this is particularly amazing. However, it gives you a few small things you can do step-by-step to change your program in ways that might look familiar from other languages.

Simple Parallelism

As a final step in the minilab, we'll pull an exercise from the University of Kent. (Note that was a link to the starter code.) It involves putting together a network of processes to produce some seemingly simple output. The network, when done, should look like this:


The diagram says that the process main will have three processes running in parallel: S0, S1, and toggle. The S0 and S1 processes will output data to the toggle process, which will in turn hold one end of the screen channel. 

Feel free to ask questions. I have given you minimal instruction in the language at this point. Share with other groups as you discover things, etc. 

Basically, I've thrown you in the pool. See what happens.