comp.lang.ada
 help / color / mirror / Atom feed
* on Ada abtract data type vs. OOP.
@ 2022-09-09  9:32 Nasser M. Abbasi
  2022-09-09 10:49 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Nasser M. Abbasi @ 2022-09-09  9:32 UTC (permalink / raw)


Lets say one does not want to do inheritance. (I think it causes
more problems than it solves actually).

The only difference I see between Ada's ADT and OOP, is that
in Ada, the data itself is separated from the package and must
be passed to the package methods at each call. The data lives
in the client side.

While in OOP, the data lives inside the object. (these are called
data memebers).

Let look at this simple example from

https://learn.adacore.com/courses/intro-to-ada/chapters/privacy.html

--------------------------
package Stacks is
    type Stack is private;

    procedure Push (S   : in out Stack;
                    Val :        Integer);
    procedure Pop (S   : in out Stack;
                   Val :    out Integer);
private

    subtype Stack_Index is Natural range 1 .. 10;
    type Content_Type is array (Stack_Index)
      of Natural;

    type Stack is record
       Top     : Stack_Index;
       Content : Content_Type;
    end record;
end Stacks;

---------------------------

To use it, The user does

-------------------------
--  Example of use
with Stacks; use Stacks;

procedure Test_Stack is
    S : Stack;
    Res : Integer;
begin
    Push (S, 5);
    Push (S, 7);
    Pop (S, Res);
end Test_Stack;
---------------------


In OOP, the stack itself, would live inside the "module" which will
be the class/object in that case.

So the above use example will becomes something like this


   o:=Object();  -- this calls the constructor
   o.Push(5); -- data now is stored inside "o"
   o.Push(7)
   res := O.Pop();

So the main difference I see, is that in Ada ADT, the data (the stack
in this example) lives on the client side, and the package
just has the methods.

For me, this actually better than OOP. Having methods separated
from data is a good thing.

Is there is something I am overlooking other than this? Again,
assuming one does not want to do inheritance? For
polymorphism one can use generic packages if needed.

It seems to me that Ada ADT provides all the benefits of OOP and more,
as it does not mix data and methods inside one container.

What do other think about this subject? Do you think it is
better to do it as OOP, to have the data inside the object,
or like with ADT, where the data instances are on the client side?

