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

Catch-up



Dear All,

There have been discussions going on with an ad-hoc mailing list on
possible new directions for occam.  This mailing list is to rationalise
that list into a formal one.  I've added you to the list in case you
are interested -- apologies if not, you will have been told how to
unsubscribe.

Before subscribing everyone else, enclosed are the relevant mailings
to date.  They are mainly about Java, which provides an extraordinary
case-study in how to take over the world that may be worth paying
attention to!

Cheers,

Peter.

(cut here)
--------------------------------------------------------------------------------

From: 0yvind Teig <teig@xxxxxxxxxxxx>
Organization: Autronica AS
To: nuug!phw@xxxxxxxxx
Date: Fri, 15 Mar 1996 08:18:21 +0200
Subject: ComsTime.java
Priority: normal
X-Mailer: Pegasus Mail for Windows (v2.01)
Status: RO

Dear Peter 

I am sending you this novice's Java program. I have implemented
your Comstime.occ.

It runs, but very, very slowly, at least on the only platform I've
tried it on, 486dx2 66Mhz Win-95.

I have made other test programs that seem to run *much* faster.

There is something strange here. Maybe your test program really
gives it a hicking! Or maybe there's something with me? Or even
Win-95 and the scheduling? Or Java run-time system?

//{{{  ComsTime.java
//{{{  Heading
// yenyvind Teig 13.3.96

// COMMUNICATION TIMER TEST PROGRAM
// as suggested by Professor Peter Welch
// (University of Kent at Canterbury)
// Originally written for occam, this program tests how Java behaves
//}}}  
//{{{  Results
// According to Lars Thore Aarrestad the original occam code runs like this:
// T800          20 Mhz  occam        12 us
// T800          20 Mhz  SPOC->C     168 us
// Intel 386dx   25 Mhz  SPOC->C      69 us
// TMS320C32-40 (20 Mhz) SPOC->C      57 us
// Intel 486dx2  66 Mhz  SPOC->C       9 us
// Intel Pentium 75 Mhz  SPOC->C       6 us

// This Java-code runs like this:
// Intel 486dx2  66 Mhz  Win-95  1000000 us (a second - what's wrong?)
//}}}  
import java.io.*;
import java.util.*;

public class  ComsTime
{
   public static void  main (String argv [])
   {
      try
      {
         int NoOfLoops = 100;
         //{{{  Report
         System.out.println (NoOfLoops + " loops:");
         //}}}  
         //{{{  Streams
         PipedOutputStream out_a  = new PipedOutputStream ();
         PipedInputStream  in_a   = new PipedInputStream  (out_a);
         out_a.connect    (in_a);

         PipedOutputStream out_b  = new PipedOutputStream ();
         PipedInputStream  in_b   = new PipedInputStream  (out_b);
         out_b.connect    (in_b);

         PipedOutputStream out_c  = new PipedOutputStream ();
         PipedInputStream  in_c   = new PipedInputStream  (out_c);
         out_c.connect    (in_c);

         PipedOutputStream out_d  = new PipedOutputStream ();
         PipedInputStream  in_d   = new PipedInputStream  (out_d);
         out_d.connect    (in_d);
         //}}}  
         //{{{  Start threads
         ComsTime_a aComsTime_a = new ComsTime_a (in_b, out_a);
         ComsTime_b aComsTime_b = new ComsTime_b (in_a, out_c, out_d);
         ComsTime_c aComsTime_c = new ComsTime_c (in_c, out_b);
         //}}}  
         //{{{  Time tag
         Date date1 = new Date();
         //}}}  
         //{{{  Loop: Wait for report of rounds
         int rounds;
         rounds = 0;
         int valueAlso_rounds = 0;

         while (rounds < NoOfLoops)
         {
            rounds = rounds + 1;
            valueAlso_rounds = in_d.read ();
            // System.out.println (valueAlso_rounds);
         }
         //}}}  
         //{{{  Time tag
         Date date2 = new Date();
         //}}}  
         //{{{  Report
         long microseconds   = ((date2.getTime() - date1.getTime()) * 1000);
         long timePerLoop_us = (microseconds / ((long) NoOfLoops));

         System.out.println (timePerLoop_us + " microseconds / iteration");
         //}}}  
         //{{{  Stop threads
         aComsTime_a.stop ();
         aComsTime_b.stop ();
         aComsTime_c.stop ();

         try
         {
            aComsTime_a.join ();
            aComsTime_b.join ();
            aComsTime_c.join ();
         }
         catch (InterruptedException ignored) {}
         //}}}  
      }
      catch (IOException ignored) {}
   }
}
//}}}  
//{{{  ComsTime_a.java
// yen.Teig 13.3.96

import java.io.*;

public class ComsTime_a extends Thread
{
   PipedInputStream  in;
   PipedOutputStream out;

   //{{{  ComsTime_a
   ComsTime_a (
      PipedInputStream  an_in,
      PipedOutputStream an_out)
   {
      in = an_in;
      out = an_out;
      start ();
   }
   //}}}  
   //{{{  run
   public void  run ()
   {
      try
      {
         out.write (0);
         int value;
         while (true)
         {
            value = in.read ();
            out.write (value);
         }
      }
      catch (IOException ignored)
      {
         System.out.println ("    " + getName() + " method run exception");
      }
   }
   //}}}  
}
//}}}  
//{{{  ComsTime_b.java
// yen.Teig 13.3.96

import java.io.*;

public class ComsTime_b extends Thread
{
   PipedInputStream  in;
   PipedOutputStream out;
   PipedOutputStream out_report;

   //{{{  ComsTime_b
   ComsTime_b (
      PipedInputStream  an_in,
      PipedOutputStream an_out,
      PipedOutputStream an_out_report)
   {
      in         = an_in;
      out        = an_out;
      out_report = an_out_report;
      start ();
   }
   //}}}  
   //{{{  run
   public void  run ()
   {
      try
      {
         int value;
         while (true)
         {
            value = in.read ();
            out.write (value);
            out_report.write (value);
         }
      }
      catch (IOException ignored)
      {
         System.out.println ("    " + getName() + " method run exception");
      }
   }
   //}}}  
}
//}}}  
//{{{  ComsTime_c.java
// yen.Teig 13.3.96

import java.io.*;

public class ComsTime_c extends Thread
{
   PipedInputStream  in;
   PipedOutputStream out;

   //{{{  ComsTime_c
   ComsTime_c (
      PipedInputStream  an_in,
      PipedOutputStream an_out)
   {
      in = an_in;
      out = an_out;
      start ();
   }
   //}}}  
   //{{{  run
   public void  run ()
   {
      try
      {
         int value;
         while (true)
         {
            value = in.read ();
            out.write (value + 1);
         }
      }
      catch (IOException ignored)
      {
         System.out.println ("    " + getName() + " method run exception");
      }
   }
   //}}}  
}
//}}}  
0yvind Teig

Autronica, Trondheim, Norway
teig@xxxxxxxxxxxx or Oyvind.Teig@xxxxxxxxxxxxxxxxxxxx
47 73 58 12 68 (Tel) 
47 73 91 93 20 (Fax)

--------------------------------------------------------------------------------

From: 0yvind Teig <teig@xxxxxxxxxxxx>
Organization: Autronica AS
To: nuug!barry@xxxxxxxxxxxxxx
Date: Wed, 20 Mar 1996 08:22:47 +0200
Subject: ComsTime.java: the explanation (?)
Cc: nuug!phw@xxxxxxxxx
Priority: normal
X-Mailer: Pegasus Mail for Windows (v2.01)
Status: RO

Dear Barry and Peter

I am, very insensitively, throwing this information at you,
even if I know that you probably have 271 other mails wanting to be
processed!

About ComsTime.java:

It does not help to set priority
It does not help to yield
It does not help to make the communicating part of "main" a separate task
It communicates just as slowly under Windows-NT

The new code (below) adds tests for timer resolution. The strange thing
is that I read 50ms or 60ms - exactly half of each.

I have made an "impedance test": introduced a loop in each thread.
I make it spin, and see how big the loop must be before it increases
the "communication" time. It seems like around 50000 loops per thread
is where it changes. It is hard to measure, since even with no loop,
time varies a lot.

In other words: Java tasks for Windows-95 or Windows-NT are rather coarse-grained.

----------------------------------------------------------------------------------

//{{{  ComsTime.java
// yenyvind Teig 20.3.96
//{{{  Heading
// COMMUNICATION TIMER TEST PROGRAM
// as suggested by Professor Peter Welch
// (University of Kent at Canterbury)
// Originally written for occam, this program tests how Java behaves
//}}}  
//{{{  Results
// According to Lars Thore Aarrestad the original occam code runs like this:
// T800          20 Mhz  occam        12 us
// T800          20 Mhz  SPOC->C     168 us
// Intel 386dx   25 Mhz  SPOC->C      69 us
// TMS320C32-40 (20 Mhz) SPOC->C      57 us
// Intel 486dx2  66 Mhz  SPOC->C       9 us
// Intel Pentium 75 Mhz  SPOC->C       6 us

