OOP_(re)

Sun, 8 Jun 1997 17:03:09 +0200



Peter Gerwinski wrote:

> > BTW: Do TV programs actually rely on the zeroing out, or is this just a
> > paranoia initialization?
>
> They do.

Bad style! Well, at least then there should be a BIG warning in the BPCompat
objects.pas not to use the library with long strings or other schemata or
any initalized fields...

> > [String constants as Object IDs ...]
> >
> > I don't think so. If Delphi does it in a bad way, we don't have to duplicate
> > that. But it would be good if a Delphi user could actually check what Delphi
> > does.
>
> I don't think it's so bad:  Strings are more flexible than Integers.  I really
> like to index a `RessourceFile' (in TV) with Strings ...

As Pierre said: string comparison are less efficient than integer compares,
and generally I think *internal* things (i.e. things that must only be read
by computers, not by humans) should use integers rather than strings when
there's no real need for strings. Resource files, AFAIK, are binary files,
anyway, so what good would it be to have some strings scattered in them?

A different thing would be textual "resource" files (e.g. like Windoze .ini
files): for such things it can be useful to have a string ID (class name),
with the compiler switch we discussed, *additionally*, but I think the
primary ID should be an integer. (BTW: It might seem that string IDs are
"more unique" than integer IDs, but I think the opposite is the case: many
programmers will write some "TEdit" class (or "TWindow", "TString", ...),
but with integer IDs there are no problems if they choose a unique
programmer ID first.)

BTW: The compiler switch for the string class names could perhaps be saved
if the VMTs are generated in the main program (we discussed this for other
reasons, anyway). Then, the compiler could know if any part of the program
referred to a string ID (this information would have to be stored in the
.gpi file for units and modules), so the compiler could decide by itself
whether or not to include the string ID. The same, of course, is true for
the integer ID, so any program will contain just those ID(s) that it uses.
So both IDs could coexist peacefully... :-)

Syntax proposal:

Object(...)[StringID,NumID]

Either or both IDs can be omitted. NumID defaults to 0, StringID to the
class name (identifier). Accessible (readable) through fields ("object
constants") called "ClassName" and "ClassID".

> > If the "other program" is part of the standard library, it would be ok (just
> > adapting our library to accept integers). Otherwise perhaps declare a
> > function to convert a numeric ID to a string. This function would have to be
> > inserted into the Delphi source then, but with a dummy function declared in
> > Delphi, the code could still be used in Delphi.
>
> Anyway, I have more and more the impression that "Delphi compatibility"
> users desire does not mean that the GNU Pascal compiler must be able to
> compile Delphi's VCL, but that GNU Pascal has its own "VCL" with a 100%
> compatible API.

That's what I meant: if the format of the ID (string or integer) is only
relied upon by the library, we could do it differently in gpc. But I'm not
really convinced that Delphi handles these IDs as strings, could someone
please check it out?

> > BTW: What about the QueryInterface things? They might make "100% source
> > compatibility" with Delphi impossible, anyway, as soon as interfaces are
> > used.
> 
> ??? Sorry, I don't understand.

I don't either... ;-)

I mean, I don't really understand what QueryInterface does, or how it's
used, but AFAI understood it, it's needed to access interfaces. If that's
right, interface acces in Delphi and gpc might be so different that programs
that use interfaces simply can't compile with Delphi and gpc at the same
time (without some {$IFDEF}s, of course). Any Delphi users to explain this
or show some code that uses interfaces?

> > I think I've found a third way, one that doesn't influence the pointer format
> > and doesn't blow up the objects. It does, however, waste some space in the
> > VMTs. I'm sending it to you by private mail (mainly because it's easier for
> > me to describe it in German) -- sorry to other readers of the list who are
> > interested in this discussion, but we'll post the results back to the list
> > -- whatever it will be finally...
>
> One pre-result:  I like that third method, but it causes some techical
> problems as well.  This task *is* a nontrivial one!

Next pre-result: We're getting on! I think we can use this way... :-)

> > But how many fields and which type??? I don't think that's a good idea.
>
> One additional field of type "pointer to base object" will allow to
> store as much additional information as desired with the object.

In which class, and pointer to which class? Sure, a pointer to TObject could
do anything, but would require type casts (which I consider bad style), or
absolute declarations (even worse).

> Some additional Boolean fields, stored in a packed array, cannot hurt.
>
> See `tree.*' in the GCC source code for an example of what I mean with
> "extensibility". The "tree nodes" used in the GCC and GPC front-end are
> in fact Objects (written in C, not in C++!), and they contain such
> extension fields at some central nodes in the object tree.

Sorry, I don't really feel like wading through 100kB of C code now, but I
guess they put in the "unused" fields because they're emulating objects --
for lack of an inheritance mechanism that allows to add fields when they're
really needed. So I don't see how this would apply to gpc OOP.

> > Actually, this is quite a general principle to get something like "separate
> > inheritance" (of different parts of an object), by splitting up the object
> > into several part-objects. There is an overhead (one additional pointer and
> > its dereferencing), OTOH one can often eliminate case discriminations by
> > clever use of virtual methods in the new part-objects.
> 
> :-)  Just what I proposed above:  One additional pointer.
> It seems that we in fact agree, but we chose different words for it.

Not completely: my suggestion is to introduce pointers to appropriate types,
e.g. pointers to some kind of video objects from all classes that access
video. The (abstract) video class would provide the services required by
those classes. That's a bit more specific than just a general purpose
pointer.

Another thing (not belonging to the topics above, but I didn't want to start
a new mail):

I think it could be useful to let the "IS" operator do an implicit type cast,
so e.g. the following would compile:

type
  a=object
    end;

  b=object(a)
     c:integer
    end;

var d:^a;

begin
 if d^ is b then writeln(d^.c)
end.

So when an "if" condition contains just one "is"-comparison (no other
conditions with "and" or "or"), the object should be type cast to the
actual type for the scope of the "then" statement. (Of course, this could
be generalized to more compilcated conditions, but I think this simple case
would suffice for most purposes.)

I don't know how difficult this is to implement, but it would be a nice
feature. E.g., in a program I have some situations like:

 if CurrentEditor^ is TTextEditor
   then TTextEditor(CurrentEditor^).TextSearch(...)

I think this type cast should be superfluous (from a "high level" point of 
view). (Of course, the "is" currently is a "TypeOf" comparison.)
-- 
Frank Heckenbach, Erlangen, Germany
heckenb@mi.uni-erlangen.de
Turbo Pascal:   http://www.mi.uni-erlangen.de/~heckenb/programs.htm
Internet links: http://www.mi.uni-erlangen.de/~heckenb/links.htm


Frank Heckenbach (heckenb@mi.uni-erlangen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es