--Nasser

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09  9:32 on Ada abtract data type vs. OOP Nasser M. Abbasi
@ 2022-09-09 10:49 ` Dmitry A. Kazakov
  2022-09-09 14:37   ` antispam
  2022-09-09 15:30   ` Dmitry A. Kazakov
  2022-09-09 14:04 ` Jeffrey R.Carter
  2022-09-09 15:06 ` antispam
  2 siblings, 2 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2022-09-09 10:49 UTC (permalink / raw)


On 2022-09-09 11:32, Nasser M. Abbasi wrote:
> Lets say one does not want to do inheritance. (I think it causes
> more problems than it solves actually).

You cannot in Ada where one can always inherit from any type in some way 
or another:

- tagged extension: type S is new T with ...;
- subtype constraining: subtype S is T;
- cloing: type S is new T;

> The only difference I see between Ada's ADT and OOP, is that
> in Ada, the data itself is separated from the package and must
> be passed to the package methods at each call. The data lives
> in the client side.

This applies to all types and has nothing to do with ADT or OO. A state 
can be either localized in an object (good design) or kept outside it in 
global variables (bad design).

> While in OOP, the data lives inside the object. (these are called
> data memebers).

Just like in any type, not even abstract one. E.g.

    type X is range 1..100;

The "data" live in each instance of X.

> Let look at this simple example from

[...] Stack example

> In OOP, the stack itself, would live inside the "module" which will
> be the class/object in that case.

No, OOP example of stack is exactly the one you cited. There is a type 
Stack and operations of. A non-OO/ADT stack would be:

generic -- No parameters!!
package Generic_Integer_Stack is
    procedure Push (Val : Integer);
    procedure Pop (Val : out Integer);

You get a stack instance this way:

    package Integer_Stack is new Generic_Integer_Stack;

> So the main difference I see, is that in Ada ADT, the data (the stack
> in this example) lives on the client side, and the package
> just has the methods.

The sentence does not make sense to me. OO is ADT. I am not sure which 
issue you have problem with:

- No local states
- Stateful vs stateless
- Interface vs implementation inheritance

> For me, this actually better than OOP. Having methods separated
> from data is a good thing.

You presented a perfectly OO design of a stack type. A better one would be:

package Integer_Stacks is
    type Stack is tagged limited private;
    procedure Push (S : in out Stack; Val : Integer);
    procedure Pop (S : in out Stack; Val : out Integer);

Here:

- limited because we do not want copy or compare stacks
- tagged because we might want to reuse the type implementation.

For example:

with Integer_Stacks;  use Integer_Stack;

package Integer_Signaled_Stacks is
    type Signaled_Stack is new Stack with private;
    procedure Wait_For_Not_Empty
             (Stack : in out Signaled_Stack; Timeout : Duration);
private
    overriding
       procedure Push (S : in out Stack; Val : Integer);
    overriding
       procedure Pop (S : in out Stack; Val : out Integer);

Here the stack maintains a lock to make it task safe and provides event 
to wait for non-empty stack.

> Is there is something I am overlooking other than this? Again,
> assuming one does not want to do inheritance?

You cannot. Unless you use an extremely primitive language like C some 
form of inheritance is always there.

> It seems to me that Ada ADT provides all the benefits of OOP and more,
> as it does not mix data and methods inside one container.

Can you explain what do you mean under mixing data with methods? Ada is 
very limited in terms of using subprograms as data. Basically you need 
to resort to pointers or generic formals. You certainly meant something 
else.

> What do other think about this subject?

- Ada type system needs an overhaul.
- People confuse OOP with OOA&D. OOP is merely a better ADT.
- Ada 83 was object-based and its ADT was quite weak.
- Ada 95 fixed that, but stopped at single inheritance and dispatch and 
C++-esque idea of having types (AKA classes) and not so much types (AKA 
everything else we do not know how to deal right).
- Ada 2005 added castrated Java-esque multiple dispatch

Nothing happened to the type system since.

> Do you think it is
> better to do it as OOP, to have the data inside the object,
> or like with ADT, where the data instances are on the client side?

It is always preferable not to have global variables.

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

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09  9:32 on Ada abtract data type vs. OOP Nasser M. Abbasi
  2022-09-09 10:49 ` Dmitry A. Kazakov
@ 2022-09-09 14:04 ` Jeffrey R.Carter
  2022-09-09 15:06 ` antispam
  2 siblings, 0 replies; 8+ messages in thread
From: Jeffrey R.Carter @ 2022-09-09 14:04 UTC (permalink / raw)


On 2022-09-09 11:32, Nasser M. Abbasi wrote:
> 
> The only difference I see between Ada's ADT and OOP, is that
> in Ada, the data itself is separated from the package and must
> be passed to the package methods at each call. The data lives
> in the client side.
> 
> While in OOP, the data lives inside the object. (these are called
> data memebers).

You seem to be confused about where data "live". Whether you use programming by 
composition or by extension, the data live in the object of the type that the 
client declares.

