On data types

Ursula Dreier Ursula.Dreier@ruhr-uni-bochum.de
Sat, 28 Nov 1998 23:13:22 +0100


Pardon me - I made a mistake transferring the original article. Here's the
part that is missing at the beginning of it:


Basic data types - I as a user would not like to be bothered with
implementation details unless really necessary. Have a look at Microsoft's
1001 string types - what a mess! So I would like to declare a string as a
string (exactly like any other basic data type), without having to specify a
code set, a length, a storage format or things like that. Same thing holds
true with numbers - normally I would like to declare just a number which can
take any value. If I really wanted to specify it to be an integral, I would
like to be able to do so, of course. But the thing should behave exactly like
any other number, apart from having a built-in truncation feature.

Pointers - Programmers are so used to pointers that they can hardly think of
how to do without. But consider Java - they don't have pointers, just arrays.

And the language I used to write business apps in for a long time
(SqlWindows, now Centura) doesn't have pointers either (but they have
"receive parameters", which are in-out parameters equivalent to thing& in
C++, window handles and arrays).

Pointers are dangerous. They tend to be uninitialized, leading to unwanted
program behaviour.

Pointers are more difficult to declare and use than ordinary variables. Every
time when it comes to declaring function pointers in C, I still have to think
how to put it right. (There is no need to use the same awkward syntax in this
project, of course).

Don't understand me wrong - of course references are used internally, but I
think we should design the language in a way that allows the USER to do
without pointers wherever possible, or at least enforces using them in a safe
way.


Here's my suggestion:

If you declare an object without assigning it a value at that point, a new
object will automatically be created and bound to that name. If you
initialize it in the declaration, the resulting value of the initialization
expression will be bound to that name:

aNumber: x   // a new number object, initialized to default value (say, 0)
aNumber: x = a  // a new number object, initialized to the current value of a

    // (maybe the value will be shared as long as it is remains unchanged)
aPerson: Smith  // a new Person object, initialized to default values
aPerson: Jones = Smith // a new Person object, containing a flat copy of
Person Smith.


"flat" copy means: Only the top-level object is copied, not the objects being
referenced. So if Person contains members, they are shared. If you change
Smith's mail address, you also change Jones mail address because they
actually are the same. If you don't want this, you need to specify it in the
copy constructor, which could look like this:

aClass: aPerson    ! Class specification
 ...
 Instance items   ! Section for instance items
  ...
  aMailAdress: MailAdress
  ...
 Virtual class items  ! Items which all instances share, e.g. methods, and
that allow late binding
  ...
  Function: new  ! Method specification
   Description: The copy constructor
   Parameters
    aPerson: Template
   ...
   Code
    MailAddress = aMailAddress.new (Template.MailAddress)
    ...



> > There is a way to simulate a pointer to a class aX: Create a new class
> > aPX containing just an instance item of class aX. Because the copy is a
> > flat one, you can have instances reference the same aX object.
>
> Yes, this is basically standard sharing semantics.  I'm not convinced
> this is necessarily the way to go long-term.  In my studies I'm
> beginning to think value semantics with pointer types might be the best
> way, but I'm prepeared to go with sharing semantics at the moment.
>
> > But note also: The instance item is guaranteed always to reference some
> > aX.
>
> Why can't it be a null (no object)?

I think it can be a NULL - (and we might be tempted to use it at least
internally), but there are some serious drawbacks to this:Because NULL
actually isn't an instance of the class in question, you can't apply methods
to it (what should they do?) and you can't access instance items (there are
none). So there has to be some DYNAMIC checking for this case if it were
allowed, and it would cause overhead and be prone to errors if not handled
properly. (Not all the checking can be done automatically - the user would
still have to specify some action if a NULL occurred, say, as an argument). I
would like to avoid runtime checking - it makes debugging so much harder than
having the checks being performed at compile time.