comp.lang.ada
 help / color / mirror / Atom feed
* Object-Oriented style question
@ 2012-01-08 12:45 Georg Bauhaus
  2012-01-08 12:52 ` Simon Wright
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Georg Bauhaus @ 2012-01-08 12:45 UTC (permalink / raw)


Given a tagged O-O type T in package Pak and a "method" of T,
called "Info". Method Info queries the state of its parameter,
which is of type T. States are of a type named "Value", which
also happens to be defined in Pak.

    function Info (Item : in T) return Value;
           -- queries status of Item

The primitive operation Info may be inherited when deriving
another type from Pak.T. A program that calls Info in an O-O style
may want the call to be dispatched to the inherited operation.

A client working with the T hierarchy could look like this:

    procedure Get_Info (Item : Pak.T'Class) is
    begin
       Status := Item.Info;  -- dispatching call
    end Get_Info;

where

    Status : Pak.Value;

My question is about the best way to declare the Info operation,
and its parameter profile in particular.

(A follow-up question is whether introduction to O-O programming
in Ada should be careful when mentioning plain "access" parameters.)

There is a number of alternative possibilities of declaring query
functions:

package Pak is

    type Value is range 1000 .. 1003;

    type T is abstract tagged private;

    function Info (Item : in T) return Value;
    function Info_1 (Item_Doubly_Indirect : access T) return Value;
    function Info_2 (Item_Doubly_Indirect : access constant T) return Value;
    function Info_3 (Item_Doubly_Indirect : not null access constant T) return Value;

private
    type T is tagged record
       Data : Value := Value'First;
    end record;
end Pak;

When evaluating the alternative possibilities of declaring
a query function such as Info, Info_1, Info_2, and Info_3---and
ignoring the fact that in some cases there might be technical  or other
issues that narrow the choices---I am thinking that the operations
Info and Info_3 are almost the same, insofar as the argument is
*read-only* in both cases, and the argument must be an *existing*
object in both cases.

Info_2 is still close to the meaning of a query function except
that the parameter may be null. This then means that there is *no*
object of type T'Class and, consequently, there cannot be a state!
Programs that call Info_2 could then needlessly raise an exception.
(If "null" is somehow important in a set of objects from
the T hierarchy, this does not preclude testing for "null",
since the test can be performed at the place in the program
where both the null pointer and the test are needed (and a default
state value assigned).)

Info_1 does not even express, at the language level, that Info_1
is a query: the query function has *write* access to the state
information. Arguably, this can be an invitation to introduce
obscure errors.

The above definitions are not even informally equivalent, then,
and, in particular, Info and Info_1 are the least alike.

Still, some recent program fragments seem to indicate that programmers
approaching O-O programming in Ada use Info_1 (with "access") for query
functions, IMHO the least preferable choice in the subjective evaluation
hierarchy above.

My guess is that the choice is caused by transporting knowledge acquired
when using a language that is different from most O-O languages,  since
most O-O languages do *not* use *explicit* "access" for declaring
O-O "methods" (Ada, Eiffel, Java, C#, OCaml, ...). Not even for
dispatching calls.  They have O-O mechanics built into the language
and translation helps with keeping O-O mechanics correct, and efficient.

I have effectively two questions, then, one concerning didactic
style and one concerning cost and robustness of using Ada:

First question: Will it be preferable if those introducing O-O
in Ada use a (virtual) rubber eraser and clean up introductions
by removing unneeded (and in some cases dangerous) "access" from
declarations of O-O primitive operations?

Second question: Technically, will it be advisable to work on
"access-free" bindings to O-O libraries because the Ada language
makes O-O types be by-reference as is?  Or on facilitating these
with the help of a compiler matching by-reference  mechanics of
foreign languages?



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

* Re: Object-Oriented style question
  2012-01-08 12:45 Object-Oriented style question Georg Bauhaus
@ 2012-01-08 12:52 ` Simon Wright
  2012-01-08 13:25   ` Dmitry A. Kazakov
  2012-01-08 14:18 ` Robert A Duff
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Simon Wright @ 2012-01-08 12:52 UTC (permalink / raw)


I don't see why anyone would use anything other than your Info:

   function Info (Item : in T) return Value;

You may need to pass values of T'Class (or access T'Class) around, but
this shouldn't affect the primitive. And it seems to me it makes it much
simpler from a teaching point of view (but IANAT!)




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