-- 
Jeff Carter
"You tiny-brained wipers of other people's bottoms!"
Monty Python & the Holy Grail
18

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09 10:49 ` Dmitry A. Kazakov
@ 2022-09-09 14:37   ` antispam
  2022-09-09 15:21     ` Dmitry A. Kazakov
  2022-09-09 15:30   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 8+ messages in thread
From: antispam @ 2022-09-09 14:37 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> On 2022-09-09 11:32, Nasser M. Abbasi wrote:
> 
> - tagged extension: type S is new T with ...;
> - subtype constraining: subtype S is T;
> - cloing: type S is new T;
> 
> > The only difference I see between Ada's ADT and OOP, is that
> > in Ada, the data itself is separated from the package and must
> > be passed to the package methods at each call. The data lives
> > in the client side.
> 
> This applies to all types and has nothing to do with ADT or OO. A state 
> can be either localized in an object (good design) or kept outside it in 
> global variables (bad design).
> 
> > While in OOP, the data lives inside the object. (these are called
> > data memebers).
> 
> Just like in any type, not even abstract one. E.g.
> 
>    type X is range 1..100;
> 
> The "data" live in each instance of X.
> 
> > Let look at this simple example from
> 
> [...] Stack example
> 
> > In OOP, the stack itself, would live inside the "module" which will
> > be the class/object in that case.
> 
> No, OOP example of stack is exactly the one you cited. There is a type 
> Stack and operations of. A non-OO/ADT stack would be:
> 
> generic -- No parameters!!
> package Generic_Integer_Stack is
>    procedure Push (Val : Integer);
>    procedure Pop (Val : out Integer);
> 
> You get a stack instance this way:
> 
>    package Integer_Stack is new Generic_Integer_Stack;
> 
> > So the main difference I see, is that in Ada ADT, the data (the stack
> > in this example) lives on the client side, and the package
> > just has the methods.
> 
> The sentence does not make sense to me. OO is ADT. I am not sure which 
> issue you have problem with:
> 
> - No local states
> - Stateful vs stateless
> - Interface vs implementation inheritance


Your statement is _very_ misleading.  OO has many common aspects
with ADT, but there is substantial difference.  One may have
prefecty fine ADT without having OO or vice versa (of course
Ada provides both so one may overlook the difference).  To
explain more, OO in mainly about inheritance and related
dynamic dispatch.  In more formal terms OO is mainy about
_dynamic_ subtyping.

To give an example, let me generalize stack example from
previous post.  This in not Ada, so I skip most details
just giving conceptsWe may have abstact interfaces BagAggregate.
StackAggregate and QueueAggregate.  Both StackAggregate and
QueueAggregate inherit from BagAggregate.  The interfaces and
actual type are parametrized and there is a type Stack(Integer)
which is a type exporting StackAggregate(Integer).  This is
abstract type, all you can do with it is declared in the
inteface.  You can use Stack(Integer) in places that statically
need BagAggregate(Integer).  You also have Queue(Integer)
which exports QueueAggregate(Integer).  You can use
Queue(Integer) in places that statically need BagAggregate(Integer).
Up to now this may look like normal OO with inheritance.
But there is signicifant difference.  You can form
List(Stack(Integer)), that is have list of stacks.  You
can form List(Queue(Integer)) that is have list of queues.
But you can _not_ have List(BagAggregate(Integer)).  In
OO design you could do this or some eqivalent to have
a list containg both stacks and queues.

-- 
                              Waldek Hebisch

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09  9:32 on Ada abtract data type vs. OOP Nasser M. Abbasi
  2022-09-09 10:49 ` Dmitry A. Kazakov
  2022-09-09 14:04 ` Jeffrey R.Carter
@ 2022-09-09 15:06 ` antispam
  2022-09-11  8:02   ` G.B.
  2 siblings, 1 reply; 8+ messages in thread
From: antispam @ 2022-09-09 15:06 UTC (permalink / raw)


Nasser M. Abbasi <nma@12000.org> wrote:
> Lets say one does not want to do inheritance. (I think it causes
> more problems than it solves actually).
> 
> The only difference I see between Ada's ADT and OOP, is that
> in Ada, the data itself is separated from the package and must
> be passed to the package methods at each call. The data lives
> in the client side.
> 
> While in OOP, the data lives inside the object. (these are called
> data memebers).
> 
<snip>
> To use it, The user does
> 
> -------------------------
> --  Example of use
> with Stacks; use Stacks;
> 
> procedure Test_Stack is
>    S : Stack;
>    Res : Integer;
> begin
>    Push (S, 5);
>    Push (S, 7);
>    Pop (S, Res);
> end Test_Stack;
> ---------------------
> 

> In OOP, the stack itself, would live inside the "module" which will
> be the class/object in that case.
> 
> So the above use example will becomes something like this
> 
> 
>   o:=Object();  -- this calls the constructor
>   o.Push(5); -- data now is stored inside "o"
>   o.Push(7)
>   res := O.Pop();
> 
> So the main difference I see, is that in Ada ADT, the data (the stack
> in this example) lives on the client side, and the package
> just has the methods.
> 
> For me, this actually better than OOP. Having methods separated
> from data is a good thing.
> 
> Is there is something I am overlooking other than this?

What you have above is trivial syntactic difference:

  o.Push(5)

versus

  Push(o, 5)

This is really no more difference than

  o.Push(5)

versus

  o :Push 5

that some OO langues use.  All syntaxes above mean call Push
(which may be called "function", "procedure", "method",
"generic function", etc.) applying it to  arguments 'o' and '5'.
The real difference is in mechanizm used to determine which code
to run.  In simplest case (C or Pascal) Push whould have
specified argument types and you could not use it with different
types.  In more complicated case there is overloading which
_at compile time_ decides which Push to call.  In OO there is
dispatch mechanizm which _at runtime_ decides which Push to
call.  In Ada you normally have overloading.  Tagged types
use OO dispatch.  To see difference runtime type must be
different than statically determined type, this is possible
due to inheritance.  Without inheritance diffences are
trivial.

-- 
                              Waldek Hebisch

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09 14:37   ` antispam
@ 2022-09-09 15:21     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2022-09-09 15:21 UTC (permalink / raw)


