* Re: smart pointer dangerous (no -> operator)
2009-01-16 11:09 ` Dmitry A. Kazakov
@ 2009-01-16 11:42 ` Georg Bauhaus
2009-01-16 12:43 ` Dmitry A. Kazakov
2009-01-16 21:21 ` Maciej Sobczak
2009-01-16 11:46 ` Oliver Kowalke
2009-01-17 0:43 ` Brian Drummond
2 siblings, 2 replies; 13+ messages in thread
From: Georg Bauhaus @ 2009-01-16 11:42 UTC (permalink / raw)
Dmitry A. Kazakov schrieb:
> On Fri, 16 Jan 2009 11:04:57 +0100, Oliver Kowalke wrote:
>
>> Ada doesn't support the dereference operator -> as C++.
>>
>> So Ada provides only two ways to access the managed object?
> Two major problems
> are:
>
> 1. Lack of delegation in order to automate generation of wrappers like Foo.
> 2. Lack of MI, because one base type is required and used further extension
> of the target type becomes practically impossible.
Frequently overlooked, I think, Ada has nested scopes, useful
in many ways here. (Except, perhaps, if reuse is only be
perceived to be possible with flat library level compiled
brick stone, and not by reusing source code and some
programming...)
1 - Ownership of objects can be strictly confined in scopes.
2 - Types can be declared where they are needed. See 1.
3 - Finalization is performed when a scope ends.
These may not directly address the original question,
but why design a program around C++ imported hindrances,
if you will?
with Ada.Finalization, Ada.Text_IO;
procedure Scoped_Pointer is
procedure Local is
-- architectural unit
type T is new Ada.Finalization.Controlled with
record
Data: Character;
end record;
overriding procedure Finalize(Object: in out T) is
begin
Ada.Text_IO.Put_Line("F!");
end Finalize;
procedure Next(Item: in out T) is
-- may raise
begin
Item.Data := Character'Val
(Natural'Succ(Character'Pos(Item.Data)));
end Next;
-- Pointer whose objects do not exist outside Local:
type T_Ptr is access T;
X: T_Ptr;
begin -- Local
X := new T'(Ada.Finalization.Controlled with Data => '*');
loop
Next(X.all); -- passed by reference; raises
end loop;
end Local;
begin
-- Local.T does not exist
Local;
-- Local.T does not exist, neither does Local.X.all,
-- as it has been finalized automatically.
end Scoped_Pointer;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: smart pointer dangerous (no -> operator)
2009-01-16 11:42 ` Georg Bauhaus
@ 2009-01-16 12:43 ` Dmitry A. Kazakov
2009-01-16 21:21 ` Maciej Sobczak
1 sibling, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2009-01-16 12:43 UTC (permalink / raw)
On Fri, 16 Jan 2009 12:42:17 +0100, Georg Bauhaus wrote:
> Dmitry A. Kazakov schrieb:
>> On Fri, 16 Jan 2009 11:04:57 +0100, Oliver Kowalke wrote:
>>
>>> Ada doesn't support the dereference operator -> as C++.
>>>
>>> So Ada provides only two ways to access the managed object?
>
>> Two major problems are:
>>
>> 1. Lack of delegation in order to automate generation of wrappers like Foo.
>> 2. Lack of MI, because one base type is required and used further extension
>> of the target type becomes practically impossible.
>
> Frequently overlooked, I think, Ada has nested scopes, useful
> in many ways here.
This is an unrelated issue. Referential semantics is not necessarily about
object life time management. Surely a better support provided by Ada for
stack allocated objects eliminates some cases of smart pointers typical in
C++. But the problem of referential objects exists independently on that.
Yes, if Ada had abstract access types, the positions 1 and 2 would be not
needed in this concrete case, because built-in access types in Ada already
"delegate" to the target, when operation "." is used. But Ada lacks
abstract access types either.
See last month's discussion: "Run-time accessibility checks (was:
Construction initialization problem)"
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: smart pointer dangerous (no -> operator)
2009-01-16 11:42 ` Georg Bauhaus
2009-01-16 12:43 ` Dmitry A. Kazakov
@ 2009-01-16 21:21 ` Maciej Sobczak
2009-01-17 19:07 ` Georg Bauhaus
1 sibling, 1 reply; 13+ messages in thread
From: Maciej Sobczak @ 2009-01-16 21:21 UTC (permalink / raw)
On 16 Sty, 12:42, Georg Bauhaus <rm.dash-bauh...@futureapps.de> wrote:
> Frequently overlooked, I think, Ada has nested scopes, useful
> in many ways here.
[...]
The problem is that in the majority of cases the whole point of
creating something dynamically (rather than on the stack) is to use it
in some other scope - outside of where it was created.
In your example the only motivation for allocating the object
dynamically would be to trade off stack space for heap space. Are
there any others?
--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
Database Access Library for Ada: www.inspirel.com/soci-ada
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: smart pointer dangerous (no -> operator)
2009-01-16 21:21 ` Maciej Sobczak
@ 2009-01-17 19:07 ` Georg Bauhaus
0 siblings, 0 replies; 13+ messages in thread
From: Georg Bauhaus @ 2009-01-17 19:07 UTC (permalink / raw)
Maciej Sobczak wrote:
> On 16 Sty, 12:42, Georg Bauhaus <rm.dash-bauh...@futureapps.de> wrote:
>
>> Frequently overlooked, I think, Ada has nested scopes, useful
>> in many ways here.
> [...]
>
> The problem is that in the majority of cases the whole point of
> creating something dynamically (rather than on the stack) is to use it
> in some other scope - outside of where it was created.
Yes, local objects do not always work, even if the location
is spanning vast areas of the program. While you can have scopes
nested in scopes nested in scopes next to a neighboring nested scope,
nicely making types and objects local or global as
desired, this is not always a (satisfactory) solution.
> In your example the only motivation for allocating the object
> dynamically would be to trade off stack space for heap space. Are
> there any others?
None that I can think of. But being able to confine objects to
scopes and at the same time control their lifetimes using scopes
can make some tricky pointer programming patterns unnecessary that
might otherwise be necessary, namely in case you use an allocator
of a library level pointer type. (GNAT makes us prefer allocators
for larger objects because of an implementation choice, AFAIK...)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: smart pointer dangerous (no -> operator)
2009-01-16 11:09 ` Dmitry A. Kazakov
2009-01-16 11:42 ` Georg Bauhaus
@ 2009-01-16 11:46 ` Oliver Kowalke
2009-01-16 12:45 ` Dmitry A. Kazakov
2009-01-17 0:43 ` Brian Drummond
2 siblings, 1 reply; 13+ messages in thread
From: Oliver Kowalke @ 2009-01-16 11:46 UTC (permalink / raw)
Dmitry A. Kazakov wrote:
> On Fri, 16 Jan 2009 11:04:57 +0100, Oliver Kowalke wrote:
>> Ada doesn't support the dereference operator -> as C++.
> It is difficult, since there is no any delegation support in Ada.
What are the reasons not to introduce it into Ada2005?
> P.S. My implementation of proxy object can be found here
> http://www.dmitry-kazakov.de/ada/components.htm#Objects_etc
Thanks! I'll take a look into your library
regards,
Oliver
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: smart pointer dangerous (no -> operator)
2009-01-16 11:09 ` Dmitry A. Kazakov
2009-01-16 11:42 ` Georg Bauhaus
2009-01-16 11:46 ` Oliver Kowalke
@ 2009-01-17 0:43 ` Brian Drummond
2009-01-17 9:28 ` Dmitry A. Kazakov
2 siblings, 1 reply; 13+ messages in thread
From: Brian Drummond @ 2009-01-17 0:43 UTC (permalink / raw)
On Fri, 16 Jan 2009 12:09:16 +0100, "Dmitry A. Kazakov"
<mailbox@dmitry-kazakov.de> wrote:
>1. In Ada 95 I declare the proxy type tagged controlled. The handle is
>created through a instantiation in the private part of the generic package
>Handle:
>
> type X_Handle is new Ada.Finalization.Controlled with private;
> -- Repeat all operations of the target
> procedure Foo (Object : X_Handle);
> ... -- and so on
>private
> package Handles is not Object.Handle (...); -- Instantiation
> type X_Handle is new Handles.Handle with null record;
>
>The implementation of Foo goes as follows:
>
> procedure Foo (Object : X_Handle) is
> begin
> Foo (Ptr (Object).all);
> end Foo;
>
>this is extremely tedious, but the best way I know.
As an Ada newbie, I've probably lost track of something important, but
I can't see a reason not to create a generic procedure, and simply
instantiate it for each Foo, which would be slightly less boring if it
worked..
I suspect it can't be that simple, but I can't see why. You don't know
the type of Ptr (Object).all but can't it be private from the generic's
point of view, or is that where a generic falls apart? Whatever the
type, there must be a Foo() for it, or the above wouldn't compile.
-Brian
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: smart pointer dangerous (no -> operator)
2009-01-17 0:43 ` Brian Drummond
@ 2009-01-17 9:28 ` Dmitry A. Kazakov
0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2009-01-17 9:28 UTC (permalink / raw)
On Sat, 17 Jan 2009 00:43:17 +0000, Brian Drummond wrote:
> On Fri, 16 Jan 2009 12:09:16 +0100, "Dmitry A. Kazakov"
> <mailbox@dmitry-kazakov.de> wrote:
>
>>1. In Ada 95 I declare the proxy type tagged controlled. The handle is
>>created through a instantiation in the private part of the generic package
>>Handle:
>>
>> type X_Handle is new Ada.Finalization.Controlled with private;
>> -- Repeat all operations of the target
>> procedure Foo (Object : X_Handle);
>> ... -- and so on
>>private
>> package Handles is not Object.Handle (...); -- Instantiation
>> type X_Handle is new Handles.Handle with null record;
>>
>>The implementation of Foo goes as follows:
>>
>> procedure Foo (Object : X_Handle) is
>> begin
>> Foo (Ptr (Object).all);
>> end Foo;
>>
>>this is extremely tedious, but the best way I know.
>
> As an Ada newbie, I've probably lost track of something important, but
> I can't see a reason not to create a generic procedure, and simply
> instantiate it for each Foo, which would be slightly less boring if it
> worked..
I am not sure what you mean. To have a generic subprogram in addition to
each primitive operation of the target type? That would be even more
boring.
The problem is:
You have a target type:
type T is ...;
procedure Foo (X : T);
function Bar return T;
procedure Baz (X : T; Y : in out T; Z : Float);
...
Now you want to create a type T_Handle which would in its implementation
Ada.Finalization.Controlled with a pointer to an instance of T and all
operations of T delegated to the pointer's target:
type T_Handle is Ada.Finalization.Controlled with private;
procedure Foo (X : T_Handle);
function Bar return T_Handle;
procedure Baz (X : T_Handle; Y : in out T_Handle; Z : Float);
...
Generics do not solve that. What does is delegation + interface inheritance
from concrete type (T). Ada has neither.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 13+ messages in thread