Python & Go

Duncan Booth duncan.booth at invalid.invalid
Fri Nov 13 13:35:07 CET 2009

Paul Rubin <> wrote:

> Nah, exceptions are an ugly effect that gets in the way of
> parallelism.  Haskell handles lookups through its type system; dealing
> with lookup errors (say by chaining the Maybe type) is clean and
> elegant.  Erlang handles it by crashing the process, and dealing with
> the crash through a supervision tree that cleans up after crashes and
> restarts the crashed processes.

I said exceptions or any other method of error handling.

>> What that article didn't mention, and what is possibly Go's real
>> strong point is that it has built-in support for parallel processing.
>> Again though the implementation looks weak...
> I'd like to know more about this; is there a link with a short
> write-up?  I haven't gotten around to looking at the reference
> materials.

I just read the reference manual. As I understand it:

Any function or method can be executed in parallel: instead of calling 
the function you use the go keyword:

   go doSomething();

go routines are executed using a thread pool, and an individual go 
routine might vary its execution thread depending on which threads are 

Most types are not thread safe, so you should never access any mutable 
value from more than one go routine. If you need to access something 
like a map from multiple parallel routines you need to use channels to 
protect it.

You can declare and pass around channel variables. A channel can hold 
values or pointers of any type and has a specific number of free slots.

   var ch = make(chan int, 3);

would create a channel that holds 3 int values.

To write to a channel (blocking if it is full):

   ch <- value;

To read from a channel (blocking if empty):

   value <- ch;

To read from a channel blocking and discarding the result (e.g. to wait 
for a routine to finish):

  <- ch;

To read without blocking:

  value, ok <- ch;

ok set true if something was read. And to write without blocking:

   ok := ch <- value;

or in fact any write in an expression context.

You can also use a select statement (syntax similar to a switch 
statement) to read or write channels in parallel. It arbitrarily chooses 
one of the case statements that can proceed to execute, otherwise if 
there is a default statement it executes that. If there is no default 
statement the entire select blocks until one of the case statements can 
proceed. e.g. (example from the docs)

var c1, c2 chan int;
var i1, i2 int;
select {
case i1 = <-c1:
	print("received ", i1, " from c1\n");
case c2 <- i2:
	print("sent ", i2, " to c2\n");
	print("no communication\n");

There doesn't seem to be any way to specify a timeout on a read or 
write. I think you can create a timer channel with regular ticks and 
select from that to provide an effective timeout, but that sounds like a 
lot of boilerplate if you have to do very often.

Duncan Booth

More information about the Python-list mailing list