On 2022-09-09 16:37, antispam@math.uni.wroc.pl wrote:

> Your statement is _very_ misleading.  OO has many common aspects
> with ADT, but there is substantial difference.

I didn't say ADT is OO. I said OO is ADT. Clearly OO deals with abstract 
data types [and classes of].

[ Here abstract means: user-defined, an problem space abstraction, 
rather than Ada's abstract type in the meaning: a type with no instances. ]

> In more formal terms OO is mainy about
> _dynamic_ subtyping.

(dynamic polymorphism, actually)

OO is about of having classes of types in a way that the closure of that 
class would be a proper type again. In Ada terms:

1. T, some tagged type
2. Class = all types derived from T and T itself
3. [Derivation] closure type = T'Class

Ad-hoc polymorphism (overloading) and parametric polymorphism (generics) 
produce classes with no type for the closure. E.g. you have no type for 
all instances of all types having

    procedure Put (File : File_Type; Value : <type>); -- ad-hoc class

[... parametric polymorphism example skipped ...]

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

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09 10:49 ` Dmitry A. Kazakov
  2022-09-09 14:37   ` antispam
@ 2022-09-09 15:30   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2022-09-09 15:30 UTC (permalink / raw)


On 2022-09-09 12:49, Dmitry A. Kazakov wrote:

> - Ada 2005 added castrated Java-esque multiple dispatch
                                                  ^^^^^^^^ inheritance, 
of course

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

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

* Re: on Ada abtract data type vs. OOP.
  2022-09-09 15:06 ` antispam
@ 2022-09-11  8:02   ` G.B.
  0 siblings, 0 replies; 8+ messages in thread
From: G.B. @ 2022-09-11  8:02 UTC (permalink / raw)


On 09.09.22 17:06, antispam@math.uni.wroc.pl wrote:
>   In OO there is
> dispatch mechanizm which _at runtime_ decides which Push to
> call.  In Ada you normally have overloading.  Tagged types
> use OO dispatch.  To see difference runtime type must be
> different than statically determined type, this is possible
> due to inheritance.  Without inheritance diffences are
> trivial.

Agreed, except  dynamic vs static determination of the
callable thing. In Ada, O.Push (5)  means determination
of the specific Push at compile time whenever the specific
type of O is known. You need class-wide operands for
this choice to be made at run time.

C++ has a similar feature, I think.

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

end of thread, other threads:[~2022-09-11  8:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-09  9:32 on Ada abtract data type vs. OOP Nasser M. Abbasi
2022-09-09 10:49 ` Dmitry A. Kazakov
2022-09-09 14:37   ` antispam
2022-09-09 15:21     ` Dmitry A. Kazakov
2022-09-09 15:30   ` Dmitry A. Kazakov
2022-09-09 14:04 ` Jeffrey R.Carter
2022-09-09 15:06 ` antispam
2022-09-11  8:02   ` G.B.

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