comp.lang.ada
 help / color / mirror / Atom feed
* Why does `Unchecked_Deallocation` need the access type?
@ 2015-07-26  7:11 EGarrulo
  2015-07-26  8:54 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: EGarrulo @ 2015-07-26  7:11 UTC (permalink / raw)


The `Free` procedure to deallocate an object is declared like this:


procedure Free is
    new Ada.Unchecked_Deallocation(Object_Type, Object_Access_Type);


Yet the access parameter seems redundant.  Why is it necessary to specify it?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-26  7:11 Why does `Unchecked_Deallocation` need the access type? EGarrulo
@ 2015-07-26  8:54 ` Dmitry A. Kazakov
  2015-07-26 11:16   ` Niklas Holsti
  2015-07-27 20:20   ` Randy Brukardt
  0 siblings, 2 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-26  8:54 UTC (permalink / raw)


On Sun, 26 Jul 2015 00:11:22 -0700 (PDT), EGarrulo wrote:

> The `Free` procedure to deallocate an object is declared like this:
> 
> procedure Free is
>     new Ada.Unchecked_Deallocation(Object_Type, Object_Access_Type);
> 
> Yet the access parameter seems redundant.  Why is it necessary to specify it?

Because the instance of the generic procedure Free has the argument of the
access type:

   procedure Free (Pointer : in out Object_Access_Type);

BTW, in Ada you can have as many access types as you wish. With operations
(like Free) of their own. It is sometimes very useful:

   type Aphabetic_Ptr is access all String;
   function "=" (Left, Right : Aphabetic_Ptr) return Boolean;
   function "<" (Left, Right : Aphabetic_Ptr) return Boolean;

   type Lexicographical_Ptr is access all String;
   function "=" (Left, Right : Lexicographical_Ptr) return Boolean;
   function "<" (Left, Right : Lexicographical_Ptr) return Boolean;

Then you create two indices of the same set of strings using different sort
ordering.

What is indeed redundant here is the Object_Type. It is necessary because
Ada does not have access type introspection. That is, you cannot get the
object type from an access type, though the compiler knows it anyway.
Surely there should have been an attribute to get that type, e.g.

   Pointer_Type'Target

But there is none.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-26  8:54 ` Dmitry A. Kazakov
@ 2015-07-26 11:16   ` Niklas Holsti
  2015-07-27 22:38     ` Jeremiah
  2015-07-27 20:20   ` Randy Brukardt
  1 sibling, 1 reply; 10+ messages in thread
From: Niklas Holsti @ 2015-07-26 11:16 UTC (permalink / raw)


On 15-07-26 11:54 , Dmitry A. Kazakov wrote:
> On Sun, 26 Jul 2015 00:11:22 -0700 (PDT), EGarrulo wrote:
>
>> The `Free` procedure to deallocate an object is declared like this:
>>
>> procedure Free is
>>      new Ada.Unchecked_Deallocation(Object_Type, Object_Access_Type);
>>
>> Yet the access parameter seems redundant.  Why is it necessary to specify it?
>
> Because the instance of the generic procedure Free has the argument of the
> access type:
>
>     procedure Free (Pointer : in out Object_Access_Type);

    [snip]

> What is indeed redundant here is the Object_Type. It is necessary because
> Ada does not have access type introspection. That is, you cannot get the
> object type from an access type, though the compiler knows it anyway.
> Surely there should have been an attribute to get that type, e.g.
>
>     Pointer_Type'Target
>
> But there is none.

Another reason, perhaps a trivial one, for including Object_Type is that 
the only syntax to define a formal access type in a generic declaration 
uses an access_type_definition, which requires a name for the object 
type. The declaration of Unchecked_Deallocation (RM 12.5.4) has this form:

    generic
       type Object(<>) is limited private;
       type Name   is access  Object;
    procedure Ada.Unchecked_Deallocation(X : in out Name)
    ...

Ada could perhaps have allowed a formal_access_type_definition with an 
unnamed target type, perhaps of the form

    type Name is access;   -- Not Ada!

or

    type Name is access <>;   -- Not Ada!

and then the Object formal type could have been omitted from 
Unchecked_Deallocation. However, it seems to me that such formal access 
types would not be very useful without the 'Target attribute that Dmitry 
suggested.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-26  8:54 ` Dmitry A. Kazakov
  2015-07-26 11:16   ` Niklas Holsti
@ 2015-07-27 20:20   ` Randy Brukardt
  2015-07-28  7:40     ` Dmitry A. Kazakov
  1 sibling, 1 reply; 10+ messages in thread
From: Randy Brukardt @ 2015-07-27 20:20 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:5d6faxxdsssv.15g7kj5hv86mk$.dlg@40tude.net...
> On Sun, 26 Jul 2015 00:11:22 -0700 (PDT), EGarrulo wrote:
...
> What is indeed redundant here is the Object_Type. It is necessary because
> Ada does not have access type introspection. That is, you cannot get the
> object type from an access type, though the compiler knows it anyway.
> Surely there should have been an attribute to get that type, e.g.
>
>   Pointer_Type'Target
>
> But there is none.

(1) The term is "designated type", so the attribute would be 
Pointer_Type'Designated.

(2) Ada 83 did not have any type-valued attributes; it was considered a 
problem. ('Base was not an attribute in Ada 83; it could only be used as the 
prefix of another attribute.) Ada 95 changed that (for 'Base and 'Class), 
but there wasn't any consideration (that I know of) whether there would be 
any others that could make sense.

(3) We recently had a proposal for 'Subtype that applies to an object. That 
would seem to be a similar sort of attribute, but it rapidly turned into a 
can of worms and it just didn't seem important enough to spend the time 
picking each worm out individually. (Kinda like what one does with old 
cheese... ;-) It's not clear to me whether 'Designated would have similar 
problems or whether it would work adequately (objects are complicated by 
anonymous subtypes and the fact that the prefix can include dynamic parts 
(i.e. function calls)). It might make sense to make a proposal to 
Ada-Comment. But in a lot of ways, it really needed to have been done for 
Ada 83, and for that we're 30+ years too late.

                                        Randy.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-26 11:16   ` Niklas Holsti