// This Java-code runs like this:
// Intel 486dx2  66 Mhz  Win-95  1000000 us (a second - what's wrong?)

// It does not help to set priority
// It does not help to yield
// It does not help to make the communicating part of "main" a separate task
// It communicates just as slowly under Windows-NT
//}}}  
import java.io.*;
import java.util.*;
import java.lang.*;

public class  ComsTime
{
   public static void  main (String argv [])
   {
      //{{{  Banner
      System.out.println ("");
      System.out.println ("Test of communication between Java threads");
      System.out.println ("Based on occam ComsTime.occ by Peter Welch, University of Kent at Canterbury");
      System.out.println ("Ported into Java by Oyvind Teig");
      System.out.println ("");
      //}}}  
      try
      {
         //{{{  Test time resolution
         long shortest        = 100000000;
         long longest         = 0;
         long mean            = 0;
         int  noOfNonZeroVals = 0;

         int Cnt = 10;
         System.out.println ("Calculates timer resolution:");
         while (noOfNonZeroVals < Cnt)
         {
            Date date1 = new Date ();
            Date date2 = new Date ();
            long diff  = date2.getTime() - date1.getTime();
            if (diff > 0)
            {
               mean            = mean + diff;
               shortest        = Math.min (diff, shortest);
               longest         = Math.max (diff, longest);
               noOfNonZeroVals = noOfNonZeroVals + 1;
            }
         }
         mean = mean / ((long) noOfNonZeroVals);
         //{{{  Report
         System.out.println ("    noOfNonZeroVals " + noOfNonZeroVals);
         System.out.println ("    shortest        " + shortest + " [ms]");
         System.out.println ("    longest         " + longest  + " [ms]");
         System.out.println ("    mean            " + mean     + " [ms]");
         //}}}  
         //}}}  
         int NoOfLoops = 10;
         int NoOfThreadLoops = 100000;
         //{{{  Streams
         PipedOutputStream out_a  = new PipedOutputStream ();
         PipedInputStream  in_a   = new PipedInputStream  (out_a);
         out_a.connect    (in_a);

         PipedOutputStream out_b  = new PipedOutputStream ();
         PipedInputStream  in_b   = new PipedInputStream  (out_b);
         out_b.connect    (in_b);

         PipedOutputStream out_c  = new PipedOutputStream ();
         PipedInputStream  in_c   = new PipedInputStream  (out_c);
         out_c.connect    (in_c);

         PipedOutputStream out_d  = new PipedOutputStream ();
         PipedInputStream  in_d   = new PipedInputStream  (out_d);
         out_d.connect    (in_d);
         //}}}  
         //{{{  Report
         System.out.println (NoOfLoops + " loops:");
         //}}}  
         //{{{  Start threads
         ComsTime_a aComsTime_a = new ComsTime_a (in_b, out_a, NoOfThreadLoops);
         ComsTime_b aComsTime_b = new ComsTime_b (in_a, out_c, out_d, NoOfThreadLoops);
         ComsTime_c aComsTime_c = new ComsTime_c (in_c, out_b, NoOfThreadLoops);
         //}}}  
         //{{{  Time tag
         Date date1 = new Date();
         //}}}  
         //{{{  Loop: Wait for report of rounds
         int rounds;
         rounds = 0;
         int valueAlso_rounds = 0;

         while (rounds < NoOfLoops)
         {
            rounds = rounds + 1;
            valueAlso_rounds = in_d.read ();
            System.out.println (valueAlso_rounds);
         }
         //}}}  
         //{{{  Time tag
         Date date2 = new Date();
         //}}}  
         //{{{  Report
         long microseconds   = ((date2.getTime() - date1.getTime()) * 1000);
         long timePerLoop_us = (microseconds / ((long) NoOfLoops));

         System.out.println ("   " + timePerLoop_us + " microseconds / iteration");
         //}}}  
         //{{{  Stop threads
         aComsTime_a.stop ();
         aComsTime_b.stop ();
         aComsTime_c.stop ();

         try
         {
            aComsTime_a.join ();
            aComsTime_b.join ();
            aComsTime_c.join ();
         }
         catch (InterruptedException ignored) {}
         //}}}  
      }
      catch (IOException ignored) {}
   }
}
//}}}

  
//{{{  ComsTime_a.java
// yen.Teig 20.3.96

import java.io.*;

public class ComsTime_a extends Thread
{
   private PipedInputStream  in;
   private PipedOutputStream out;
   private int loop;