* Re: Object-Oriented style question
  2012-01-08 12:52 ` Simon Wright
@ 2012-01-08 13:25   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 18+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-08 13:25 UTC (permalink / raw)


On Sun, 08 Jan 2012 12:52:46 +0000, Simon Wright wrote:

> I don't see why anyone would use anything other than your Info:
> 
>    function Info (Item : in T) return Value;
> 
> You may need to pass values of T'Class (or access T'Class) around, but
> this shouldn't affect the primitive. And it seems to me it makes it much
> simpler from a teaching point of view (but IANAT!)

In some rare cases Info need to be is contravariant ("final"), then:

   function Info (Item : in T'Class) return Value;

When T is supposed to use some reference counting scheme. Then due to lack
of either MI or interface inheritance in Ada, there must be an extra
interface type declared. E.g.

   type T_Interface is limited interface ...;
   function Info (Item : in T_Interface) return Value is abstract;

   type T_Implementation is ... and T_Interface;
   overriding -- This one does the job
      function Info (Item : in T_Implementation) return Value;

   type T_Handle is ... and T_Interface ...
   overriding -- This one delegates to the implementation
      function Info (Item : in T_Handle) return Value;

   function Info (Item : in T_Handle) return Value is
   begin
       return Item.Ptr.Info;
   end Info;

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



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

* Re: Object-Oriented style question
  2012-01-08 12:45 Object-Oriented style question Georg Bauhaus
  2012-01-08 12:52 ` Simon Wright
@ 2012-01-08 14:18 ` Robert A Duff
  2012-01-08 20:32   ` Martin Dowie
  2012-01-09 22:34   ` Adam Beneschan
  2012-01-09  8:55 ` Maciej Sobczak
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 18+ messages in thread
From: Robert A Duff @ 2012-01-08 14:18 UTC (permalink / raw)


Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> writes:

>    function Info (Item : in T) return Value;

This is the right way to do it.  Don't use access types when
you don't need to.  That goes double for anonymous access
types, and triple for cases involving run-time accessibility
checks, as the cases below do.

I can't think of any good reason to use access parameters
in Ada.  Note: "access parameter" does not mean "parameter of
an access type", it means "parameter of an ANONYMOUS access type".

The "in" is just noise; I suggest you leave it out.

>    function Info_1 (Item_Doubly_Indirect : access T) return Value;
>    function Info_2 (Item_Doubly_Indirect : access constant T) return Value;
>    function Info_3 (Item_Doubly_Indirect : not null access constant T) return Value;

All of the above exclude null.  That is, "not null" is implicit
for Info_1 and Info_2.  Calling any of these three with "null"
will raise Constraint_Error.  That's necessary, because they're
dispatching on a Tag, and if the actual is null, there is no tag.

So Info_2 and Info_3 have identical semantics.

- Bob



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

* Re: Object-Oriented style question
  2012-01-08 14:18 ` Robert A Duff
@ 2012-01-08 20:32   ` Martin Dowie
  2012-01-08 20:52     ` Robert A Duff
  2012-01-09 22:34   ` Adam Beneschan
  1 sibling, 1 reply; 18+ messages in thread
From: Martin Dowie @ 2012-01-08 20:32 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> wrote:
> Georg Bauhaus <rm-host.bauhaus@maps.futureapps.de> writes:
> 
>>    function Info (Item : in T) return Value;
> 
> This is the right way to do it.  Don't use access types when
> you don't need to.  That goes double for anonymous access
> types, and triple for cases involving run-time accessibility
> checks, as the cases below do.
> 
> I can't think of any good reason to use access parameters
> in Ada.  Note: "access parameter" does not mean "parameter of
> an access type", it means "parameter of an ANONYMOUS access type".
> 
> The "in" is just noise; I suggest you leave it out.
> 
>>    function Info_1 (Item_Doubly_Indirect : access T) return Value;
>>    function Info_2 (Item_Doubly_Indirect : access constant T) return Value;
>>    function Info_3 (Item_Doubly_Indirect : not null access constant T) return Value;
> 
> All of the above exclude null.  That is, "not null" is implicit
> for Info_1 and Info_2.  Calling any of these three with "null"
> will raise Constraint_Error.  That's necessary, because they're
> dispatching on a Tag, and if the actual is null, there is no tag.
> 
> So Info_2 and Info_3 have identical semantics.
> 
> - Bob

