[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:
WHILE TRUE
SEQ
...
IF
more.memory
REALLOC [n+m]myHeap:
TRUE
SKIP
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
operator_mul_INT32_INT32).
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
better.
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:
STRING OPERATOR ([M]BYTE str)
...
:
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
value).
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:
DATA TYPE ASCII IS INT[32..128]:
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