@ 2015-07-27 22:38     ` Jeremiah
  0 siblings, 0 replies; 10+ messages in thread
From: Jeremiah @ 2015-07-27 22:38 UTC (permalink / raw)


On Sunday, July 26, 2015 at 7:16:51 AM UTC-4, Niklas Holsti wrote:
> Ada could perhaps have allowed a formal_access_type_definition with an 
> unnamed target type, perhaps of the form
> 
>     type Name is access;   -- Not Ada!
> 
> or
> 
>     type Name is access <>;   -- Not Ada!
> 
> and then the Object formal type could have been omitted from 
> Unchecked_Deallocation. However, it seems to me that such formal access 
> types would not be very useful without the 'Target attribute that Dmitry 
> suggested.

I think the only place where this has really bit me and I really felt I needed it was when I was making a generic package for incomplete types and I wanted to hide the deletion of access types from the client.  But since they were incomplete types, you could not use Unchecked_Deallocation within the generic.  It had to be created by the client (wrapped in another procedure) and passed in as a generic parameter, which felt like it defeated the purpose of me trying to hide those details.

There might be other situations where it would be useful, but that is the one I ran into.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-27 20:20   ` Randy Brukardt
@ 2015-07-28  7:40     ` Dmitry A. Kazakov
  2015-07-28 21:25       ` Randy Brukardt
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-28  7:40 UTC (permalink / raw)


On Mon, 27 Jul 2015 15:20:37 -0500, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:5d6faxxdsssv.15g7kj5hv86mk$.dlg@40tude.net...
>> On Sun, 26 Jul 2015 00:11:22 -0700 (PDT), EGarrulo wrote:
> ...
>> What is indeed redundant here is the Object_Type. It is necessary because
>> Ada does not have access type introspection. That is, you cannot get the
>> object type from an access type, though the compiler knows it anyway.
>> Surely there should have been an attribute to get that type, e.g.
>>
>>   Pointer_Type'Target
>>
>> But there is none.
> 
> (1) The term is "designated type", so the attribute would be 
> Pointer_Type'Designated.
> 
> (2) Ada 83 did not have any type-valued attributes; it was considered a 
> problem. ('Base was not an attribute in Ada 83; it could only be used as the 
> prefix of another attribute.) Ada 95 changed that (for 'Base and 'Class), 
> but there wasn't any consideration (that I know of) whether there would be 
> any others that could make sense.