Presumably when you need to store a reference to an object, you'd then pass
in a 'aliased in out' and take an '(Unchecked_)Access? This is how I map a
UML association to Ada.

-- Martin

-- 
-- Sent from my iPad



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

* Re: Object-Oriented style question
  2012-01-08 20:32   ` Martin Dowie
@ 2012-01-08 20:52     ` Robert A Duff
  0 siblings, 0 replies; 18+ messages in thread
From: Robert A Duff @ 2012-01-08 20:52 UTC (permalink / raw)


Martin Dowie <martin@re.mo.ve.thedowies.com> writes:

> Presumably when you need to store a reference to an object, you'd then pass
> in a 'aliased in out' and take an '(Unchecked_)Access?

Sure.  Or use anonymous access, but then you get run-time
accessibility checks, which is (approximately) never what
you want.

But the need for a dispatching operation to store a reference
is fairly rare, in my experience.  If you don't need dispatching,
then you can use a named access type.

- Bob



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

* Re: Object-Oriented style question
  2012-01-08 12:45 Object-Oriented style question Georg Bauhaus
  2012-01-08 12:52 ` Simon Wright
  2012-01-08 14:18 ` Robert A Duff
@ 2012-01-09  8:55 ` Maciej Sobczak
  2012-01-09 23:58   ` Georg Bauhaus
  2012-02-08 12:23 ` Yannick Duchêne (Hibou57)
  2012-02-08 12:39 ` Yannick Duchêne (Hibou57)
  4 siblings, 1 reply; 18+ messages in thread
From: Maciej Sobczak @ 2012-01-09  8:55 UTC (permalink / raw)


On Jan 8, 1:45 pm, Georg Bauhaus <rm-host.bauh...@maps.futureapps.de>
wrote:

>     function Info (Item : in T) return Value;
>     function Info_1 (Item_Doubly_Indirect : access T) return Value;
>     function Info_2 (Item_Doubly_Indirect : access constant T) return Value;
>     function Info_3 (Item_Doubly_Indirect : not null access constant T) return Value;

> I am thinking that the operations
> Info and Info_3 are almost the same,

Almost. And considering the fact that T is tagged and is passed by
reference, you might argue that their meaning is the same.

But I think that in one particular case you might want to distinguish
between these profiles - access value is a "name" of the object, not
the object itself, and therefore can be used for more involved lookup.
Like in a dictionary, where access values are lightweight keys.
Then, the real meaning of Info_3 would be "tell me what you know about
the object whose name is this-or-that", using perhaps multiple
dictionaries (or should I say "caches"?) or complicating this idea in
any other way you like.

In short: access value is a "name" of the object and therefore Info
and Info_3 do not have to mean the same.

I agree, however, that in most cases your original Info is the most
obvious and easy to decipher. At the didactic level this is what
should be used for teaching OO.

--
Maciej Sobczak * http://www.inspirel.com



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

* Re: Object-Oriented style question
  2012-01-08 14:18 ` Robert A Duff
  2012-01-08 20:32   ` Martin Dowie
@ 2012-01-09 22:34   ` Adam Beneschan
  2012-01-09 23:21     ` Robert A Duff
  2012-01-10  8:34     ` Dmitry A. Kazakov
  1 sibling, 2 replies; 18+ messages in thread
From: Adam Beneschan @ 2012-01-09 22:34 UTC (permalink / raw)


On Jan 8, 6:18 am, Robert A Duff <bobd...@shell01.TheWorld.com> wrote:
> Georg Bauhaus <rm-host.bauh...@maps.futureapps.de> writes:
> >    function Info (Item : in T) return Value;
>
> This is the right way to do it.  Don't use access types when
> you don't need to.  That goes double for anonymous access
> types, and triple for cases involving run-time accessibility
> checks, as the cases below do.
>
> I can't think of any good reason to use access parameters
> in Ada.  Note: "access parameter" does not mean "parameter of
> an access type", it means "parameter of an ANONYMOUS access type".

I presume you mean "parameter of an anonymous access-to-object type"?
I think there are very good reasons for using anonymous access-
subprogram parameters.

                        -- Adam



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

* Re: Object-Oriented style question
  2012-01-09 22:34   ` Adam Beneschan