   //{{{  ComsTime_a
   ComsTime_a (
      PipedInputStream  an_in,
      PipedOutputStream an_out,
      int a_loop)
   {
      setName ("ComsTime_a");
      in = an_in;
      out = an_out;
      loop = a_loop;
      start ();
   }
   //}}}  
   //{{{  run
   public void  run ()
   {
      // System.out.println ("    " + getName() + " " + toString());
      try
      {
         out.write (0);
         int value;
         while (true)
         {
            value = in.read ();
            out.write (value);
            //{{{  loop
            int cnt = loop;
            while (cnt > 0) {cnt = cnt - 1;}
            //}}}  
         }
      }
      catch (IOException caught)
      {
         System.out.println ("    " + getName() + " method run exception");
      }
   }
   //}}}  
}
//}}} 

 
//{{{  ComsTime_b.java
// yen.Teig 20.3.96

import java.io.*;

public class ComsTime_b extends Thread
{
   private PipedInputStream  in;
   private PipedOutputStream out;
   private PipedOutputStream out_report;
   private int loop;

   //{{{  ComsTime_b
   ComsTime_b (
      PipedInputStream  an_in,
      PipedOutputStream an_out,
      PipedOutputStream an_out_report,
      int a_loop)
   {
      setName ("ComsTime_b");
      in         = an_in;
      out        = an_out;
      out_report = an_out_report;
      loop       = a_loop;
      start ();
   }
   //}}}  
   //{{{  run
   public void  run ()
   {
      // System.out.println ("    " + getName() + " " + toString());
      try
      {
         int value;
         while (true)
         {
            value = in.read ();
            out.write (value);
            out_report.write (value);
            //{{{  loop
            int cnt = loop;
            while (cnt > 0) {cnt = cnt - 1;}
            //}}}  
         }
      }
      catch (IOException caught)
      {
         System.out.println ("    " + getName() + " method run exception");
      }
   }
   //}}}  
}
//}}}

  
//{{{  ComsTime_c.java
// yen.Teig 20.3.96

import java.io.*;

public class ComsTime_c extends Thread
{
   private PipedInputStream  in;
   private PipedOutputStream out;
   private int loop;

   //{{{  ComsTime_c
   ComsTime_c (
      PipedInputStream  an_in,
      PipedOutputStream an_out,
      int a_loop)
   {
      setName ("ComsTime_c");
      in   = an_in;
      out  = an_out;
      loop = a_loop;
      start ();
   }
   //}}}  
   //{{{  run
   public void  run ()
   {
      // System.out.println ("    " + getName() + " " + toString());
      try
      {
         int value;
         while (true)
         {
            value = in.read ();
            out.write (value + 1);
            //{{{  loop
            int cnt = loop;
            while (cnt > 0) {cnt = cnt - 1;}
            //}}}  
         }
      }
      catch (IOException caught)
      {
         System.out.println ("    " + getName() + " method run exception");
      }
   }
   //}}}  
}
//}}}  

Cheers,
0yvind Teig

Autronica, Trondheim, Norway
teig@xxxxxxxxxxxx or Oyvind.Teig@xxxxxxxxxxxxxxxxxxxx
47 73 58 12 68 (Tel) 
47 73 91 93 20 (Fax)

--------------------------------------------------------------------------------

From: 0yvind Teig <teig@xxxxxxxxxxxx>
Organization: Autronica AS
To: nuug!barry@xxxxxxxxxxxxxx
Date: Wed, 20 Mar 1996 09:16:21 +0200
Subject: ComsTime.java for Linux
Cc: nuug!phw@xxxxxxxxx
Priority: normal
X-Mailer: Pegasus Mail for Windows (v2.01)
Status: RO

Again! 

I guy just came down to me and told he'd installed Java on his
Linux machine. We tried my code.

Timer reolution was 1 ms flat.

"Communication" time was still about the same as on Win-95 and NT.

However, *in*creasing the loadwork in each thread *de*creased 
"communication" time. 100000 loops gave 1 sec, whereas 1 loop
gave 2.7 sec.

Like "since your're so busy I'll let you do your thing" - and
"lazy boy, you'll have to wait".

This is fun, even if occam is, in many respects, a much better 
language!


0yvind Teig

Autronica, Trondheim, Norway
teig@xxxxxxxxxxxx or Oyvind.Teig@xxxxxxxxxxxxxxxxxxxx
47 73 58 12 68 (Tel) 
47 73 91 93 20 (Fax)

--------------------------------------------------------------------------------

