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

Re: Rick's musings on modifications to occam

Some thoughts on Richard's Musings #1 and #2:

Paragraphs 1 to 5 talk about dynamic memory controlled by the compiler. 
I think both (array and PAR changes) would be a good idea. I'd like to 
add, though, one extra item:

It might be a "good thing" to have a tool (perhaps a mode of the 
compiler?) by which , given actual sizes for arrays in the compiler, the 
compiler can continue and do it's current full check of memory sizes. This
would allow a designer to verify that in normal forseeable cases there 
are no problems, leaving the dynamic allocation to, perhaps, allow the 
reuse of memory (e.g. if one module needs 10k, another 20k, currently the 
system must have 30k free. However, if the designer knows that when 
module 1 wants 10k, module 2 needs a max of 5k, the system needs only 
15k. Checking the program with these sorts of constraints would be a Big 
problem without some help.


I am not so happy about the model for array resizing, in particular the
hidden relationship between 'n' in the para 10 example and the array size. I
think overall I would prefer a REALLOC operator: 

VAL n is 10:
[n]THING myHeap:
        REALLOC [n+m]myHeap:

I can't remember if SIZE returns the number of elements or the byte size of
an array; if the latter we should have a way of returning the former (perhaps
LENGTH ?) so that code could have REALLOC [LENGTH(myHeap)+2]myHeap: 

Note that because we don't have pointers, the compiler should be free to 
move the array if there is insufficient space otherwise.

I'm still not fond of this; it breaks the normal rule that a declaration 
is only effective within it's block. Can anyone do better?


Regarding new data types and operator overloading... well, whilst I can agree
it would be handy on occasion to have a Complex type, I would prefer to
provide the full thing (as in C++) rather than just for the simple maths
operators. This would mean that when a compiler saw any operator, it would
have to look up in a table whether that operator was defined. To do this it
would construct a name e.g. "operator_mul" for *, and find the possible
functions to call. It would then have to do either a strist match of the args
(so if it had the call "a := b * 1" with b an INT32, it would have to find
operator_mul_INT32_INT) or a lazy match (i.e. search the possible conversions
and say " well I could convert "INT to INT32" and use

I'm not quite sure whether loose matching should be allowed; it dramatically
simplifies the code, but at the expense of a certain uncertanty about which
functions are being called. 


Regarding polymorphism; It's something which is very handy in many
programming situations, particularly regarding common data structures. First
of all, I agree that the use of RETYPES is poor; you get very little
assurance that what you are doing is legal. In C++, the principle is used 
that functions acting on the base type can be applied to the supertype, 
but not vice versa. In general this is a good thing, but with the use of 
class member functions, the virtual keyword, allowing the supertype to 
jump in and override base function calls in order to maintain it's state 
is vital.

I don't really like the BASEOF operator; as Rick says, for types multiply 
renamed, the meaning id unclear, and IMHO even (BASEOF BASEOF t) is no 

While Occam remains a non-OO language, how about allowing the syntax 
(using the examples Rick provided):

  len := stringLength(([]BYTE) string)

i.e. you 'cast' the supertype to the parent type using the parent type's 
type name. Of course, this adds no code, as the supertype must contain 
the parent type for it to be legal.

Of course if we were to allow for user-defined casts as a result of the 
polymorphism extensions, we could simply define an operator:


  len := stringLength(string)

which could then be called automatically by the compiler in the sure 
knowledge that doing so was OK. 


Regarding Enumerated types; I thing Rick's example in para 24 is good, 
and the meaning laid out in para 25 seems fine - much better than the 
UNION method. We could extend it to allow the initial value to be 
specified too, however:

DATA TYPE LOGICSTATE IS [False = 1, True, Tristate]:

This would be of use mainly when casting to INT type (e.g. to print the 

However, I dispute the use of SIZE here - it is to me counter-intuitive, 
and should we wish to allow this sort of operator, we should provide a 
proper way of doing it; LAST seems fine to me:

s := LAST LOGICSTATE   => s := Tristate

We could even add FIRST to get the whole range:

s := FIRST LOGICSTATE  => s := False

As a final note, how about adding the ranged integer to this:


as an obvious security extension?


Regarding thoughts about "." and [x], I agree things have probably gone 
too far to change them now.


Array Indices (Musings 2). I think the suggestion has merit, and 
certainly permits greater run time checking and security. I must admit I 
failed to get the point of the example in para 34, however.



Ruth Ann Ivimey-Cook    	   |               ruthc@xxxxxxxxxxxxxxxxxx
Just living my life as best I can. |                             Marlow, UK
And trying not to be an Also-Ran!  | http://www.telergy.com/ruthc/ruth.html