From: Maciej Sobczak <see.my.homepage@gmail.com>
Subject: Re: Inherited Methods and such
Date: Tue, 25 Sep 2007 13:53:51 -0700
Date: 2007-09-25T13:53:51-07:00 [thread overview]
Message-ID: <1190753631.240548.101820@19g2000hsx.googlegroups.com> (raw)
In-Reply-To: <1r9s9v6pcjifl.vp4ktk0unpd1.dlg@40tude.net>
On 24 Wrz, 21:20, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> > OK. Let's forbid to call virtual functions altogether until the full
> > object is ready. I'm fine with such restriction.
>
> No, because:
>
> 1. It introduces another type T w/o primitive operations;
Indeed.
> 2. This degenerate is anyway inviable, as you can call primitive operations
> from non-primitive ones.
>
> 3. There already exists a type that has the desired property of
> non-dispatching, it is T (specific).
2. and 3. are inconsistent.
> You are in an unresolvable contradiction by trying to mix class and its
> truncations. It is untyped, just because mixing types in untyped. Ada 95
> solved that by naming the truncation as T and the class of as T'Class. The
> rest was easy.
Yes. Like here:
-- p.ads:
with Ada.Finalization;
package P is
type T is new Ada.Finalization.Controlled with null record;
overriding procedure Initialize (X : in out T);
procedure Some_Operation (X : in T);
type R is range 10 .. 20;
type S is new T with record
I : R;
end record;
overriding procedure Initialize (X : in out S);
overriding procedure Some_Operation (X : in S);
end P;
-- p.adb:
with Ada.Text_IO;
use Ada.Text_IO;
package body P is
procedure Dispatch (X : in T'Class) is
begin
Put ("Calling Some_Operation with T'Class");
New_Line (2);
Some_Operation (X);
end Dispatch;
procedure Initialize (X : in out T) is
begin
Put ("P.Initialize for T");
New_Line;
Put ("-> doing some operation with the object");
New_Line (2);
Dispatch (X);
end Initialize;
procedure Some_Operation (X : in T) is
begin
Put ("P.Some_Operation for T");
New_Line (2);
end Some_Operation;
procedure Initialize (X : in out S) is
begin
Put ("P.Initialize for S, but first let's initialize T" &
" and then we will take care of our (S) components");
New_Line (2);
Initialize (T (X));
Put ("OK, finished with the supertype (T)");
New_Line;
Put ("-> let's initialize our own (S) components...");
New_Line;
X.I := 15;
Put ("-> components initialized and now I =" & R'Image (X.I));
New_Line (2);
end Initialize;
procedure Some_Operation (X : in S) is
begin
Put ("P.Some_Operation for S");
New_Line;
Put ("-> here we are SURE that all components are correct");
New_Line;
Put ("-> for example I =" & R'Image (X.I));
Put (" which is SURELY in the range " &
R'Image (R'First) & " .." & R'Image (R'Last));
New_Line;
Put ("-> otherwise it would be UNTYPED MESS");
New_Line (2);
end Some_Operation;
end P;
-- a.adb:
with P;
procedure A is
X : P.S;
begin
null;
end;
$ gnatmake a
gcc -c a.adb
gcc -c p.adb
gnatbind -x a.ali
gnatlink a.ali
$ ./a
P.Initialize for S, but first let's initialize T and then we will take
care of our (S) components
P.Initialize for T
-> doing some operation with the object
Calling Some_Operation with T'Class
P.Some_Operation for S
-> here we are SURE that all components are correct
-> for example I = 0 which is SURELY in the range 10 .. 20
-> otherwise it would be UNTYPED MESS
OK, finished with the supertype (T)
-> let's initialize our own (S) components...
-> components initialized and now I = 15
$
The above program prints 0 as the value of an object which type is
range 10 .. 20.
What's even more funny, I can add the following inside Some_Operation
for S:
declare
J : R := X.I; -- at this point X.I = 0
begin
Put (R'Image (J));
end;
Guess what will happen. No constraint_error and 0 is assigned to J.
Why? Because the poor compiler assumed that if X.I is of type R, then
no checks are necessary.
Wow.
> > Let's say I want to register my new object from T's constructor in
> > some map or somewhere. I don't want to hook to complete T'Class,
> > because I cannot force users deriving from my T to call be back so
> > that I can register. I want the registration process to be
> > encapsulated and invisible and I want to do it from T's constructor.
> > If you restrict the possibility to use T'Class inside the constructor,
> > you have to way to register T'Class reference/pointer from T's
> > constructor. Too bad.
>
> I don't understand your example - if you don't derive from T, its
> constructor will not be called. What do you want, to register objects of
> the type T or objects of the type T'Class? Answer this and you will know
> from where to do the registration of what.
I want to register T'Class, but I don't want to involve those who
derive from T.
> > Another part is dispatch into
> > vacuum.
>
> Not in Ada. You cannot dispatch in Initialize because its argument is
> specific.
See above example.
> >>> What about growing up?
>
> >> The attributes do.
>
> > No. Children and Adults have different interfaces. It's not even the
> > case-block-pretending-dispatch. There are different primitive
> > operations, some of them not even rooted in Human.
>
> You could say it simpler: Children and Adult are different types. Period.
They are both in Human'Class. You try to escape the problem instead of
solving it.
> >> My point is, a view is just a new object of a *new* type.
>
> > It does not have to be, but I find it acceptable except that I don't
> > think you need a *new* type for them.
>
> We need it to prevent infinite recursion. More generally, here the
> behavioral principle applies: if there is a difference between object and a
> reference to => that should be observable through the behaviors of => they
> have different behaviors => they have different types.
What if they don't have different behaviors?
There are two ways to achieve it:
1. Prevent anybody from interacting with the object directly, so there
is nothing to compare (Java).
2. Make references just names, which are syntax entities (C++, in some
contexts).
> > Control question: what is the identity of the view? :-)
>
> There is nothing special in identity. A view can have many identities:
>
> 1. The name of the view
> 2. The type of the view
> 3. The target if the type of is comparable
> 4. The tag of the view if it is polymorphic
> 5. The tag of the target if that is polymorphic
> ...
6. The identity of the target.
> >> Ada is consistent because Initialize is not a constructor. It washes its
> >> hands: if we don't know how to do it properly, we better don't.
>
> > Leaving the problem open? I don't call it consistent.
>
> Incomplete, but consistent. Absence of solution is better than a wrong one.
A wrong solution is exploited in the example above.
This is *really* *untyped* *mess* (tm).
Let's also not forget that Initialize is useless as a constructor (and
thus incomparable to C++) anyway due to the lack of parameters. But so-
called "constructor functions" will not solve this problem.
--
Maciej Sobczak
http://www.msobczak.com/
next prev parent reply other threads:[~2007-09-25 20:53 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-17 14:26 Inherited Methods and such shaunpatterson
2007-09-17 15:11 ` Ludovic Brenta
2007-09-17 16:46 ` shaunpatterson
2007-09-17 19:07 ` Ludovic Brenta
2007-09-17 20:22 ` Maciej Sobczak
2007-09-17 21:07 ` Ludovic Brenta
2007-09-18 14:27 ` Maciej Sobczak
2007-09-18 14:27 ` Maciej Sobczak
2007-09-18 15:25 ` Dmitry A. Kazakov
2007-09-18 18:34 ` Ludovic Brenta
2007-09-18 19:29 ` Dmitry A. Kazakov
2007-09-18 19:39 ` Ludovic Brenta
2007-09-18 20:49 ` Dmitry A. Kazakov
2007-09-18 21:10 ` Simon Wright
2007-09-18 20:39 ` Maciej Sobczak
2007-09-18 21:12 ` Dmitry A. Kazakov
2007-09-19 14:49 ` Maciej Sobczak
2007-09-19 15:16 ` Dmitry A. Kazakov
2007-09-19 22:13 ` Maciej Sobczak
2007-09-20 8:12 ` Dmitry A. Kazakov
2007-09-20 13:52 ` Maciej Sobczak
2007-09-20 16:22 ` Dmitry A. Kazakov
2007-09-20 20:45 ` Maciej Sobczak
2007-09-21 18:59 ` Dmitry A. Kazakov
2007-09-21 21:02 ` Maciej Sobczak
2007-09-22 8:48 ` Dmitry A. Kazakov
2007-09-22 21:53 ` Maciej Sobczak
2007-09-23 8:41 ` Dmitry A. Kazakov
2007-09-23 20:36 ` Maciej Sobczak
2007-09-24 9:32 ` Dmitry A. Kazakov
2007-09-24 15:02 ` Maciej Sobczak
2007-09-24 19:20 ` Dmitry A. Kazakov
2007-09-25 20:53 ` Maciej Sobczak [this message]
2007-09-26 10:42 ` Dmitry A. Kazakov
2007-09-26 21:31 ` Maciej Sobczak
2007-09-27 15:02 ` Dmitry A. Kazakov
2007-09-27 21:02 ` Maciej Sobczak
2007-09-26 12:21 ` Robert A Duff
2007-09-26 12:54 ` Dmitry A. Kazakov
2007-09-26 21:37 ` Maciej Sobczak
2007-09-26 23:47 ` Randy Brukardt
2007-09-27 21:08 ` Maciej Sobczak
2007-09-28 0:44 ` Randy Brukardt
2007-09-28 20:32 ` Maciej Sobczak
2007-09-28 22:35 ` Randy Brukardt
2007-09-29 23:58 ` Robert A Duff
2007-09-26 12:26 ` Robert A Duff
2007-09-26 21:50 ` Maciej Sobczak
2007-09-26 22:20 ` Ray Blaak
2007-09-27 0:01 ` Randy Brukardt
2007-09-27 13:39 ` Robert A Duff
2007-09-27 14:54 ` Dmitry A. Kazakov
2007-09-28 0:35 ` Randy Brukardt
[not found] ` <7p6gc1s9imfa$.kmvwf5zyf8e9.dlg@40tude.net>
2007-09-28 22:53 ` Randy Brukardt
2007-09-29 20:37 ` Dmitry A. Kazakov
2007-09-27 21:23 ` Maciej Sobczak
2007-09-28 19:12 ` Robert A Duff
2007-09-28 19:02 ` Robert A Duff
2007-09-28 19:42 ` Robert A Duff
2007-09-28 20:44 ` Maciej Sobczak
2007-09-28 22:40 ` Randy Brukardt
2007-09-29 20:35 ` Dmitry A. Kazakov
2007-09-29 20:52 ` Maciej Sobczak
2007-09-30 8:38 ` Dmitry A. Kazakov
2007-09-29 23:47 ` Robert A Duff
2007-09-29 20:48 ` Maciej Sobczak
2007-09-29 23:39 ` Robert A Duff
2007-09-30 8:38 ` Dmitry A. Kazakov
2007-09-29 23:42 ` Robert A Duff
2007-09-25 1:59 ` Randy Brukardt
2007-09-25 8:59 ` Dmitry A. Kazakov
2007-09-25 21:02 ` Randy Brukardt
2007-09-26 12:42 ` Dmitry A. Kazakov
2007-09-18 4:03 ` Steve
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox