The Guppy Programming Language

[ preface | about | examples | bad-practice ]


Preface

"Guppy" is the name I've given (crudely) to a possible successor language for occam-pi. I.e. one that keeps all the nice features (concurrent expression, channel-based I/O, dynamics and mobility, compiled-code performance and multicore support) and tries to engineer around the issues that occam-pi currently has (limited dynamic type handling, restricted recursion, old compiler code-base, no minimal-pain route to 64-bit support).

I'm still trying to come up with a better name, so, for the time being, "Guppy" is what will happen between occam-pi and whatever the finalised version is called. Suggestions welcome. I thought that "Ob" (O-flat) would be quite amusing, but some of my colleagues disagree (and I'll bow to their judgement on that issue). No-one has objected too hard to the name so far, so it's stuck for now. (historical note: unimaginatively sourced from Peter Jackson's "Meet the Feebles", a thoroughly warped but quite fun film).

About

Guppy is a concurrent programming language, based around the concepts of isolated processes that communicate and synchronise with each other through explicit mechanisms such as channels and barriersprocess-oriented programming. The concurrency semantics are based on Hoare's CSP and Milner's pi-calculus. A central aim is to provide a language that is powerful (in expression, particularly of concurrent behaviour) but without losing what could be termed mechanical sympathy (well described by Carl Ritson in his thesis and elsewhere). In short, when programmers write code, with concurrent code being no exception, they have some internal model of how that code will execute. If that model is wrong, over-complicated, or just hard to understand for any particular language, what the programmer expects and what actually happens diverge. This leads to more frustrated development amongst other things, even when the original intention was to create a more powerful (expressive) abstraction. On that basis, Guppy aims to be simple to understand, and obvious in its execution, as far as possible. Functional (e.g. Haskell) and logic (e.g. Prolog) programming are two places where I see programmers struggle with an execution model, and it is perhaps no surprise that optimising functional and constraint programs are black-art hard, but there again, the number of people who understand the low-level workings of functional and logic compilers and run-time systems is few.

Guppy is not a new methodology for concurrent programming, is merely a new expression for what we have already been doing and experimenting with in terms of occam-pi for the past decade.

Examples

As of 28th April 2013, the nocc compiler successfully produced working code for a crude hello-world program. This makes it a good example as any:

    # hello.gpp -- guppy hello-world program

    define hello (chan!(char) screen)
        val string msg is "Hello, world!\n"

	seq i = 0 for size msg
            screen ! msg[i]

    end

Sometimes, it's useful to have functions that return things too:

    define timestwo (val int n) -> int
        return n * 2;
    end

As of 25th May 2013, some initial parallel process handling is in place, e.g.:

  define partest (chan!(char) screen)
    par
      seq
        screen ! 'X'
        screen ! '\n'
      skip
  end

As of 24th June 2013, we have a working commstime benchmark!

  # commstime.gpp -- simple benchmark

  @include "guppy_stdlib.gpi"

  define delta (chan(int) in?, out0!, out1!)
    while true
      int v
  
      in ? v
      par
        out0 ! v
        out1 ! v
  end
  
  define prefix (val int n, chan(int) in?, out!)
    out ! n
  
    while true
      int v
  
      in ? v
      out ! v
  end
  
  define succ (chan(int) in?, out!)
    while true
      int v
  
      in ? v
      out ! v + 1
  end
  
  define sink (chan(int) in?, chan(string) out!)
    while true
      int v
      int t0, t1
      timer tim
  
      tim ? t0
      seq for 1000000
        in ? v
      tim ? t1
      t1 = (t1 - t0) / 4000
      out ! "context switch: " + int_to_str (t1) + " ns\n"
  
  end
  
  define test_g31 (chan(string) screen!)
    chan(int) a, b, c, d
    par
      prefix (0, d?, a!)
      delta (a?, b!, c!)
      succ (b?, d!)
      sink (c?, screen!)
  end

How not to write a compiler

Some folk take one look at nocc, which provides the front-end for Guppy, and shriek! It's written in C (just plain C, no C++ fancies) and is pretty terse. Considerable use is made of things like structures of function pointers to provide the required dynamics in the compiler. Basically this way I can pick-and-choose features from object-oriented and aspect-oriented programming, without being constrained by the containing languages. The downside is that small errors can sometimes have spectacular and occasionally non-obvious effects. However, gdb and valgrind make lovely debugging tools, and given that it's just a plain old C program, debugging is straightforward. On the plus side, it is quick. Most of the development I do on my 2.4 GHz Core2 Quad with 3 gigs of RAM (mostly occupied by the web-browser, xterms and vim) which isn't fast by modern standards but runs nocc almost instantaneously. This is nice, especially considering most of the Guppy language grammar (as with all nocc languages) is loaded dynamically at compiler run-time: the point of this being to allow languages to modify their own grammar in various ways. The most time-consuming part is where nocc invokes the C compiler (gcc) to compile the transformed Guppy program, link it against the KRoC/CCSP run-time and gather stack-usage information.

The development methodology is one of: get stuff working first, then fill in the gaps. I.e. whilst the above commstime program compiles and runs, variations on it might not. Moreover, apart from rudimentary type-checking, there is little in the way of semantic analysis of Guppy code (e.g. parallel usage, aliasing and definedness). These will follow in time, but in the short-term my focus is mostly on being able to compile and run programs and refining the language.


Last modified: 2013-06-24 20:32:40.000000000 +0100 by Fred Barnes.