Date: Wed, 20 Mar 96 12:26:55 GMT
From: phw <P.H.Welch@xxxxxxxxx>
Message-Id: <9603201226.AA10078@xxxxxxxxxxxxxxx>
To: teig@xxxxxxxxxxxx
Subject: Re: ComsTime.java: the explanation (?)
Cc: jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx, roebbers@xxxxxxxxxxxxx,
        wotug-com@xxxxxxxxx
Status: RO


Hi Oyvind,

I am quickly reading (and filing) the stuff you have been sending on
Java thread overheads ... and will think about it real soon now!

What I'd like to get a handle on are the Java (as it is implemented):

  o overheads for an explicit "yield" from a thread;

  o call to a synchronised method (no parameters) -- i.e. what is the
    overhead for locking the semaphore that controls access from threads
    to that method?

So far as I can see from a rapid reading of the language manual, Java
incorporates a bland threads mechanism into the language that gives
absoulutely no security against thread-unsafe programming.  As far as
its support for parallel programming is concerned, it seems to have
no lessons to teach occam -- the reverse very much seems to be the case.

Objects offering synchronised methods are just servers (i.e. cyclic
processes ALTing at the start of their loop body for a method call).
Each synchronised method can be called from any thread -- so this is
just a SHARED CALL channel in occam3 terms.

Otherwise, threads can share data and it's up to the programmer to
use the semaphores implicit in synchronised method calls to prevent
uncontrolled non-determinism.

Java can do nothing to prevent threads updating and reading data at
the same time since it has no ability to control name aliasing --
something at which occam has to, and does, excel.  Enclosed is a
small Java example to demonstrate this -- my first Java program!
It's just the "harmless" procedure that I used in my "Going to Ceed"
and "Role and Future of occam" papers from long ago.  It shows that
Java has the same semantic complexities ("singularities") as C, Pascal
and all the others -- excepting occam ...

These semantic singularities are dangerous!

They did a great job applying occam's razor to C/C++ to get rid of the
high-level superstructure and yield Java.  Unfortunately, all the
low-level rubbish of C still remains -- assignment as an operator, ++,
the total confusion between methods that return values (i.e. functions)
and methods that cause state change (i.e. procedures), a for-loop that
ain't a for-loop, break/continues out of loops (labelled loops ain't
the answer, they need occam's if-loops), etc.  They need to finish the
job!!!

Cheers,

Peter.

cc: wotug-com, ofa-com

(cut here)
-----------------------------------------------------------------------------

Below is a script session.  It first lists a Java program, then compiles
and runs it.  The last line shows the semantic singularity ...

bay% more alias_test.java
class thing
{
  int x;

  public thing(int v)
  {
    x = v;
  }

  public static void harmless (thing t1, thing t2)
  {

    // this doesn't look as though it changes anything ...
    // but it's semantics is not WYSYWIG (as in occam) ...
    // it depends on the context of its call ...

    // if t1 and t2 are different objects, it is harmless ...
    // if t1 and t2 are aliases for the same object, it zaps it !!!

    // in occam, since t1 and t2 are different names, we know that
    // they are different objects: what-you-see-is-what-you-get ...
    // so if this were occam, there is no context dependency and
    // the `obvious' harmless semantics is universally obeyed.

    t1.x = t1.x + t2.x;
    t1.x = t1.x - t2.x;
  }
}

class alias
{
  public static void main (String args[])
  {
    thing c1 = new thing(10);
    thing c2 = new thing(20);

    System.out.println("BEFORE: c1 = " + c1.x + ", c2 = " + c2.x);

    thing.harmless (c1, c2);

    System.out.println(" AFTER: c1 = " + c1.x + ", c2 = " + c2.x);

    thing.harmless (c1, c1);

    System.out.println(" ALIAS: c1 = " + c1.x + ", c2 = " + c2.x);

  }
}
bay% javac alias_test.java
bay% java alias
BEFORE: c1 = 10, c2 = 20
 AFTER: c1 = 10, c2 = 20
 ALIAS: c1 = 0, c2 = 20

--------------------------------------------------------------------------------

To: phw <P.H.Welch@xxxxxxxxx>
Cc: teig@xxxxxxxxxxxx, jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx,
        roebbers@xxxxxxxxxxxxx, wotug-com@xxxxxxxxx
Subject: Re: ComsTime.java: the explanation (?)
In-Reply-To: Your message of "Wed, 20 Mar 1996 12:26:55 GMT." <9603201226.AA10078@xxxxxxxxxxxxxxx>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Date: Wed, 20 Mar 1996 13:02:17 +0000
From: Paddy Nixon <pnixon@xxxxxxxxxxxxx>
Status: RO


