On Wed, 28 May 1997 20:46:54 -0400 (EDT) Pierre Phaneuf <pp(a)dilu.ml.org> wrote:
>On Wed, 28 May 1997, The African Chief wrote:
>
>> If it can be done, then it should be done. However, I would advise
>> against using it in the RTS or in any UNIT supplied as part of the GPC
>> distribution. Let us make it's use completely optional (i.e., people can
>> use it in their own programs if they want, but GPC is itself free from it.
>
>Well, removing GOTO is another thing that could be done. Maybe we
>shouldn't do that, but *please*, let's not add multiple inheritance to a
>language whose goal is to be the Right Thing and to be simple. Do you know
>how many pages there is in the C++ standard? Its something in excess of a
>*thousand*. Do we want *that*?
No. C++ is clumsy and bloated. However, the problem is that MI is part
of the language definition. If it were to be implemented in GPC, it wouldn't
be part of any definition. It would just be a local extension that could be
ignored by anybody who so wishes. I don't see that having such an
extension is so bad. Some day, someone will want to use it, and it
doesn't help to tell them that they don't need it.
Also note that Java has been widely
>> I think this is better than using MI. BP seems to have set the trend to
>> have an almost useless ultimate ancestor for an object heirarchy. I
>> personally do not agree with that philosophy.
>
>Why do you disagree?
A purely personal thing, perhaps. If I did it my own way, without any
preconceived notions, I would have an ancestor object which would
contain everything that I think every object should have. What I think
every object should have changes from time to time, and therefore, for
me, it is better to start with more, than with less ;-)
> I really don't see what a TWindow object and a
>TString object has in common that should be in TObject!
They could all have a Name, a SelfID, a Parent, and a Child.
>BP didn't set that
>trend BTW. The Smalltalk anscestor object doesn't do *ANYTHING*.
The first thing I would do to it is to change that omission ;)
And what is the point of have the ancestor then - just for type
compatibility ?
>BPs constructor fills the object with zeros for instance. :-)
Not very useful at all. They might as well not have any constructor
or destructor.
>The use is in
>having the POBject pointer type handy, that can handle *any* objects. You
>have a single TCollection that can handle both TWindow objects and TString
>objects, even a *MIX* of those! *This* is what TObject is there for, not
>have a heap of methods.
Ok. Let's just say we have a difference of opinion there! My experience
in writing my CHIEFAPP class library has led me to a different conclusion
about what an ancestor object should be like. In the end, I suppose that
these things are a matter of personal preference!
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.50 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
Peter Gerwinski wrote:
> What are these "interfaces"? (Somebody already explained it to me some
> time ago, but I have forgotten ... #-)
Ok, here are some explanations from "Java in a Nutshell", with some comments
by me, and some ideas how to implement them in gpc:
"[Text describes a situation that seems to need MI]
\footnote{ C++ allows classes to have more than one superclass, using a
technique known as 'multiple inheritance'. Multiple inheritance opens up
a can of worms, so Java replaces it with what many believe is a more elegant
solution. }
Java's solution to this problem is called an interface. An interface looks
a lot like an abstract class, except that it uses the keyword 'interface'
instead of the words 'abstract' and 'class'. [...]
While an 'abstract' class may define some 'abstract' methods and some non-
'abstract' methods, all the methods defined within an interface are
implicitly 'abstract'. [The 'abstract' keyword can, but doesn't have to, be
omitted.] [Note: In Java, all methods are what we call virtual.]
A further restriction on interfaces is that any variables declared in an
interface must be 'static' and 'final' - that is, they must be constants
[ordinary constants, not initialized variables, nor object constants -
since ordinary constants don't appear in BP's object type declarations at
all, this restriction effectively means there can't be any variables or
constants in an interface in gpc, so an interface consists only of
declarations of abstract virtual methods (**, see below)].
So what can we do with an interface? Just as a class 'extends' [is derived
from] its superclass, it also optionally 'implements' an interface.
'implements' s a Java keyword that can appear in a class declaration
following the 'extends' clause. 'implements' should be followed by the name
of the interface that the class implements. In order to implement an
interface, a class must first delcare the interface in an 'implements'
clause, and then it must provide an implementation (i.e. body) for all of
the 'abstract' methods of the interface.
\footnote{ This is the real difference between multiple inheritance in C++
and interfaces in Java. In C++, a class can interit method implementations
from more than one superclass. In Java, a class can inherit actual
implementations only from one superclass. It can inherit additional
'abstract' methods [declarations] from interfaces, but it must provide its
own implementation of those methods. It is rare, however, to actually be able
to use C++ multiple inheritance to inherit useful, non-trivial
implementations from more than one class. The elegance and simplicity of
Java's interface more than compensate for the inability to inherit
implementations from more than one class. }
[...]
Using Interfaces
[...] [Syntax translated to Pascal, tentatively:]
Type
Drawable=Interface [this wouldn't introduce a new reserved identifer, but
I'm not sure if it can be parsed easily.]
Procedure Draw(dw:DrawWindow); ['virtual;' or 'abstract;' optionally]
[possibly other methods]
End;
[declaration of type Rectangle that doesn't have a Draw method]
DrawableRectangle=Object(Rectangle;Drawable)
[in Java this is:
public class DrawableRectangle extends Rectangle implements Drawable]
x,y:Double;
Constructor Init(w,h:Double);
Procedure Draw(dw:DrawWindow); virtual;
[other methods, destructor]
End;
[implementation of all methods, constructor and destructor]
Var
d:^Drawable;
r:^Rectangle;
dr:^DrawableRectangle;
Begin
New(dr,Init(2.3,4.5));
d:=dr;
r:=dr;
dr.Draw;
d.Draw;
End.
[...]
[Classes can implement several interfaces ('implements Drawable, Scalable').]
[...]
Extending Interfaces
[...]
public interface Transformable extends Scalable, Rotateable, Reflectable
public interface DrawingObject extends Drawbable, Transformable
public class Shape implements DrawingObject
[So there is 'multiple inheritance' between interfaces - which makes no
problems!]
[...]
No 'implements' clause is permitted in an interface declaration.
An interface body may not contain any constructors, static class
initializers, instance variables, or class methods. [...]"
Concerning a possible implementation in gpc:
AFAICS, the only thing that really makes problems are variables (or
parameters) of interface types.
First of all, since interfaces can't be instantiated, such variables or
parameters must be pointers (or var parameters). In Java, this is implied,
since *all* object variables are pointers.
But such a pointer must point to the actual object and to the methods
declared in the interface. Since different object types can implement the
same interface, those methods will not always be at the same VMT offset.
However, it is possible to guarantee that all methods of one interface
are at consecutive VMT offsets (in the order they're declared in the
interface). (*, see below)
So one needs the VMT offset of the interface's first method.
I can see (at least) two solutions:
- A "pointer" to an interface variable consists of two parts: the actual
pointer to the variable, and the VMT offset of the first method (or,
alternatively, directly the adress of the first method in the VMT).
Disadvantage: The pointer gets twice as big. The difference must be
considered when assigning it to another pointer (this could be an untyped
pointer or a pointer of one of the "parent" interfaces - in the latter
case the VMT offset has to be adjusted).
- The VMT must contain information about all interfaces that are implemented
together with the addresses of their methods. However, since different
object types can implement different interfaces, and one type can
implement more than one interface, I can't think of a method that doesn't
involve some kind of searching (searching the wanted interface out of
possibly many interfaces).
So this is basically a speed vs. size tradeoff. For most applications,
I think, speed is to be favoured (and 32 bit programming favours speed,
anyway), so I'd prefer the first solution. I can't see a solution without
a need of either searching or additional data *per variable* (whereas
additional data per VMT wouldn't matter so much).
(*)
If we allow the following inheritance between interfaces
A
/ \
B C
\ /
D
(and I don't see a reason why not), the methods of A will have to be
duplicated in D, so that it's possible to "cast" a ^D into a ^B or a ^C.
So the "VMT" of D would look like
Methods of A \_ "B"
New methods of B /
Methods of A \_ "C"
New methods of C /
The two parts "Methods of A" would contain the same information, but since
this is only in the VMTs, I don't think it wastes very much memory.
I hope I was clear in most things. If not, please ask again. Of course,
there will be some "details" left to be solved, but I hope, no major
problems.
(**)
This last thing is a bit off-topic to interfaces, so I put it at the end.
Thinking about object constants again, I think there can be "un-virtual"
constants, i.e. constants that can be redeclared in child classes, but the
parent class will always use their own constants. So, effectively, they're
oridinary constants, with the only difference that they're visibility is
limited to the object type (applying the usual rules of
public/protected/private). These constants don't have to be typed, of course.
Also, one can imagine "un-virtual" class variables, very similarly.
They should be relatively easy to implement (since the only difference to
ordinary constants/variables is the visibility). If this is done, interfaces
could contain constants, like in Java.
--
Frank Heckenbach, Erlangen, Germany
heckenb(a)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
On Wed, 28 May 1997 15:46:06 -0400 (EDT) Pierre Phaneuf <pp(a)dilu.ml.org> wrote:
>On Wed, 28 May 1997, The African Chief wrote:
[...]
>Maybe the InstanceFromSelfID is valid (though I'd simply use the instance
>pointer as a handle), but (in a Turbo Vision context) only TView should
>have a Handle, because it is the first class that can possibly have a
>window handle. The InstanceFromHandle would hence return a PView or a
>PWindow, which is much more useful, since TView/TWindow has methods for
>window manipulation that TObject doesn't even have.
Yes, that is correct. The handle is not not necessary in TObject - but
I still feel that it does no harm to have it there.
>> It has a present use - to be able to locate every object instance by its
>> own unique ID. See above.
>
>The instance pointer is an unique ID, why have another redundant one?
Yes, the instance pointer is a unique ID. But this assumes that you
know the instance pointer. This will be the case in most situations,
but it won't always be the case. And, like I said in another post, there
are things that you can do with integers that you cannot do with
pointers.
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.50 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
On Wed, 28 May 1997 15:54:42 -0400 (EDT) Pierre Phaneuf <pp(a)dilu.ml.org> wrote:
>On Wed, 28 May 1997, The African Chief wrote:
>
>> [1] - the DOS and CRT units are not portable to unix and Linux). This is
>> obviously due to the use of functions from DOS.H and CTYPE.H and
>> CONIO.H. Can anyone port those units to unix and Linux (or, put another
>> way, are there any unix/Linux ports of dos.h, ctype.h and conio.h)?
>> Without these, the DOS and CRT units will never port to unix/Linux.
>
>This is harder. I recommend not using any ports of dos.h, ctype.h and
>conio.h (though I know of at least a port of conio.h), because they would
>be required to build the units.
This wouldn't be a problem if the ports were part of the GPC distribution
just as they are with DJGPP (and EMX?).
>Better make their functionality integrated in the units,
I am not sure what this means. If it means writing the code for DOS
and CRT from the scratch, I wouldn't want to be the one to do that!
>> [2] the SYSTEM unit is not totally portable - because of "itoa()" which
>> I used in the "Str" procedure. itoa() converts an int to a CString. Is there
>> a unix/Linux equivalent of this? I can use an IFDEF to link the unix/Linux
>> equivalent if "__UNIX__" is defined.
>
>If there is a Unix equivalent, it could be used both in the Unix version
>and the DOS version, no? Would be cleaner...
AFAICS the unix version is not in the DOS version, otherwise I would
have used it (I tried to use only portable C functions in the SYSTEM
unit). The problem is that itoa() exists in DJGPP and EMX (and perhaps
CYGWIN) but not in unix/Linux. If there is a function in the unix/Linux
C libraries that does the same thing, that function does not exist in
DJGPP, so it cannot be used there. I cannot see any solution other
than an IFDEF here!
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.50 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
According to Pierre Phaneuf:
>
> Here's the answer I got from one of my C wizard friend... :-)
>
> [...]
>
> From: stephane.lajoie(a)belairdirect.com
>
> itoa is in stdlib.h/libc.a for DJGPP. I thought it was ANSI C...? Anyway, I
> would suggest sprintf like this:
>
> sprintf(buf, "%i", i);
Why use C when GPC (Extended Pascal) has the same?
WriteStr ( Buf, i : FieldWidth );
Greetings,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
According to Pierre Phaneuf:
>
> If we have to have a MI-like feature, it should be something less
> dangerous, like interfaces, not the real thing/poison.
What are these "interfaces"? (Somebody already explained it to me some
time ago, but I have forgotten ... #-)
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
According to Sven Hilscher:
>
> I had a little problem to use the new info files. I get all the time the
> message "node TOP not found". After removing the last line in gpc.inf
> (these "end tag table" was doubled) now it works fine...
This line was caused by RHIDE.
(Somebody should report that bug to Robert ...)
Greetings,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski(a)uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]
On Wed, 28 May 1997 19:41:17 +0200 (MET DST) Peter Gerwinski
<peter(a)agnes.dida.physik.uni-essen.de> wrote:
>> Is it possible to tell which GPC platform and version is being used?
>> [...]
>> This would really help in writing portable code. What do you think?
>
>I agree in complete. Let's ask the list what they think, but I am almost
>sure that everybody will agree.
Ok. I am sending this response to the list.
>> [...]
>> So, can this be done with GPC? It would help with a lot of things, e.g.,
>> in the SYSTEM unit - so, could we have these pre-defined in GPC;
>> __LINUX__
>> __UNIX__
>> __DJGPP__ (or __MSDOS__)
>> __EMX__ (or __OS2__)
>> __WIN32__ (or __CYGWIN__)
>> - depending on which GPC port you are using.
>
>Since `__MSDOS__' is ambiguous and with EMX one and the same executable
>runs on DOS as well as on OS/2 making this a run-time, not a compile-time
>decision, I vote for `__DJGPP__' and `__EMX__' rather than `__MSDOS__'
>and `__OS2__'.
Yes, I agree.
>Since I agree with "xxxx" that Windows 95/NT is
>not a "win" in the sence of hacker's speech (see `jarg400.info.gz' from
>the GNU distribution), but Cygnus is, I'd vote for `__CYGWIN__' rather
>than `__WIN32__', although "Win32" is the official name of that API.
Yes, "__CYGWIN__" seems fine.
>> and you could have;
>> __VER20__
>>
>> or whatever, depending on the GPC version.
>
>Here I'd prefer to use the GNU convention and define the `__GPC__' symbol
>to be `2' and `__GPC_MINOR__' to be `0'.
I am not sure I understand how this works.
>This also avoids confusion with Borland Pascal 4.0 once we reach
>that version number.
There would be no confusion, because BP doesn't include the leading
and trailing "__". TP 4.0 would have "VER40" defined. GPC 4.0 would
have "__VER40__" defined.
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.50 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
On Wed, 28 May 1997 20:04:02 -0400 (EDT) Pierre Phaneuf <pp(a)dilu.ml.org> wrote:
>
>Here's the answer I got from one of my C wizard friend... :-)
>itoa is in stdlib.h/libc.a for DJGPP. I thought it was ANSI C...? Anyway, I
>would suggest sprintf like this:
>
> sprintf(buf, "%i", i);
[...]
Thanks!
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v3.50 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12(a)cc.keele.ac.uk
I had a little problem to use the new info files. I get all the time the
message "node TOP not found". After removing the last line in gpc.inf
(these "end tag table" was doubled) now it works fine...
___,
((__ o
,____)) V E N I