From the top of my head:

1. Arrays

type A is array (Positive range <>) of T;

A'Index = Positive
A'Element = T

2. Records

type R is record
   I : Integer;
   F : Float;
end R;

R'Index = type ... is (I, F) -- Enumeration of members
R'Member (R'Index'Val (0)) = Integer
R'Aggregator =
    type ... is access function (I : Integer; F : Float) return R

3. Tagged hierarchies

type S is new T with private;

S'Parent (T'Class) = T (in a public context)

The argument indicates the hierarchy where to search for the ancestor (due
to MI).

4. Subroutines

function Foo (I : Integer; F : Float) return T;

Foo'Index = type ... is (I, F)
Foo'Argument (Foo'Index'Val (0)) = Integer
Foo'Result = T

5. Discriminants

type T (I : Integer; B : Boolean) is ...;

T'Discriminant_Index = type ... is (I, B);
T'Discriminant (T'Discriminant_Index'Val (0)) = Integer
T'Constraints =  type ... (I : Integer; B : Boolean) is null record;

6. Generics

Actuals of generics. The visibility of is a real mess now. E.g. presently I
must "rename" actuals of generics like this:

   generic
      type T is ...;
   package Bar is
      subtype My_T is T;

to be able to access T in some generic contexts.

+ Some comparison of anonymous types

A'Index'Subtype_Conformant (B'Index) -- yields Boolean
A'Index'Type_Conformant (Integer)

--------------------------
The use cases are clear. Generics, universal stream I/O, persistency
layers, constructing/destructing will hugely profit from introspection. #3
is essential for robust code, when calling parent operations, e.g. in
Finalize.

> (3) We recently had a proposal for 'Subtype that applies to an object.

That is different I suppose, because it involves subtypes and because it
acts on an object, things which are not so static as plain types. Allowing
the attributes above for objects will possibly have similar problems. But
they are worth each attempt to resolve, IMO.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-28  7:40     ` Dmitry A. Kazakov
@ 2015-07-28 21:25       ` Randy Brukardt
  2015-07-29  6:28         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Randy Brukardt @ 2015-07-28 21:25 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:170ajsv4tazu3.mgrs0or8en9w$.dlg@40tude.net...
> 3. Tagged hierarchies
>
> type S is new T with private;
>
> S'Parent (T'Class) = T (in a public context)
>
> The argument indicates the hierarchy where to search for the ancestor (due
> to MI).

