I have updated my class patch to gpc-2005031. Testing I get failure with fjf903c.pas:
TEST fjf903c.pas: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:14: error: method `p', overrides parent method /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas: In main program: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:31: error: assignment from incompatible pointer type
And the question now: what happens if the child tries to make a method with the same name as a parent, but without `override'. Is it an error (like OOP) or maybe just "shadows" parent method?
Waldek Hebisch wrote:
I have updated my class patch to gpc-2005031. Testing I get failure with fjf903c.pas:
TEST fjf903c.pas: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:14: error: method `p', overrides parent method /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas: In main program: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:31: error: assignment from incompatible pointer type
And the question now: what happens if the child tries to make a method with the same name as a parent, but without `override'. Is it an error (like OOP) or maybe just "shadows" parent method?
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
But fjf903c.pas is `--mac-pascal', and AFAIK it needs override (right, Peter?), so the test program seems to be wrong without `override'.
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
I have updated my class patch to gpc-2005031. Testing I get failure with fjf903c.pas:
TEST fjf903c.pas: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:14: error: method `p', overrides parent method /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas: In main program: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:31: error: assignment from incompatible pointer type
And the question now: what happens if the child tries to make a method with the same name as a parent, but without `override'. Is it an error (like OOP) or maybe just "shadows" parent method?
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
IIUC in Delphi it shadows (creates new method with the same name), but in BP it just overrides.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
I have updated my class patch to gpc-2005031. Testing I get failure with fjf903c.pas:
TEST fjf903c.pas: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:14: error: method `p', overrides parent method /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas: In main program: /pom/kompi/gcc/tst44/gcc-3.4.3/gcc/p/test/fjf903c.pas:31: error: assignment from incompatible pointer type
And the question now: what happens if the child tries to make a method with the same name as a parent, but without `override'. Is it an error (like OOP) or maybe just "shadows" parent method?
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
IIUC in Delphi it shadows (creates new method with the same name), but in BP it just overrides.
You can still access the old method by a "class-qualified" name. Or what's the difference between shadowing and overriding?
program Foo;
type a = object procedure p; end;
b = object (a) procedure p; end;
procedure a.p; begin WriteLn ('a.p') end;
procedure b.p; begin WriteLn ('b.p'); a.p end;
var v: b;
begin v.p end.
Frank
At 8:05 +0200 22/6/05, Waldek Hebisch wrote:
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
IIUC in Delphi it shadows (creates new method with the same name), but in BP it just overrides.
Could you explain the difference between shadow and override? Or perhaps it doesn't make sense with Mac's "always virtual" concept?
For Mac Pascal, you can never entirely remove a parent method, and you can all the parent method from within the method by calling "inherited p" (but that is only allowed in an overriden method p). Peter.
Peter N Lewis wrote:
At 8:05 +0200 22/6/05, Waldek Hebisch wrote:
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
IIUC in Delphi it shadows (creates new method with the same name), but in BP it just overrides.
Could you explain the difference between shadow and override? Or perhaps it doesn't make sense with Mac's "always virtual" concept?
For static methods shadow and override give the same. Consider:
type a = class procedure dop; virtual; { virtual just for consitency} procedure p; virtual; end; b = class (a) procedure p; virtual; end;
procedure a.dop; begin p end;
procedure a.p; begin writeln('a.p') end;
procedure b.p; begin writeln('b.p') end;
the in the case of overriding `b.dop' prints `b.p'. but in the case of shadowing it just prints `a.p', because `b.p' beeing a new method gets a new VMT slot, but `b.dop' calls old slot (so old method).
For Mac Pascal, you can never entirely remove a parent method, and you can all the parent method from within the method by calling "inherited p" (but that is only allowed in an overriden method p).
Do you mean that the following is illegal?:
type a = object procedure p; end; b = object(a) procedure q; end;
procedure a.p; begin end;
procedure b.q; begin inherited p end;
Waldek Hebisch wrote:
Peter N Lewis wrote:
At 8:05 +0200 22/6/05, Waldek Hebisch wrote:
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
IIUC in Delphi it shadows (creates new method with the same name), but in BP it just overrides.
Could you explain the difference between shadow and override? Or perhaps it doesn't make sense with Mac's "always virtual" concept?
For static methods shadow and override give the same. Consider:
type a = class procedure dop; virtual; { virtual just for consitency} procedure p; virtual; end; b = class (a) procedure p; virtual; end;
procedure a.dop; begin p end;
procedure a.p; begin writeln('a.p') end;
procedure b.p; begin writeln('b.p') end;
the in the case of overriding `b.dop' prints `b.p'. but in the case of shadowing it just prints `a.p', because `b.p' beeing a new method gets a new VMT slot, but `b.dop' calls old slot (so old method).
And Delphi does the latter? (Seems a bit contrary to the purpose of being virtual IMHO.)
Frank
Frank Heckenbach wrote:
Waldek Hebisch wrote:
the in the case of overriding `b.dop' prints `b.p'. but in the case of shadowing it just prints `a.p', because `b.p' beeing a new method gets a new VMT slot, but `b.dop' calls old slot (so old method).
And Delphi does the latter? (Seems a bit contrary to the purpose of being virtual IMHO.)
Yes, Delphi uses shadowing. They have a rationale: they want to sove "fragile base class problem" (when change to base class propagates to the whole inheritance hierarchy). Most of the time you do not want/need virtual methods. But to be able to override methods in base class they have to be virtual. When you add a new method to the base class it may conflict with child methods. Their selling point is that since you did not know about new base method surely you do not want to call it.
I still like more OOP way (error in such a case), but at least it is consistent with general Delphi attitude.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
the in the case of overriding `b.dop' prints `b.p'. but in the case of shadowing it just prints `a.p', because `b.p' beeing a new method gets a new VMT slot, but `b.dop' calls old slot (so old method).
And Delphi does the latter? (Seems a bit contrary to the purpose of being virtual IMHO.)
Yes, Delphi uses shadowing. They have a rationale: they want to sove "fragile base class problem" (when change to base class propagates to the whole inheritance hierarchy). Most of the time you do not
I suspect you two have put much more time into thinking about Delphi and its consistencies and inconsistencies than ever did the Borland people. After all, it was thrown together for commerical purposes building on the non-compliant broken Turbo Pascal, using a transient set of programmers and architects, none of whom ever stayed very long, and none of whom had a real interest in the language.
CBFalconer wrote:
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Waldek Hebisch wrote:
the in the case of overriding `b.dop' prints `b.p'. but in the case of shadowing it just prints `a.p', because `b.p' beeing a new method gets a new VMT slot, but `b.dop' calls old slot (so old method).
And Delphi does the latter? (Seems a bit contrary to the purpose of being virtual IMHO.)
Yes, Delphi uses shadowing. They have a rationale: they want to sove "fragile base class problem" (when change to base class propagates to the whole inheritance hierarchy). Most of the time you do not
I suspect you two have put much more time into thinking about Delphi and its consistencies and inconsistencies than ever did the Borland people. After all, it was thrown together for commerical purposes building on the non-compliant broken Turbo Pascal, using a transient set of programmers and architects, none of whom ever stayed very long, and none of whom had a real interest in the language.
Harsh words, but hoestly, I sometimes had this feeling when thinking about some strange BP constructs (e.g., `^' character constants). I can't imagine the Borland people really thought them through without ROTFL ...
Frank
Waldek Hebisch wrote:
Peter N Lewis wrote:
[snip]
For Mac Pascal, you can never entirely remove a parent method, and you can all the parent method from within the method by calling "inherited p" (but that is only allowed in an overriden method p).
Do you mean that the following is illegal?:
type a = object procedure p; end; b = object(a) procedure q; end;
procedure a.p; begin end;
procedure b.q; begin inherited p end;
I'm not exactly sure what Peter is referring to here, but your exmple should be legal in a complete program.
A better example program to demonstrate the working of "inherited" in MacPascal:
program InheritedTest(output);
type a = object procedure p; end; b = object(a) procedure q; procedure r; end; c = object(b) procedure p; override; end;
var cInstance : c;
procedure a.p; begin writeln('in a.p') end;
procedure b.q; begin writeln('in b.q'); inherited p end;
procedure b.r; begin writeln('in b.r'); p end;
procedure c.p; begin writeln('in c.p'); end;
begin new(cInstance); cInstance.q; cInstance.r; dispose(cInstance) end.
The output is:
in b.q in a.p in b.r in c.p
From this, you should be able to see "inherited" added to a method call
is used to specify calling a method in the declared (immediate) parent of the declared object type. The method doesn't have to be explicitly declared as a new method or overridden method in the direct ancestor parent - the method just has to be declared somewhere in the ancestory type chain. If there is more than one method in the ancestory chain (i.e., one or more method overrides), the first method encountered as you traverse the type chain from immediate parent to the root of the chain is the one called.
Without "inherited", the implicit "self" is used to to make a virtually dispatched method call; self.p in this example. The method actually called is the one associated with the object type of self at the time of the call.
An additional point that might need some clarification is on what "override" is classified as in MacPascal. Peter, in one or two previous postings, has used "keyword" to classify "override". As most people think of "keyword", that really isn't correct for "override". Technically, in MacPascal, "override" is classified as a Pascal language directive; therefore, it only has specific language significant meaning in the directive "slot" of a method heading declaration. For example; you could put the following declaration:
var override: integer;
immediately after the program heading in the above program, and the program is still a legal MacPascal program.
Gale Paeper gpaeper@empirenet.com
At 7:30 +0200 22/6/05, Frank Heckenbach wrote:
And the question now: what happens if the child tries to make a method with the same name as a parent, but without `override'. Is it an error (like OOP) or maybe just "shadows" parent method?
In BP OOP it shadows. (It doesn't have `override', or if you will, it's implicit.)
But fjf903c.pas is `--mac-pascal', and AFAIK it needs override (right, Peter?), so the test program seems to be wrong without `override'.
Correct, shadowing is not allowed without override in Mac Pascals. A method in a subclassed object must be either:
a) a new name in no parent object, and not have "override" or b) a name in a parent object, with the same parameters (same by type anyway, the formal parameter name is not typically checked, although GPC typically requires the formal names to match), and must have "override"
Looking at the fjf903c.pas test file, yes, procedure p in object b would need "overide", ie:
b = object (a) procedure p; override; end;
Enjoy, Peter.
Peter N Lewis wrote:
b) a name in a parent object, with the same parameters (same by type anyway, the formal parameter name is not typically checked, although GPC typically requires the formal names to match), and must have "override"
The latter condition is a consequence of the fact that all methods are virtual. If we support/require `override' without all-methods-virtual in another dialect (mix), this condition wouldn't apply IMHO.
Frank
At 8:19 +0200 22/6/05, Frank Heckenbach wrote:
Peter N Lewis wrote:
b) a name in a parent object, with the same parameters (same by type anyway, the formal parameter name is not typically checked, although GPC typically requires the formal names to match), and must have "override"
The latter condition is a consequence of the fact that all methods are virtual. If we support/require `override' without all-methods-virtual in another dialect (mix), this condition wouldn't apply IMHO.
Which condition do you mean? The matching parameters?
Ok, so lets see if I understand the rules you are suggesting. For a given subclassed object method p, which might be virtual or static, there are three possible parent method states: no method named p in any parent; a static method named p in a parent method; a virtual method named p in a parent method. It is also possible there might be a mix of static and virtual methods named p, I presume only the most recently (object hierarchy wise) defined one would be relevant.
So that gives six possible combinations:
1. static method p defined and no method named p in any parent Legal. "override" is not allowed. "inherited p" not allowed.
2. virtual method p defined and no method named p in any parent Legal. "override" is not allowed. "inherited p" not allowed.
3. static method p defined where a static method named p in a parent Legal. "override" is required if enabled. "inherited p" is ok. Does parameters have to match? Is any warning given if no "override"?
4. virtual method p defined where a static method named p in a parent Is this legal? "override" is required if enabled. "inherited p" is ok. Does parameters have to match? Is any warning given if no "override"?
5. static method p defined where a virtual method named p in a parent Is this legal? "override" is required if enabled. "inherited p" is ok. Does parameters have to match? Is any warning given if no "override"?
6. virtual method p defined where a virtual method named p in a parent Legal. "override" is required if enabled. "inherited p" is ok. Does parameters have to match? Is any warning given if no "override"?
Whether a method is virtual or static depends on whether the "virtual" keyword is there or the dialect "all-methods-virtual" state.
Whether override is enabled depends on the dialect "override" state. I would think if the override dialect is enabled, then it would be required in any of the last four cases. Peter.
Peter N Lewis wrote:
At 8:19 +0200 22/6/05, Frank Heckenbach wrote:
Peter N Lewis wrote:
b) a name in a parent object, with the same parameters (same by type anyway, the formal parameter name is not typically checked, although GPC typically requires the formal names to match), and must have "override"
The latter condition is a consequence of the fact that all methods are virtual. If we support/require `override' without all-methods-virtual in another dialect (mix), this condition wouldn't apply IMHO.
Which condition do you mean? The matching parameters?
Yes.
Ok, so lets see if I understand the rules you are suggesting. For a given subclassed object method p, which might be virtual or static, there are three possible parent method states: no method named p in any parent; a static method named p in a parent method; a virtual method named p in a parent method. It is also possible there might be a mix of static and virtual methods named p, I presume only the most recently (object hierarchy wise) defined one would be relevant.
So that gives six possible combinations:
static method p defined and no method named p in any parent Legal. "override" is not allowed. "inherited p" not allowed.
virtual method p defined and no method named p in any parent Legal. "override" is not allowed. "inherited p" not allowed.
static method p defined where a static method named p in a parent Legal. "override" is required if enabled. "inherited p" is ok.
Yes.
Does parameters have to match?
No (according to BP).
Is any warning given if no "override"?
Only if the object model requires it (and then perhaps even an error). In the BP model, that's a normal thing to do, so no warning there.
- virtual method p defined where a static method named p in a parent Is this legal?
BP allows it, but I don't see any real use for it, so GPC warns already.
"override" is required if enabled. "inherited p" is ok. Does parameters have to match? Is any warning given if no "override"?
As in 3.
- static method p defined where a virtual method named p in a parent Is this legal?
No (according to BP). This would create some really confusing semantics, so it's good IMHO it's not allowed. (In fact, GPC makes the new method virtual automatically, but warns.)
- virtual method p defined where a virtual method named p in a parent Legal. "override" is required if enabled. "inherited p" is ok. Does parameters have to match?
Yes.
Is any warning given if no "override"?
As above.
Whether a method is virtual or static depends on whether the "virtual" keyword is there or the dialect "all-methods-virtual" state.
Yes.
Whether override is enabled depends on the dialect "override" state. I would think if the override dialect is enabled, then it would be required in any of the last four cases.
I agree.
Frank