@ 2012-01-09 23:21     ` Robert A Duff
  2012-01-10  8:34     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 18+ messages in thread
From: Robert A Duff @ 2012-01-09 23:21 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

> I presume you mean "parameter of an anonymous access-to-object type"?
> I think there are very good reasons for using anonymous access-
> subprogram parameters.

Yes!

- Bob



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

* Re: Object-Oriented style question
  2012-01-09  8:55 ` Maciej Sobczak
@ 2012-01-09 23:58   ` Georg Bauhaus
  2012-01-10  8:47     ` Maciej Sobczak
  0 siblings, 1 reply; 18+ messages in thread
From: Georg Bauhaus @ 2012-01-09 23:58 UTC (permalink / raw)


On 1/9/12 9:55 AM, Maciej Sobczak wrote:

> But I think that in one particular case you might want to distinguish
> between these profiles - access value is a "name" of the object, not
> the object itself, and therefore can be used for more involved lookup.
> Like in a dictionary, where access values are lightweight keys.
> Then, the real meaning of Info_3 would be "tell me what you know about
> the object whose name is this-or-that", using perhaps multiple
> dictionaries (or should I say "caches"?) or complicating this idea in
> any other way you like.

Wouldn't the following lookup function handle the situation?

    function Lookup (Table  : Dictionaries.Map;
                     Object : T'Class) return Boolean is
    begin
       return Table.Contains (Object'Unchecked_Access);
    end Lookup;

Object denotes an object, then, so no nulls. Therefore, passing
the result of 'Unchecked_Access to function "Contains" should
be safe in the sense that Contains always gets a meaningful
access value to be used as a key.

The effect is that there still wouldn't be any parameters of an
anonymous access-to-object type at the level of T's definition.



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

* Re: Object-Oriented style question
  2012-01-09 22:34   ` Adam Beneschan
  2012-01-09 23:21     ` Robert A Duff
@ 2012-01-10  8:34     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 18+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-10  8:34 UTC (permalink / raw)


On Mon, 9 Jan 2012 14:34:17 -0800 (PST), Adam Beneschan wrote:

> I think there are very good reasons for using anonymous access-
> subprogram parameters.

No. In most cases access-to-subprogram parameter should have been a
subprogram parameter, if Ada only supported that.

If you meant rather that anonymous access to subprogram is better than
named one, that is also debatable. Anonymous access-to-subprogram is weakly
typed in the sense that it wrongly presumes that all subprograms of same
parameter profile are exchangeable = belong to compatible subtypes.

That is certainly not a strong typed approach. It is a hack necessary
*because* subprograms in Ada have no explicit types.

If they had:

   type procedure Differentiable (X : Float) return Float;
   type procedure Non_Differentiable (X : Float) return Float;

   Sine_Waveform : Differentiable; -- Sine is differentiable
   Square_Waveform : Non_Differentiable; -- Squares are non-differentiable

   procedure Differentiate (F : Differentiable);
      -- You cannot pass squares here

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



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

* Re: Object-Oriented style question
  2012-01-09 23:58   ` Georg Bauhaus
@ 2012-01-10  8:47     ` Maciej Sobczak
  2012-01-10 10:27       ` Dmitry A. Kazakov
                         ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Maciej Sobczak @ 2012-01-10  8:47 UTC (permalink / raw)


On Jan 10, 12:58 am, Georg Bauhaus <rm-
host.bauh...@maps.futureapps.de> wrote:

> Wouldn't the following lookup function handle the situation?
>
>     function Lookup (Table  : Dictionaries.Map;
>                      Object : T'Class) return Boolean is
>     begin
>        return Table.Contains (Object'Unchecked_Access);
>     end Lookup;

> Object denotes an object, then, so no nulls. Therefore, passing
> the result of 'Unchecked_Access to function "Contains" should
> be safe in the sense that Contains always gets a meaningful
> access value to be used as a key.

Yes, but this also brings an idea for some typing convention, which I
happen to use.
The idea is to somehow express the expectation that the operation has
with regard to the lifetime of the object and with regard to the
aliasing that can be involved. In the case of Info, where no access
value is used, the operation expects nothing, which means that it
should not leak the reference to the object (store it, etc.). That is,
after the operation completes, the object can be destroyed with no
consequences, as no alias was created.
In the case of Info_3 (or any other operation that accepts access
values), the operation can assume that the object lives longer and can
therefore leak (store, etc.) the reference and make new alias - it is
up to the user to figure out the complete lifetime management.

Of course, this convention is not checked statically (other than with
the usual rules for access types, which can be bypassed with
Unchecked_XXX anyway), but is a good hint for the user with regard to
object lifetime expectations.

For this reason I would explicitly use access values in the profile if
the operation stores the access value in a dictionary.
The user should know that there is some aliasing going on there.

> The effect is that there still wouldn't be any parameters of an
> anonymous access-to-object type at the level of T's definition.

Why this should be a goal?
I prefer if the profile describes what is going on. If sh*t is going
on, then it is better to show it in the profile than to hide it and
surprise the user later.

--
Maciej Sobczak * http://www.inspirel.com



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

* Re: Object-Oriented style question
  2012-01-10  8:47     ` Maciej Sobczak
@ 2012-01-10 10:27       ` Dmitry A. Kazakov
  2012-01-10 12:27       ` Georg Bauhaus
  2012-01-10 21:26       ` Randy Brukardt
  2 siblings, 0 replies; 18+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-10 10:27 UTC (permalink / raw)


On Tue, 10 Jan 2012 00:47:19 -0800 (PST), Maciej Sobczak wrote:

> On Jan 10, 12:58�am, Georg Bauhaus <rm-
> host.bauh...@maps.futureapps.de> wrote:
> 
>> The effect is that there still wouldn't be any parameters of an
>> anonymous access-to-object type at the level of T's definition.
> 
> Why this should be a goal?
> I prefer if the profile describes what is going on. If sh*t is going
> on, then it is better to show it in the profile than to hide it and
> surprise the user later.

I agree, if the referential semantics is a part of the contract, it must be
exposed, and hidden otherwise.

Furthermore, semantically

   procedure Foo (X : access T)

is not a method of T, it is one of access T. Objects of T and access T are
different objects of different types and different sets of operations
defined on them.

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



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

* Re: Object-Oriented style question
  2012-01-10  8:47     ` Maciej Sobczak
  2012-01-10 10:27       ` Dmitry A. Kazakov
@ 2012-01-10 12:27       ` Georg Bauhaus
  2012-01-11  8:54         ` Maciej Sobczak
  2012-01-10 21:26       ` Randy Brukardt
  2 siblings, 1 reply; 18+ messages in thread
From: Georg Bauhaus @ 2012-01-10 12:27 UTC (permalink / raw)


On 10.01.12 09:47, Maciej Sobczak wrote:

>> The effect is that there still wouldn't be any parameters of an
>> anonymous access-to-object type at the level of T's definition.
> 
> Why this should be a goal?

For two reasons.

First, just restating that, as already agreed, the definition of
O-O types T should normally be concerned with operations defined
for the type T more than with operations defined on access T,
adopting Dmitry's parlance, if I may, for the sake of the argument.

Second, a pointer as a key can be seen as an implementation detail
used as an abstraction. More on this below.

> I prefer if the profile describes what is going on. If sh*t is going
> on, then it is better to show it in the profile than to hide it and
> surprise the user later.

Absolutely.

I wonder, though, whether the convention (using pointers to hint
at lifetime and identity) could be turned into a different setup.
The resulting types may entail more work, but perhaps also more
flexibility. Suppose objects' lifetimes can be interrupted.
For example, objects that can be "serialized" to external storage.
They then seize to exist. Later, the program may load the objects
from external storage, bringing them to life again. Perhaps on
a different machine/node/partition. This might effectively mean
that addresses of objects have changed.

A client program wishes access to an object that it "thinks" must exist,
because it has worked on this object before, knowing its identity
(via its access value). If every such object has a unique ID, and
this ID is used in place of its 'Access, then requesting access
to the object may trigger loading the object from external storage,
using said unique ID. Is this possible with pointers?




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

* Re: Object-Oriented style question
  2012-01-10  8:47     ` Maciej Sobczak
  2012-01-10 10:27       ` Dmitry A. Kazakov
  2012-01-10 12:27       ` Georg Bauhaus
@ 2012-01-10 21:26       ` Randy Brukardt
  2 siblings, 0 replies; 18+ messages in thread
From: Randy Brukardt @ 2012-01-10 21:26 UTC (permalink / raw)


"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message 
news:36ee3b54-496c-41d4-a8ba-3357741adada@p4g2000vbt.googlegroups.com...
On Jan 10, 12:58 am, Georg Bauhaus <rm-
host.bauh...@maps.futureapps.de> wrote:

>> Wouldn't the following lookup function handle the situation?
>>
>> function Lookup (Table : Dictionaries.Map;
>> Object : T'Class) return Boolean is
>> begin
>> return Table.Contains (Object'Unchecked_Access);
>> end Lookup;

>> Object denotes an object, then, so no nulls. Therefore, passing
>> the result of 'Unchecked_Access to function "Contains" should
>> be safe in the sense that Contains always gets a meaningful
>> access value to be used as a key.

>Yes, but this also brings an idea for some typing convention, which I
>happen to use.
>The idea is to somehow express the expectation that the operation has
>with regard to the lifetime of the object and with regard to the
>aliasing that can be involved. In the case of Info, where no access
>value is used, the operation expects nothing, which means that it
>should not leak the reference to the object (store it, etc.). That is,
>after the operation completes, the object can be destroyed with no
>consequences, as no alias was created.
>In the case of Info_3 (or any other operation that accepts access
>values), the operation can assume that the object lives longer and can
>therefore leak (store, etc.) the reference and make new alias - it is
>up to the user to figure out the complete lifetime management.

I agree with your differentiation here, but I think it is usually a mistake 
to expose lifetime management to the user. That is, if it is reasonably 
possible, don't hamstring your clients by forcing *your* ideas of 
appropriate lifetime on them (which forces them to do memory management 
explicitly, which is error-prone).

For instance, Claw makes lots of internal pointers to objects. But we don't 
impose any requirements on the lifetime of the objects passed. How do we do 
this? All Claw objects are designed to unhook themselves from any Claw data 
structures that they were stored in when they are finalized. So the fact 
that Claw maintains these structures is invisible to the client, and if they 
want to use local variables or put Claw objects into a container, they can 
do that.

                                                 Randy.





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

* Re: Object-Oriented style question
  2012-01-10 12:27       ` Georg Bauhaus
@ 2012-01-11  8:54         ` Maciej Sobczak
  0 siblings, 0 replies; 18+ messages in thread
From: Maciej Sobczak @ 2012-01-11  8:54 UTC (permalink / raw)


On Jan 10, 1:27 pm, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:

> I wonder, though, whether the convention (using pointers to hint
> at lifetime and identity) could be turned into a different setup.
[...]

> The resulting types may entail more work, but perhaps also more
> flexibility. Suppose objects' lifetimes can be interrupted.
> For example, objects that can be "serialized" to external storage.
> They then seize to exist. Later, the program may load the objects
> from external storage, bringing them to life again. Perhaps on
> a different machine/node/partition. This might effectively mean
> that addresses of objects have changed.

This is essentially what object lifetime management in CORBA is
supposed to do. In principle, this is also a way to achieve
scalability by allowing objects (or rather their physical
representations) to materialize only when they are needed and be
"etherealized" otherwise. Transparent object migration is just one of
the possibilities here.

> Is this possible with pointers?

My experience with such approaches is that distribution cannot be made
fully transparent and attempts to do so result in severe problems[*]
(you cannot manage what you don't see). I can, however, imagine some
thick smart-pointer that provides this kind of functionality at least
at the design level.

[*] For more thoughts on why O-O and distribution don't work together
in the way that is typically expected, see:

http://www.inspirel.com/articles/RPC_vs_Messaging.html
http://www.inspirel.com/articles/What_Is_Wrong_With_IDL.html
http://www.inspirel.com/articles/Types_Of_Middleware.html

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com



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

* Re: Object-Oriented style question
  2012-01-08 12:45 Object-Oriented style question Georg Bauhaus
                   ` (2 preceding siblings ...)
  2012-01-09  8:55 ` Maciej Sobczak
@ 2012-02-08 12:23 ` Yannick Duchêne (Hibou57)
  2012-02-08 12:39 ` Yannick Duchêne (Hibou57)
  4 siblings, 0 replies; 18+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2012-02-08 12:23 UTC (permalink / raw)


Le Sun, 08 Jan 2012 13:45:00 +0100, Georg Bauhaus  
<rm-host.bauhaus@maps.futureapps.de> a écrit:

> Given a tagged O-O type T in package Pak and a "method" of T,
> called "Info". Method Info queries the state of its parameter,
> which is of type T. States are of a type named "Value", which
> also happens to be defined in Pak.
> […]
> My question is about the best way to declare the Info operation,
> and its parameter profile in particular.
> […]
>     type Value is range 1000 .. 1003;
>
>     type T is abstract tagged private;
>
>     function Info (Item : in T) return Value;
>     function Info_1 (Item_Doubly_Indirect : access T) return Value;
>     function Info_2 (Item_Doubly_Indirect : access constant T) return  
> Value;
>     function Info_3 (Item_Doubly_Indirect : not null access constant T)  
> return Value;
> […]
> Info_2 is still close to the meaning of a query function except
> that the parameter may be null. This then means that there is *no*
> object of type T'Class and, consequently, there cannot be a state!
> Programs that call Info_2 could then needlessly raise an exception.
> (If "null" is somehow important in a set of objects from
> the T hierarchy, this does not preclude testing for "null",
> since the test can be performed at the place in the program
> where both the null pointer and the test are needed (and a default
> state value assigned).)

Yes, but with the need to repeat the test at every call place. This would  
also mean possibly different interpretation at each call place. If  
multiple interpretation are intended, that's OK, otherwise, this would be  
error‑prone (and redundant with no added value).

On the other hand, giving Null a meaning in the sense of the meaning  
associated with an instance of a type, is a bad idea (ambiguous and lacks  
evidence from the reader's point of view), and a special state or value of  
the type is better.

For the above reasons, I would exclude both Info_1 and Info_2.

Now, as you noted Info_3 fall into the same as Info, leaving a single  
question: why use an access type ? As T is a private record type, if it  
needs access type for sharing, this could be encapsulated, and Info_3 may  
be dropped in favor of Info.

 From my point of view, the classical way to do with Info, is also the best  
of the above four.

-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University



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

* Re: Object-Oriented style question
  2012-01-08 12:45 Object-Oriented style question Georg Bauhaus
                   ` (3 preceding siblings ...)
  2012-02-08 12:23 ` Yannick Duchêne (Hibou57)
@ 2012-02-08 12:39 ` Yannick Duchêne (Hibou57)
  4 siblings, 0 replies; 18+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2012-02-08 12:39 UTC (permalink / raw)


Le Sun, 08 Jan 2012 13:45:00 +0100, Georg Bauhaus  
<rm-host.bauhaus@maps.futureapps.de> a écrit:

> First question: Will it be preferable if those introducing O-O
> in Ada use a (virtual) rubber eraser and clean up introductions
> by removing unneeded (and in some cases dangerous) "access" from
> declarations of O-O primitive operations?

If you talk about student, there will soon learn about unneeded access,  
and will want to go with it if their background suggest it.

> Second question: Technically, will it be advisable to work on
> "access-free" bindings to O-O libraries because the Ada language
> makes O-O types be by-reference as is?  Or on facilitating these
> with the help of a compiler matching by-reference  mechanics of
> foreign languages?

If by “compiler” you mean “Ada compiler” (or else what?), this would be an  
error I believe. Ada's interface to C was first defined to use access type  
where C did not. This was confusing and had to be fixed.

-- 
“Syntactic sugar causes cancer of the semi-colons.” [1]
“Structured Programming supports the law of the excluded muddle.” [1]
[1]: Epigrams on Programming — Alan J. — P. Yale University



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

end of thread, other threads:[~2012-02-08 12:39 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-08 12:45 Object-Oriented style question Georg Bauhaus
2012-01-08 12:52 ` Simon Wright
2012-01-08 13:25   ` Dmitry A. Kazakov
2012-01-08 14:18 ` Robert A Duff
2012-01-08 20:32   ` Martin Dowie
2012-01-08 20:52     ` Robert A Duff
2012-01-09 22:34   ` Adam Beneschan
2012-01-09 23:21     ` Robert A Duff
2012-01-10  8:34     ` Dmitry A. Kazakov
2012-01-09  8:55 ` Maciej Sobczak
2012-01-09 23:58   ` Georg Bauhaus
2012-01-10  8:47     ` Maciej Sobczak
2012-01-10 10:27       ` Dmitry A. Kazakov
2012-01-10 12:27       ` Georg Bauhaus
2012-01-11  8:54         ` Maciej Sobczak
2012-01-10 21:26       ` Randy Brukardt
2012-02-08 12:23 ` Yannick Duchêne (Hibou57)
2012-02-08 12:39 ` Yannick Duchêne (Hibou57)

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