From: roger@gimli.inmos.co.uk (Roger Shepherd)
Subject: Re: occam
Organization: INMOS Limited, Bristol, UK
Date: Mon, 17 Aug 1992 08:59:00 GMT



In article <1462@eagle.ukc.ac.uk>, wgd@ukc.ac.uk (W.G.Day) writes:
|> In article <2490@news.cerf.net> jcbhrb@nic.cerf.net (Jacob Hirbawi) writes:
|> 

|> >(2) I fail to see the advantage of having no operator hierarchy or default 
|> >    data types:
|> 
|> >    why write this:
|> 
|> >       (1.0 (REAL32) + (2.0 (REAL32) * 3.0 (REAL32))) - 4.0 (REAL32)
|> 
|> >    and count brackets when all I'm trying to do is:
|> 
|> >       1.0 + 2.0*3.0 - 4.0
|> 

Question 1:  Data types

How is a poor compliler supposed to know that that is what you meant? This is
a real, serious question, after all you might have meant

     (1.0 (REAL64) + (2.0 (REAL64) * 3.0 (REAL64))) - 4.0 (REAL64) 

Acctually, this is a poor example, since this expression JUST HAPPENS to give
the same result evaluated single or double precision.  This is not always the
case - try replacing the * with a /.

However, if the expression is seen in context, for example

     REAL32 result :
     SEQ
       result := (1.0 (REAL32) + (2.0 (REAL32) / 3.0 (REAL32))) - 4.0 (REAL32)

then is is arguable that the compiler might reasonably deduce that 1.0
meant 1.0(REAL32); of course, the language would have to state that this was
what happened, AND it would open up a certain risk of programming errors
not being detected, for example, 

        result :=  (1.0 + (2.0 / 3.0)) - 4.0

would be legal, and interpretted as 

        result := (1.0 (REAL32) + (2.0 (REAL32) / 3.0 (REAL32))) - 4.0 (REAL32)

even if the programmer had really meant

        result :=  REAL32((1.0(REAL64) + (2.0(REAL64)/3.0(REAL64))) - 4.0(REAL64))

which signifies a different computation.

Now on balance, **** I ****** (me, that it is, not INMOS) feel that inferring the
data types of literals in these situations would be a good thing, and would
improvge readability - however, the issue is not straightforward.


Question 2: Operator precidence and non-associative operators.

Well, let us suppose that we have inferrence of the data type of literals. Then
our example would be either

              1.0 + 2.0/3.0 - 4.0

or

             (1.0 + (2.0/3.0)) - 4.0

Now, how is the compiler supposed to know that the second example is
what was meant? How indeed? How does it know that you didn't mean 

              1.0 + ((2.0/3.0)) - 4.0)

which is, again, a different computation? (If we were dealing with real numbers 
then (a + (b/c)) - d = a + ((b/c) - d) for non-zero c. However, computers
use only an approximation to the reals, for which the addition operation is
NOT associative).

Again, on balance ,  **** I ****** think that occam ought to obey the
usual operator precidence rules that you learn at school. That would let 
you write

            1.0 + (2.0/3.0 - 4.0) 
or
           (1.0 + 2.0/3.0) - 4.0

depending on what you actually meant. Also, for the genuinely associative 
operators, like BITAND, it ought to let you drop the parenthesisation. However,
the non-quite associatives,  like +, cause me more worry. Again though,
on balance, having written and read numeric programs in occam 2, I would
allow them to be dropped, and for the language to impose a left to right
evaluation rule. Of course, if brakets were used, the compiler would have to obey
them (unlike some other languages I could name). So, the original example
could be written 

            1.0 + 2.0/3.0 - 4.0

and if you really wanted


            1.0 + (2.0/3.0 - 4.0)

that's what you'd write.

As for expressions which mix computer science operations (eg >>) with good
old arithmetic ones (eg +); these should be paraenthesised.

|> Occam's approach to typing like this is hard on the fingers and brain sometimes
|> but it does make look at what you want the machine to do.  I once realised
|> that although the obvious way to do something was,
|> 
|>   REAL64 hello, there:
|>   INT world:
|>   ((REAL32 ROUND hello) * (REAL32 ROUND there)) + (REAL32 ROUND world)
|> 
|> it was faster to do,
|> 
|>   REAL32 ROUND (hello * there) + (REAL64 ROUND world)
|> 
|> although I think C gets it right in this case, it may not in general and in a
|> critical loop its nice to have full control.
|>

These also give different results!

There is some discussion about this subject in  ``The development of occam 2''
in the Transputer Applications Notebook - Architecture and Software.



-- 
Roger Shepherd, INMOS Ltd   JANET:    roger@uk.co.inmos 
1000 Aztec West             UUCP:     ukc!inmos!roger or uunet!inmos-c!roger
Almondsbury                 INTERNET: roger@inmos.com
+44 454 616616              ROW:      roger@inmos.com OR roger@inmos.co.uk