comp.lang.ada
 help / color / mirror / Atom feed
From: bobduff@world.std.com (Robert A Duff)
Subject: Re: Allocating "initialized" limited types...
Date: 1996/09/03
Date: 1996-09-03T00:00:00+00:00	[thread overview]
Message-ID: <Dx5xHt.423@world.std.com> (raw)
In-Reply-To: JSA.96Sep1205656@alexandria


In article <JSA.96Sep1205656@alexandria>, Jon S Anthony <jsa@alexandria> wrote:
>Hmmm, actually there is another point poking through here: What I had
>in mind was an aggregate where all the fields are specified (as non
>copies) - not the sort of case where you use an _object_ of the type
>for the aggregate.  Actually, I didn't even know you could do this -
>thought that was a simple qualified expression (then again, I guess
>that's what an aggregate is...).

A qualified expression can contain any sort of expression inside the
parens, not just an aggregate.  The syntax special-cases aggregates,
just so you can leave out one pair of parens -- you can write T'(a,b,c)
instead of T'((a,b,c)).  And an initialized allocator contains a
qualified expression.

>Fine.  If that is the reasoning that went into it.  My claim is that
>in the user model it does not have to be a copy.

I suspect you're right -- you *could* define a language feature that
made initialization work the way you want.

>> Another useful trick is to make all the record fields into discriminants
>> (possibly of access type).  Then you can initialize them using a
>> discriminant constraint, which does the full coverage check you want.
>
>Yes, I've done this one too - it is _very_ useful, but not in those
>cases where the discriminants are to be hidden.

I don't understand what you mean, here.  Ada 95 added the
"unknown discrims" feature so you can hide discrims.  E.g.:

    package P is
        type T(<>) is ...
    private
        type T(Length, Width: Integer) is ...
    end P;

>Yup, that is precisely the idea that I had in mind by the notion that
>you would not have to define an initialized allocator as a copying
>operation.  You have nailed down what I really had in mind.  The
>reason allocators _seem_ special here, is that there is no object in
>the _user model_ that is being assigned!
>
>X : T := expression; -- Clearly an assignment IN THE USER MODEL to a T object
>
>X : T_Ref := new T'(...); -- NOT an assignment to a T object
>                          -- IN THE USER MODEL.  In the user model
>                          -- a T_Ref object is being assigned!  Sure,
>                          -- in the nefarious innards of the language
>                          -- model this too has an assignment to a T
>                          -- object - as currently defined.

Well, hmph.  If the user has that model, then the user's model is wrong.
The two cases of initialization are entirely analogous.  In the second
case, the heap object is being explicitly initialized.  Look at the
rules in the RM for the two cases -- you will see a lot of parallels,
and that's intentional.

So, I would claim that if the feature you are looking for (a way to
initialize limited objects with compile-time checking for missing
components) existed, then it should exist for initializing stack objects
*and* heap objects.

>> whereas Ada always uses (essentially) type-equivalence-by-name.  Access
>> parameters are helpful, but that only works for parameters.

>Not when you are using access to class wide types.  That is more or
>less the whole point of such things.  One named type representing whole
>sets of possible structures.  Criminey, that's the whole point!

I'm not sure what that "not" refers to, or the "such things".  You *can*
have an access parameter whose designated type is class-wide.  I do it
all the time, precisely because it doesn't require a bogus
type_conversion.  Unfortunately, you can't do that for other things,
like record components and stand-alone variables.  E.g.:

    type T1 is ...
    type T1_Ptr is access all T1'Class;
    
    type T2 is new T1 with ...
    type T2_Ptr is access all T2'Class;
    
    X: T1_Ptr;
    Y: T2_Ptr;

    X := T1_Ptr(Y); -- Grr.

I find the above type_conversion to be annoying rubbish, because it
can't possibly fail, and it doesn't do anything, and it doesn't tell the
reader of the code anything interesting.  It's nice that I can pass Y to
a parameter of type "access T1'Class", but it's annoying that the same
thing doesn't work for things that aren't parameters.  That was *my*
point.  Did I misunderstand *your* point?

Perhaps we should have defined access-to-tagged to allow implicit
conversions up the hierarchy.  It's a bit tricky to get the overload
resolution rules right, so they don't cause Beaujolais effects, but I
think it's possible.

(By the way, we should not have defined the "access all" feature.  We
should have just made all access types work that way.  There's really no
*important* reason for the language to have both "access Foo" and
"access all Foo".  This design mistake was largely my fault -- during
the language design, I argued strongly for the "all" feature.  I've
since changed my mind, since I end up almost always using "all" anyway.)

- Bob




  reply	other threads:[~1996-09-03  0:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1996-08-30  0:00 Allocating "initialized" limited types Jon S Anthony
1996-08-31  0:00 ` Robert A Duff
1996-09-02  0:00   ` Jon S Anthony
1996-09-04  0:00     ` Joel VanLaven
1996-09-05  0:00       ` Robert A Duff
1996-09-06  0:00     ` Jon S Anthony
1996-09-02  0:00   ` Jon S Anthony
1996-09-03  0:00     ` Robert A Duff [this message]
1996-09-06  0:00     ` Jon S Anthony
1996-09-04  0:00   ` Jon S Anthony
1996-09-05  0:00     ` Robert A Duff
1996-09-05  0:00   ` Jon S Anthony
1996-09-05  0:00     ` Robert A Duff
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox