[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Proposal: Abstract types for OOC



At 08:17 PM 3/1/99 +0100, hartmut Goebel wrote:

...

> >It is true that the compiler knows whether a type is abstract or not. By
> >definition, it is abstract if it has abstract methods. However, for a
> >programmer to determine this  he or she would have to scan the module in
> >which the type is defined, as well as the modules of all super-types to
> >search for abstract methods.
>
>According to this arguments: would you suggest enforcing the declaration of
>methods when declarating the record? If yes: This is no longer Oberon then.
>If No: Why then require a record to be declared abstract?

No. I'm not suggesting that record declaration be changed. Oberon is
unusual (in my experience) in that methods are not "forward-declared" in
the class (or record) definition. This makes it a little harder to read
code, but easier to write it since you don't have to maintain multiple
declarations. 

However, I do think that abstract records should be explicitly declared
abstract. I would like to be able to look at a record declaration and
easily determine whether it is a concrete or abstract type. I don't want to
have to hunt through source code or symbol files to determine this. 

> >In this sense, the ABSTRACT system flag
> >enforces a simple documentation convention: all abstract types must be
> >declared to be abstract.
>
>You may use a tool for that. Its names 'browser' :-)

Yes, browsers are useful. It would be possible to extend oob (or oocn) to
output suitable definitions of modules. Currently, oob does not output
system flags on records or procedures so this would have to be changed in
order to be useful in this way.

Personally, I prefer source code to be self-documenting wherever possible.

> >More importantly, the ABSTRACT system flag signals the programmers
> >intention to the compiler. It unambiguously distinguishes between abstract
> >and concrete types. Without this distinction, the compiler would have to
> >assume that any type with abstract methods is abstract. This may not agree
> >with the programmers intentions (eg. they intended to declare a concrete
> >type, but forgot to implement an abstract method). The ABSTRACT flag on
> >records allows us to catch this kind of error.
>
>Is it really necessary to catch this error? I don't think so!
>
>Simple ecample:
>Module "Abstract" defined an abstract record + methods.
>Module "Concrete" implement a concrete type base on Abstract.
>Moduel "UseConcrete" instantiates this concrete type.
>
>The only benefit in this case would be: the error get signaled when compiling
>"Concrete".
>
>Whithout explicit declaring records as abstract, the compilation of
>"UseConcrete" would signal an error.
>
> >I see this as an important
> >safety feature.
>
>It's a safety feature, but not at all important.

In your simple example it is probably not so important. Indeed, for proper
encapsulation module Concrete should provide constructors for its own types
in which case the instantiation (and thus the error report) would be in
Concrete.

In situations where abstract classes are implemented progressively via a
number of levels of sub-classes it becomes harder to determine whether a
given sub-class is abstract or not. By declaring records as abstract or
not, changes in the "abstractness" of a parent classes are only propagated
as far as their direct descendents before an error is signalled. Otherwise,
the error would only appear later when a sub-class is instantiated.

Whether you like this model or not is probably a matter of perference.
Personally, I prefer things to be explicitly stated and errors caught as
early as possible. However, both approaches are used in popular languages.
Component Pascal and Java require explicit declaration and signal errors;
C++ does not.

> >1) It can have abstract extensions, so sub-types can introduce new abstract
> >methods. This cannot be done for concrete types.
>
>But this is pretty usefull, eg.:
>
>  File = RECORD ... END;  (* concrete *)
>  CompressedFile = RECORD ... END;
>  PROC ABSRACT Compress * (cf: CompressedFile); END Compress;
>
>This enables to extent types for things, the author of the base class hadn't
>thought about. According to your proposal, this would not be possible -- thus
>limiting the usability.
>
>This may leed to all record type being declared as abstract. See below about
>this problem.
>

See below for reply.

> >Yes. By my proposal, you can declare abstract records without any abstract
> >methods. Technically, this goes against my original definition of abstract
> >types being those with abstract methods. Thus, we should probably either
> >change the definition, or disallow this kind of declaration.
>
>Changing the definition of "abstract type" is no solution. What is "abstract"
>on this type:
>
>  Module XX;
>  TYPE
>    X = RECORD ABSTRACT
>          a,b: INTEGER;
>        END;
>  END XX.
>
>Beside of being declared as abstract, it is concrete. Wiered, isn't it?

I agree that in itself, it might be wierd. Whether it is an appropriate use
of abstraction depends on whether you later extend the type or not (see
Tim's point about ObjectDesc). Note that you can also do the same thing in
other languages. For example (Java):

  abstract class X {
    int a, b;
  }

or (Component Pascal):

  X = ABSTRACT RECORD
    a, b : INTEGER;
  END;

Admittedly, this does not make it "right". 

> >2) It cannot be instantiated. Thus, the programmer must declare a concrete
> >extension.
>
>What speaks again instantiating the above type XX.X?

Only the fact that you've declared it abstract. This may be a base class
which you intend to extend later. In this case, you probably do not want it
to be instantiated.

> >I can't think of any situations where this would be particularly useful
> >properties for what are essentially "concrete" types.
>
>So why not disallow declaration of thus type at all? By simply ommitting the
>ASTRACT keyword for record type declarations.
>
> >We could enforce this interpretation of abstract types by insisting that
> >every type declared ABSTRACT has at least one method declared ABSTRACT. I
> >would be prepared to add this to the specification. Can anyone think of any
> >useful programming constructs that would be disallowed by this restriction?
>
>Since one can not re-abstract a concrete type (according to your proposal),
>one has to declare each type (eg. "Object") to-be-extented-somewhen as
>abstract. This would lead to nearly all type being declared as abstract.

Not all records will be declared abstract: you only need abstract methods
when you want to defer implementation. Many exported types will be
abstract. I don't see a problem with this. In the Blackbox Component
Framework, files, directories, readers, writers, locators are all abstract.
So are display ports, fonts, views, stores, etc. This is important to
achieve separation between interface and implementation.

>But since I can't implement all methods of "Object", I can't declare it as
>abstract -- thus it's concrete, thus it can't be re-abstracted later.

Personally, I don't favour re-abstraction of concrete types because it
encourages implementation inheritance which often leads to trouble (eg. the
semantic fragile base class problem). Component Pascal (after which I
modelled this proposal) does not allow abstraction of concrete types.
However, I acknowledge that there are valid uses for this construct and
that it is probably more a matter of programming style than technically
necesssary. I would never use it, but I'm prepared to relax point (3) in
the original proposal to allow this.

>Conclusion
>----------
>
>Requiering of explicit declaring a record type as abstract introduces a lot
>of problems, be it logically, language consistency, extensability or
>implementational (see mva's posting).

I'm not sure that there are serious logical problems.

I acknowledge the point about extensibility (see above).

I thought that Michael was objecting to rule about requiring records
declared abstract to have abstract methods, not to the declaration of
records as abstract. However, I may be wrong here...

>The only benefits are 1) documentation and 2) early error catching.

I regard both these as important considerations.

>These benefits re over-weight by the drawbacks. Thus I "vote" against this
>part of the proposal!
>
> >- Stewart
>
>+++hartmut

I've attempted to summarise the discussion in the following posting. I will
change the specification if enough people are in favour.

- Stewart