You may be interested in the Concurrent Programming in Java: Tutorials and 
design patterns. The url is http://g.oswego.edu/dl/pats/aopintro.html

Paddy

--------------------------------------------------------------------------------

From: "B.M. Cook" <barry@xxxxxxxxxxxxxx>
Message-Id: <10350.9603211055@xxxxxxxxxxxxxxxxxxx>
Subject: Re: ComsTime.java: the explanation (?)
To: P.H.Welch@xxxxxxxxx (phw)
Date: Thu, 21 Mar 1996 10:55:00 +0000 (GMT)
Cc: teig@xxxxxxxxxxxx, jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx,
        roebbers@xxxxxxxxxxxxx, wotug-com@xxxxxxxxx
In-Reply-To: <9603201226.AA10078@xxxxxxxxxxxxxxx> from "phw" at Mar 20, 96 12:26:55 pm
X-Mailer: ELM [version 2.4 PL21]
Content-Type: text
Status: RO

Hi Oyvind, and others (in reply to Peter's message) ...

I looked at the source of PipedInputStream - there is a suspicious
"wait(1000)" statement a couple of times!  I tried reducing it to 1, with no
effect; and removing the lines altogether and that stopped it working at
all!  I'm not sure PipedI/O is "properly" implemented (is wait(...) really a
voluntary de-schedule?).

> So far as I can see from a rapid reading of the language manual, Java
> incorporates a bland threads mechanism into the language that gives
> absoulutely no security against thread-unsafe programming.  As far as
> its support for parallel programming is concerned, it seems to have
> no lessons to teach occam -- the reverse very much seems to be the case.

I do agree.

> They did a great job applying occam's razor to C/C++ to get rid of the
> high-level superstructure and yield Java.  Unfortunately, all the
> low-level rubbish of C still remains -- assignment as an operator, ++,

I still don't agree that these should be a problem in a concurrent language
- Algol68 placed a simple interpretation on them that is perfectly safe (and
the occam checker can test if the program is OK).

              Barry.

--------------------------------------------------------------------------------

Date: Thu, 21 Mar 96 14:29:39 GMT
From: phw <P.H.Welch@xxxxxxxxx>
Message-Id: <9603211429.AA06976@xxxxxxxxxxxxxxx>
To: barry@xxxxxxxxxxxxxx
Subject: Re: ComsTime.java: the explanation (?)
Cc: jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx, roebbers@xxxxxxxxxxxxx,
        wotug-com@xxxxxxxxx
Status: RO


Barry et al.,

> > They did a great job applying occam's razor to C/C++ to get rid of the
> > high-level superstructure and yield Java.

Just to reinforce what was meant here, this really seems good.  Dumping
user-defined data-structures (records, unions, typedefs) and user-defined
algorithm structures (functions/procedures) and replacing them with one
unifying structuring mechanism (classes) was inspired.

[Following that line of thought, maybe occam should dump its shiny new
RECORDs, its PROCs and its FUNCTIONS and replace them with the MODULE!
I don't think so ... but that may be more to do with weaknesses in the
MODULE concept currently proposed than with the general principle ... 
humm, this may be too radical ... ?]

> >                                           Unfortunately, all the
> > low-level rubbish of C still remains -- assignment as an operator, ++,
>
> I still don't agree that these should be a problem in a concurrent language

It's not that they are a problem for a concurrent language.  It's that
they are a problem for *any* language -- they certainly make a great big
mess for serial programming!

> - Algol68 placed a simple interpretation on them that is perfectly safe (and
> the occam checker can test if the program is OK).

I'm sorry I never got to grips with Algol68 -- did it really have assignment
as an operator and side-effecting `functions'?  How did it make them safe??
Maybe by defining the order of expression evaluations -- in which case, they
no longer have the simple semantics of mathematical expressions?

Cheers,

Peter.

--------------------------------------------------------------------------------

From: "B.M. Cook" <barry@xxxxxxxxxxxxxx>
Message-Id: <12400.9603211516@xxxxxxxxxxxxxxxxxxx>
Subject: Re: ComsTime.java: the explanation (?)
To: P.H.Welch@xxxxxxxxx (phw)
Date: Thu, 21 Mar 1996 15:16:56 +0000 (GMT)
Cc: barry@xxxxxxxxxxxxxx, jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx,
        roebbers@xxxxxxxxxxxxx, wotug-com@xxxxxxxxx
In-Reply-To: <9603211429.AA06976@xxxxxxxxxxxxxxx> from "phw" at Mar 21, 96 02:29:39 pm
X-Mailer: ELM [version 2.4 PL21]
Content-Type: text
Status: RO

Peter, et al.,

> [Following that line of thought, maybe occam should dump its shiny new
> RECORDs, its PROCs and its FUNCTIONS and replace them with the MODULE!
> I don't think so ... but that may be more to do with weaknesses in the
> MODULE concept currently proposed than with the general principle ... 
> humm, this may be too radical ... ?]

Hmm, maybe - this needs a good deal of thought.


> I'm sorry I never got to grips with Algol68 -- did it really have assignment
> as an operator and side-effecting `functions'?  How did it make them safe??