We tried such an attribute sometime during the Ada 2005 work and eventually 
gave up. The problem being that the parent (in a language sense - it's the 
subtype after "new") depends on the visibility on the type, and that is very 
unconfortable (besides causing problems):

  package P is
      type S is new T with private;
      procedure Bar (Obj : in out S'Parent); -- S'Parent is T here.
  private
      type S in new U with private; -- U is descended from T, of course.
  end P;

  package body P is
      procedure Bar (Obj : in out S'Parent) is -- !! - S'Parent is U here.
      ...
  end P;

The body of Bar does not conform with the specification as S'Parent means 
something different in the two locations. That potentially includes having 
different operations available (Imagine if U has a function Foo that T does 
not have.), so there is a potential for a real problem.

Eventually we added a function Parent_Tag in Ada.Tags; since it's runtime it 
ignores privacy and thus it has a unique value.

I think you are using "Parent" in your write-up as what Ada calls a direct 
ancestor - that includes the parent (if any) and any progenitors. That's a 
different problem -- at least hiding interfaces isn't allowed so the 
visibility problem doesn't come up for progentitors. (Of course, if we ever 
did full MI, it would come back with a vengance.)

                                                Randy.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-28 21:25       ` Randy Brukardt
@ 2015-07-29  6:28         ` Dmitry A. Kazakov
  2015-07-29 20:47           ` Randy Brukardt
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-29  6:28 UTC (permalink / raw)


On Tue, 28 Jul 2015 16:25:19 -0500, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:170ajsv4tazu3.mgrs0or8en9w$.dlg@40tude.net...
>> 3. Tagged hierarchies
>>
>> type S is new T with private;
>>
>> S'Parent (T'Class) = T (in a public context)
>>
>> The argument indicates the hierarchy where to search for the ancestor (due
>> to MI).
> 
> We tried such an attribute sometime during the Ada 2005 work and eventually 
> gave up. The problem being that the parent (in a language sense - it's the 
> subtype after "new") depends on the visibility on the type, and that is very 
> unconfortable (besides causing problems):
> 
>   package P is
>       type S is new T with private;
>       procedure Bar (Obj : in out S'Parent); -- S'Parent is T here.
>   private
>       type S in new U with private; -- U is descended from T, of course.
>   end P;
> 
>   package body P is
>       procedure Bar (Obj : in out S'Parent) is -- !! - S'Parent is U here.

I see. Perhaps:

   procedure Bar (Obj : in out S'Public_Parent) is
      -- S'Parent is U here
      -- S'Public_Parent is still T

------------------------
Of course nobody should ever declare non-primitive operations defined on
the parent type. And doing that in the public scope is almost a criminal
offense.

If we designed Ada from a fresh start I would try to eliminate all
non-primitive operations. Any operations would be either primitive or
class-wide. And a class-wide operation would be still primitive of T'Class
and thus dispatch on T'Class'Class etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-29  6:28         ` Dmitry A. Kazakov
@ 2015-07-29 20:47           ` Randy Brukardt
  2015-07-30  6:19             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Randy Brukardt @ 2015-07-29 20:47 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:mu2l292s5nlq$.1ag4nqmfs3kyl$.dlg@40tude.net...
...
> Of course nobody should ever declare non-primitive operations defined on
> the parent type. And doing that in the public scope is almost a criminal
> offense.

I agree this is not a realistic example. But it's possible, and it's the 
sort of problem (known as a "Bairdian problem" within the ARG, in honor of 
Steve Baird, who has an uncanny ability to come up with these weird examples 
that kill otherwise appealing ideas) that causes no end of trouble when 
defining new features for Ada, as they have to be addressed somehow.

It would be more realistic in a public child package, but even there your 
point would hold.

                         Randy.

P.S. 'Public_Parent probably would have worked. Not sure why we didn't go 
that way, maybe it didn't work for delegation. And both attributes are 
annoying when there is no parent, as in:

    type P is tagged private;

as they have to be illegal in that case, causing generic contract problems. 
All solvable, but continually getting messier.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Why does `Unchecked_Deallocation` need the access type?
  2015-07-29 20:47           ` Randy Brukardt
@ 2015-07-30  6:19             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2015-07-30  6:19 UTC (permalink / raw)


On Wed, 29 Jul 2015 15:47:15 -0500, Randy Brukardt wrote:

> And both attributes are 
> annoying when there is no parent, as in:
> 
>     type P is tagged private;
> 
> as they have to be illegal in that case, causing generic contract problems.

To me it is simply no P'Parent, just as the contract says. Tagged or not
 
   type P is private;

it does not make difference.

A generic contract that requires a parent is only

   type P is new Q with private;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-07-30  6:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-26  7:11 Why does `Unchecked_Deallocation` need the access type? EGarrulo
2015-07-26  8:54 ` Dmitry A. Kazakov
2015-07-26 11:16   ` Niklas Holsti
2015-07-27 22:38     ` Jeremiah
2015-07-27 20:20   ` Randy Brukardt
2015-07-28  7:40     ` Dmitry A. Kazakov
2015-07-28 21:25       ` Randy Brukardt
2015-07-29  6:28         ` Dmitry A. Kazakov
2015-07-29 20:47           ` Randy Brukardt
2015-07-30  6:19             ` Dmitry A. Kazakov

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