[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re. Lamport / Composition



Paul,

> there was one there would be plenty more excuses for people to ignore
> occam, but until:
> 
>  there is a compiler of occam written in occam;
>  and it farms itself out over a reasonable number of processors;
>  and gives genuine speed-up from so doing;
>
>      it is too easy to rubbish occam as a toy.

Well, the original occam compilers were all written in occam.  They were
a network of processes each responsible for different elements of compilation.
There was a tokenising process, a nametable, a line parser (that identified
each line type and checked its syntax), a structure parser (that checked
higher-level syntax), a semantic/usage checker, an error reporter and a
code generator.

This was easy to understand -- particularly the recursive descent parsing
(which was really no problem even without recursion).  I never got to grips
with the code checking though.  I remember a student project way back in
1986 (or thereabouts) that extended the language so that the direction of
use of channel parameters was made explicit:

  -- I notice this now arriving in David May's Icarus language ...

  PROC thing (CHAN OF SCAN in?, CHAN OF BOOL interrupt?, CHAN OF RESULTS out!)
    ...  local declarations
    INITIAL BOOL running IS TRUE:
    WHILE TRUE
      ALT
	in ? scan
	  SEQ
	    ...  process scan
	    out ? results                -- semantic error here!
	BOOL any:
	interrupt ? any
	  SEQ
	    out ? interrupted            -- semantic error here!
	    running := FALSE
  :

The compiler was modified to enforce the extended channel parameter information
and check that the channel usage within the PROC body conformed.  This way,
the compiler reports the error where it is made (e.g. on the marked lines
above).

Current occam compilers don't have the channel direction declaration and have
to accept the above code.  An error is reported when you connect the output
channel of thing (which the compiler thinks is an input channel) to an input
channel of another process (assuming we didn't make the same, but opposite
mistake when coding that one).  But that error is reported in the wrong place!
You get the error at the place of use of thing (where it was being used
correctly according to what you had in mind) and not where the error really
was (in the body of thing).  Such misdirected error reporting is something
we get used to ... but it's not nice!

Of course, back in 1986, occam compilers didn't do channel usage checks when
you wired up processes ... so you wouldn't get any errors at all from the
compiler ... your code would just crash.

The point is that my (undergraduate) student was able to make this fairly
sophisticated modification to the occam compiler -- written in occam -- and
extend the language in a non-trivial and useful way.  So, occam can't be
that bad a language with which to write compilers.  Nowadays, with occam2.1
data types, it would be *much* easier.  Mind you occam3 union types would
help some more, but I don't think we would need much else for a sophisticated
product.

As for speed-up, the reason for designing and implementing the compiler
as a network of processes was for control of complexity.  The channel
(and, nowadays, protocol) interfaces between components is much cleaner
(claim!) than procedural (or object) interfaces.  It makes teamwork on
the project easy.  This is because of the *compositionality* deriving
from using the CSP model -- i.e. we're back again to the original argument.

Having said that, such an occam compiler running on an SMP-PC would
automatically exhibit speed-up, with all phases of the compilation
decoupled into parallel threads: file i/o, tokenising, parsing, semantic
checking and code generation.  The compiler would automatically pipeline
in parallel, given enough processors.  With fewer processors (or just one),
it would make best use of what was available.  The overheads for managing
the parallel threads on fewer processors being completely insignificant!

Peter.