Yes.

> Maybe by defining the order of expression evaluations -- in which case, they
> no longer have the simple semantics of mathematical expressions?

No, it added rules about what constituted a legal program, not dissimilar to
occam's.

To paraphrase greatly ...
Basically, it was illegal to have 2 (or more) unsafe concurrent processes,
and then defined concurrent ("collateral" in Algol68) ...
e.g. the operands of an operator are executed concurrently
 - so the Algol68 equivalent of "i++ + x[i++]" is illegal because i is written
 to on both sides of "+"
e.g. a comma indicates concurrency
 - so lists of values for arrays, or parameters to procedures can be
 checked. From your example, "harmless(x,x)" is illegal since there are
 concurrent writes to x  [I can't remember the rule, or even if there was
 one, about avoiding the problem with one parameter and a global - there
 wasn't a clearly specified anti-aliasing rule as such.]

BUT - Algol68 also had pointers (references) that allowed you to avoid the
rules (which weren't implemented on all compilers since not all compilers
actually ran concurrent programs in parallel).

Unfortunately, Algol68 isn't the answer to everything (it's the answer to
enough that I still use it daily) - but it did have some very well thought-out
ideas.

The above (badly presented) insight into expressions and side effects, with
occam's anti-aliasing DOES (I believe) show us how to allow the dreaded ++
etc., safely (and those operators are a good short-hand which removes
unnecessary typing - and a source of error through mis-typing [OK, occam
tries with its abbreviations but splitting an expression onto 2 lines is not
always very readable]).


		Barry.

--------------------------------------------------------------------------------

Date: Thu, 21 Mar 96 16:30:53 GMT
From: phw <P.H.Welch@xxxxxxxxx>
Message-Id: <9603211630.AA10416@xxxxxxxxxxxxxxx>
To: barry@xxxxxxxxxxxxxx
Subject: Re: ComsTime.java: the explanation (?)
Cc: jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx, roebbers@xxxxxxxxxxxxx,
        wotug-com@xxxxxxxxx
Status: RO


Hi,

Ah-ha ... so expressions are evaluated in parallel and the normal usage
rules apply ... so we can let expressions have side-effects safely ... 
the usage rules ensure that the side-effects are disjoint so that
evaluation remains deterministic.  That's neat ... like it!

As an (ex-)mathematician, however, it still goes against the grain to
let expressions have side-effects.  Expression evaluation (which includes
function evaluation) should yield the same answer every time it occurs
with its variables having the same values -- that's what a `function'
means: we give it the same parameters, we get the same answer.  As
soon as we allow the function to cause a side-effect, that guarantee
is lost and the semantics is much more complicated ... even though it
its (parallel) evaluation may now be deterministic.

It's the complex semantics of side-effecting expressions that is the
(remaining) reason for arguing against them ... and that applies to
serial programming as much as to parallel stuff:

> e.g. a comma indicates concurrency
>  - so lists of values for arrays, or parameters to procedures can be
>  checked. From your example, "harmless(x,x)" is illegal since there are
>  concurrent writes to x  [I can't remember the rule, or even if there was
> one, about avoiding the problem with one parameter and a global - there
> wasn't a clearly specified anti-aliasing rule as such.]

The "harmless" procedure/method only assigns to its first parameter.
Hence, "harmless(x,x)" doesn't have concurrent writes to x and will,
I guess, be accepted by Algol68 ... and will show the semantic singularity
that makes things so complicated.  It's not the concurrency rules it
violates, it's the aliasing one ... and Java, C, C++, Pascal, Modula,
Ada, SuperPascal (can anyone confirm SuperPascal?) and just about
every procedural language, bar occam, all fall into it!

Cheers,

Peter.

--------------------------------------------------------------------------------

Date: Fri, 22 Mar 96 09:51:31 GMT
From: phw <P.H.Welch@xxxxxxxxx>
Message-Id: <9603220951.AA23812@xxxxxxxxxxxxxxx>
To: jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx, roebbers@xxxxxxxxxxxxx,
        wotug-com@xxxxxxxxx
Subject: What's Dylan?
Status: RO


I received the following from a mailing list to which I can't seem to
detach myself:

> > of course, if you switch to teaching s/w engineering, programming,
> > GUI/Graphics, HCI, and networks and distributed systems by using Java,
> > then you shouldn't care what platform you use...for O/S or H/W
> 
> I can't comment. I am still ignorant about Java, though I was told
> recently by one of the designers of Dylan that he felt Java was a poor
> substitute for Dylan but would win over it because of the push from Sun.
> But we all know that what wins in the market place has nothing to do
> with technical merit....

It seems there are some other players out there!  Anyone know anything
about Dylan?

Cheers,

Peter.

--------------------------------------------------------------------------------

From: geoffb@xxxxxxxxxxxxxx (Geoff Barrett)
Date: Fri, 22 Mar 1996 09:59:53 +0000
In-Reply-To: phw <P.H.Welch@xxxxxxxxx> "What's Dylan?" (Mar 22, 9:51am)
References: <9603220951.AA23812@xxxxxxxxxxxxxxx>
X-Mailer: Z-Mail (3.2.0 06sep94)
To: phw <P.H.Welch@xxxxxxxxx>
Subject: Re: What's Dylan?
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Status: RO

If I remember correctly, it's some variant of Lisp that is being peddled by
Harlequin.



-- 
------------------------------------------------------------------------
Geoff Barrett		Tel: +44 1454 611467	Fax: +44 1454 620688
SGS-Thomson Microelectronics Limited
1000 Aztec West, ALmondsbury, Bristol BS12 4SQ, England
------------------------------------------------------------------------

--------------------------------------------------------------------------------

Date: Fri, 22 Mar 96 16:40:35 GMT
From: phw <P.H.Welch@xxxxxxxxx>
Message-Id: <9603221640.AA04732@xxxxxxxxxxxxxxx>
To: jsunter@xxxxxxxxxxxxx, ofa-com@xxxxxxxxx, roebbers@xxxxxxxxxxxxx,
        wotug-com@xxxxxxxxx
Subject: SuperPascal
Status: RO


Dear All,

Just for the record, I checked out Brinch Hansen's SuperPascal (see
Software Practice and Experience, May, 1994, pp. 467-483).  [Aside:
a referee on my submission to UKPar96 complained that I had made no
reference to it -- nor to PVM, MPI, ...]

SuperPascal is described as a "secure programming language for the
publication of parallel scientific algorithms".  

It has explicit synchronised message passing over typed channels.

It has something that gives you an occam CASE protocol (except that the
receiving side *has* to know the type of the incoming variant -- if you
get it wrong, you remain blocked until someone sends you the one you
were expecting -- the different variants flow down logically separate
channels).

It has no sequential protocol, but you can, of course, send records as
messages.  Variant records are not in the language.

There are no pointers or dynamic memory allocation.

It has no counted array protocol -- you need to get message sizes right.

It has something equivalent to the PAR and replicated PAR ("parallel"
and "forall" constructors respectively).  It has the exact same parallel
usage rules as occam.  The compiler checks that these are obeyed.
To do that, it has to take care about aliasing.  It has the same
anti-aliasing rules as occam -- thus, you can't pass the same actual
variable to different VAR parameters.  Hence, my "harmless (x, x)"
will be properly stamped upon -- just like in occam.  Hurray!

It has a "sic" construct to turn off usage-checking on blocks of code.

There is no ALT or any suggestion of the need for one.

There is no timeout support.

Channel variables are references to channels.  The channels themselves
are created at run-time and live for the duration of the program.
Multiple channel variables can point to the same channel -- here's
a point where aliasing problems may creep back in (?).

Therefore, any process may have channel variables giving it access to
any channel -- i.e. channels are not bound as a private connection
between two processes.  But, channels *must* be used as a private
connection between two processes.  There doesn't seem to be anything
to prevent two processes attempting to output to (or input from) the
same channel -- you just get a *run-time* error if they do!

There is recursion (but, as a publication language, so does occam).

Conclusion: SuperPascal seems to be a pale imitation of the facilities
provided by occam, giving nothing new, missing several items and
allowing needless run-time errors (although giving deterministic
parallelism through adopting the same usage rules).  The parallel
facilities it does have are exact copies of occam equivalents.  It
was published 11 years after the first occam systems became available,
but the SP&E paper makes no reference to occam (nor to CSP).

Sigh ...

Peter.

--------------------------------------------------------------------------------