I just found another problem in BP's OOP. In the following program, `o.f' in oo.p is ambiguous. It could mean field f of the field o, or function f of the parent type o. Both BP and GPC (currently) do the former (i.e., say 99).
I noticed this because the OOE draft forbids this case by requiring that object fields don't clash with parent type names.
We do we do here? Allow it in BP mode with a warning, error otherwise?
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record f: Integer end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.f) end;
var v: oo;
begin v.o.f := 99; v.p end.
Frank
On 18 May 2004 at 4:03, Frank Heckenbach wrote:
I just found another problem in BP's OOP. In the following program, `o.f' in oo.p is ambiguous. It could mean field f of the field o, or function f of the parent type o. Both BP and GPC (currently) do the former (i.e., say 99).
I noticed this because the OOE draft forbids this case by requiring that object fields don't clash with parent type names.
We do we do here? Allow it in BP mode with a warning, error otherwise?
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record f: Integer end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.f) end;
var v: oo;
begin v.o.f := 99; v.p end.
This looks okay to me (i.e., I would expect "99"). The "Writeln (o.f)" clearly refers to the "f" field of the record "o". The fact that it is qualified makes it clear (to me at least). It could not possible refer to the function "f" in the parent object, because using the base name of the parent object in this manner must generate a compiler error. On the other hand, "Writeln (f)" would refer to the function "f" in the parent object. In other words, I don't see any ambiguity here - and neither does the compiler, because, in fact, there is no ambiguity.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
On 18 May 2004 at 4:03, Frank Heckenbach wrote:
I just found another problem in BP's OOP. In the following program, `o.f' in oo.p is ambiguous. It could mean field f of the field o, or function f of the parent type o. Both BP and GPC (currently) do the former (i.e., say 99).
I noticed this because the OOE draft forbids this case by requiring that object fields don't clash with parent type names.
We do we do here? Allow it in BP mode with a warning, error otherwise?
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record f: Integer end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.f) end;
var v: oo;
begin v.o.f := 99; v.p end.
This looks okay to me (i.e., I would expect "99"). The "Writeln (o.f)" clearly refers to the "f" field of the record "o". The fact that it is qualified makes it clear (to me at least). It could not possible refer to the function "f" in the parent object, because using the base name of the parent object in this manner must generate a compiler error.
Not at all. If we rename the field, both GPC and BP call the parent method and say 42. This shows that the parent method call is syntactically correct (and I see no reason why it shouldn't -- it's the normal form of parent method calls).
I.e., in the original program, both interpretations are valid (i.e., it's ambiguous), and one happens to take precendence (likely unintentionally -- I hadn't considered this case before, and I'm not sure Borland did).
On the other hand, "Writeln (f)" would refer to the function "f" in the parent object.
This refers to the method in the current object (which in this case is inherited from the parent). (You may be confusing inheritance with explicit parent method calls.) E.g., if you add a method f to the child, you have:
1. f: call of the child's method 2. o.f: call of the parent's method 3. o.f: access of the sub-field
(This may make the ambiguity clearer, but it's also there in the original program where 2. and 3. still apply, and 1. is equivalent to 2.)
Frank
On 18 May 2004 at 22:06, Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
On 18 May 2004 at 4:03, Frank Heckenbach wrote:
I just found another problem in BP's OOP. In the following program, `o.f' in oo.p is ambiguous. It could mean field f of the field o, or function f of the parent type o. Both BP and GPC (currently) do the former (i.e., say 99).
I noticed this because the OOE draft forbids this case by requiring that object fields don't clash with parent type names.
We do we do here? Allow it in BP mode with a warning, error otherwise?
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record f: Integer end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.f) end;
var v: oo;
begin v.o.f := 99; v.p end.
This looks okay to me (i.e., I would expect "99"). The "Writeln (o.f)" clearly refers to the "f" field of the record "o". The fact that it is qualified makes it clear (to me at least). It could not possible refer to the function "f" in the parent object, because using the base name of the parent object in this manner must generate a compiler error.
Not at all. If we rename the field, both GPC and BP call the parent method and say 42. This shows that the parent method call is syntactically correct (and I see no reason why it shouldn't -- it's the normal form of parent method calls).
[...]
I am not sure that I made myself clear. This variation of the program shows what I meant.
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record af: Integer { we have renamed this field } end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.af); WriteLn (o.f); { this must and does generate a compiler error } end;
var v: oo;
begin v.o.af := 99; v.p end.
As you can see, the point that I made is correct. The original program was not ambiguous, and "Writeln (o.f)" in the original "procedure oo.p" could only correctly refer to the "f" field of the "o" record - it could not correctly refer to the "f" method (unless I am missing something).
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
On 18 May 2004 at 22:06, Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
On 18 May 2004 at 4:03, Frank Heckenbach wrote:
I just found another problem in BP's OOP. In the following program, `o.f' in oo.p is ambiguous. It could mean field f of the field o, or function f of the parent type o. Both BP and GPC (currently) do the former (i.e., say 99).
I noticed this because the OOE draft forbids this case by requiring that object fields don't clash with parent type names.
We do we do here? Allow it in BP mode with a warning, error otherwise?
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record f: Integer end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.f) end;
var v: oo;
begin v.o.f := 99; v.p end.
This looks okay to me (i.e., I would expect "99"). The "Writeln (o.f)" clearly refers to the "f" field of the record "o". The fact that it is qualified makes it clear (to me at least). It could not possible refer to the function "f" in the parent object, because using the base name of the parent object in this manner must generate a compiler error.
Not at all. If we rename the field, both GPC and BP call the parent method and say 42. This shows that the parent method call is syntactically correct (and I see no reason why it shouldn't -- it's the normal form of parent method calls).
[...]
I am not sure that I made myself clear. This variation of the program shows what I meant.
program Foo;
type o = object function f: Integer; end;
oo = object (o) o: record af: Integer { we have renamed this field } end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.af); WriteLn (o.f); { this must and does generate a compiler error } end;
var v: oo;
begin v.o.af := 99; v.p end.
As you can see, the point that I made is correct. The original program was not ambiguous, and "Writeln (o.f)" in the original "procedure oo.p" could only correctly refer to the "f" field of the "o" record - it could not correctly refer to the "f" method (unless I am missing something).
Perhaps I was unclear -- I meant renaming the object field `o', not the record field `f'. Then you wil see that `o.f' is valid syntax for a parent method call.
You can probably also look up the syntax in the Borland manuals. As I said, that's the normal syntax for a parent method call, and AFAIK the only one besides `inherited f'.
Frank
On 19 May 2004 at 3:36, Frank Heckenbach wrote:
[...]
As you can see, the point that I made is correct. The original program was not ambiguous, and "Writeln (o.f)" in the original "procedure oo.p" could only correctly refer to the "f" field of the "o" record - it could not correctly refer to the "f" method (unless I am missing something).
Perhaps I was unclear -- I meant renaming the object field `o', not the record field `f'. Then you wil see that `o.f' is valid syntax for a parent method call.
You can probably also look up the syntax in the Borland manuals. As I said, that's the normal syntax for a parent method call, and AFAIK the only one besides `inherited f'.
Of course. I think we are speaking at cross-purposes here. But the long and short of it is that I still do not see the ambiguity in the original example. Perhaps I am just too influenced by having used BP for far too long, and that is what is blinding me to the ambiguity. IAC, if one person sees something as ambiguous, then it is ambiguous, and so perhaps code like that should generate at least a warning (except in BP/Delphi mode). For my part, I would just leave it as it is.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.bigfoot.com/~african_chief/
Prof A Olowofoyeku (The African Chief) wrote:
On 19 May 2004 at 3:36, Frank Heckenbach wrote:
[...]
As you can see, the point that I made is correct. The original program was not ambiguous, and "Writeln (o.f)" in the original "procedure oo.p" could only correctly refer to the "f" field of the "o" record - it could not correctly refer to the "f" method (unless I am missing something).
Perhaps I was unclear -- I meant renaming the object field `o', not the record field `f'. Then you wil see that `o.f' is valid syntax for a parent method call.
You can probably also look up the syntax in the Borland manuals. As I said, that's the normal syntax for a parent method call, and AFAIK the only one besides `inherited f'.
Of course. I think we are speaking at cross-purposes here. But the long and short of it is that I still do not see the ambiguity in the original example. Perhaps I am just too influenced by having used BP for far too long, and that is what is blinding me to the ambiguity.
I'm still not quite sure what your point is. So let's try it step by step:
1. Do you agree that if an object type `oo' has a parent type `o', and this parent has a method function `f', then in a method of `oo' the expression `o.f' is valid syntax for a call of that former method function?
2. Do you agree that if an object type has a field `o' which is a record which has a field `f' than within a method of this object type `o.f' is valid syntax to access this field?
3. Do you agree that the preconditions of both 1. and 2. are fulfilled in my original program?
4. If so, I suppose you'll agree that `o.f' in `oo.p' is valid syntax for both the parent method call and the subfield access. That's what an ambiguity is.
5. The fact that both BP and GPC so far choose one of the interpretations (namely 2.) does not mean that there is no ambiguity, just that it's resolved arbitrarily.
IAC, if one person sees something as ambiguous, then it is ambiguous, and so perhaps code like that should generate at least a warning (except in BP/Delphi mode). For my part, I would just leave it as it is.
Well, in fact, if it's ambiguous, the warning should be there even in BP mode (as we warn for other dangerous features), while elsewhere it may well be an error. (Since the declarations of the two `o's and `f's can be far apart in the program, it might not be easy for a programmer to notice such a problem if he ever runs into it, and he might be very confused by the field access if he's trying to call the parent method and unaware of the field name conflict. That's why I consider it a bit dangerous. BTW, I don't suppose Borland made it so intentionally -- perhaps they just overlooked this potential problem.)
BTW, I don't think many real programs would run into this problem, because object type names and field names are usually quite different. Therefore I'd almost like to forbid it entirely, but for compatibility's sake, I'll go with a warning in BP mode.
Frank
Frank Heckenbach wrote:
- Do you agree that if an object type `oo' has a parent type `o', and this parent has a method function `f', then in a method of `oo' the expression `o.f' is valid syntax for a call of that former method function?
Only if `o' is not shadowed -- in your example it is shadowed, so inside `oo' parent is not accesible. The same problem appears if you use `with' (and have just three records, one outside, a big one and a small one inside big shadowing the one outside).
By the way, I agree that systax is correct -- intentionaly method call, filed acess and qualified acess share the same syntax, but to have valid method call you need an object -- `o' needs to denote an object at the place of call. Besides your example the following should be valid:
procedure oo.foo; var o : integer; begin for o:=0 to 1 do something; end;
And inside `oo.foo' an attempt to acces `o.f' is invalid.
- Do you agree that if an object type has a field `o' which is a record which has a field `f' than within a method of this object type `o.f' is valid syntax to access this field?
The same as 1 -- yes unless shadowed.
Do you agree that the preconditions of both 1. and 2. are fulfilled in my original program?
If so, I suppose you'll agree that `o.f' in `oo.p' is valid syntax for both the parent method call and the subfield access. That's what an ambiguity is.
The fact that both BP and GPC so far choose one of the interpretations (namely 2.) does not mean that there is no ambiguity, just that it's resolved arbitrarily.
I see that you do not like shadowing -- normal Pascal rules are that names in inner scope shadow names in outsde scope. And object do introduce a new scope. Shadowing may be confusing, but it happens and scope rules are supposed to minimize confusion.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
- Do you agree that if an object type `oo' has a parent type `o', and this parent has a method function `f', then in a method of `oo' the expression `o.f' is valid syntax for a call of that former method function?
Only if `o' is not shadowed -- in your example it is shadowed, so inside `oo' parent is not accesible. The same problem appears if you use `with' (and have just three records, one outside, a big one and a small one inside big shadowing the one outside).
By the way, I agree that systax is correct -- intentionaly method call, filed acess and qualified acess share the same syntax, but to have valid method call you need an object -- `o' needs to denote an object at the place of call. Besides your example the following should be valid:
procedure oo.foo; var o : integer; begin for o:=0 to 1 do something; end;
And inside `oo.foo' an attempt to acces `o.f' is invalid.
- Do you agree that if an object type has a field `o' which is a record which has a field `f' than within a method of this object type `o.f' is valid syntax to access this field?
The same as 1 -- yes unless shadowed.
Do you agree that the preconditions of both 1. and 2. are fulfilled in my original program?
If so, I suppose you'll agree that `o.f' in `oo.p' is valid syntax for both the parent method call and the subfield access. That's what an ambiguity is.
The fact that both BP and GPC so far choose one of the interpretations (namely 2.) does not mean that there is no ambiguity, just that it's resolved arbitrarily.
I see that you do not like shadowing -- normal Pascal rules are that names in inner scope shadow names in outsde scope. And object do introduce a new scope. Shadowing may be confusing, but it happens and scope rules are supposed to minimize confusion.
I'm not sure this is like normal shadowing because both meanings of `o.f' come "into scope" at the same point, i.e. on method entry.
I think it's similar to conflicts between object field or method names with method parameter names or even method local variable names, which both GPC and BP do not allow, although syntactically they could been seen as in different scopes. Apparently there's some consensus that this is not shadowing (because they also both come into scope on method entry).
OK, it might be a gray area. I think we agree that it's at least potentially dangerous, so a warning seems in order. The question is where it will be an error. Not in BP mode, for compatibility, sure. In (future) OOE mode it must be an error. In default mode, we have the choice. I don't see quite the difference to the latter example, but if you really want only a warning by default, ok.
Frank
On 19 May 2004 at 14:12, Frank Heckenbach wrote:
[...]
- Do you agree that if an object type `oo' has a parent type `o', and this parent has a method function `f', then in a method of `oo' the expression `o.f' is valid syntax for a call of that former method function?
Yes.
- Do you agree that if an object type has a field `o' which is a record which has a field `f' than within a method of this object type `o.f' is valid syntax to access this field?
Yes.
- Do you agree that the preconditions of both 1. and 2. are fulfilled in my original program?
Yes.
- If so, I suppose you'll agree that `o.f' in `oo.p' is valid syntax for both the parent method call and the subfield access.
Yes.
That's what an ambiguity is.
Perhaps, even though it seems pretty obvious to me that it is the record field of the oo object that is in scope ....
- The fact that both BP and GPC so far choose one of the interpretations (namely 2.) does not mean that there is no ambiguity, just that it's resolved arbitrarily.
I wouldn't call it arbitrary. I would just say that it's a question of scope. However, I wouldn't press the issue either.
IAC, if one person sees something as ambiguous, then it is ambiguous, and so perhaps code like that should generate at least a warning (except in BP/Delphi mode). For my part, I would just leave it as it is.
Well, in fact, if it's ambiguous, the warning should be there even in BP mode (as we warn for other dangerous features), while elsewhere it may well be an error. (Since the declarations of the two `o's and `f's can be far apart in the program, it might not be easy for a programmer to notice such a problem if he ever runs into it, and he might be very confused by the field access if he's trying to call the parent method and unaware of the field name conflict. That's why I consider it a bit dangerous. BTW, I don't suppose Borland made it so intentionally -- perhaps they just overlooked this potential problem.)
BTW, I don't think many real programs would run into this problem, because object type names and field names are usually quite different. Therefore I'd almost like to forbid it entirely, but for compatibility's sake, I'll go with a warning in BP mode.
A warning it is then!
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
Prof A Olowofoyeku (The African Chief) wrote:
BTW, I don't think many real programs would run into this problem, because object type names and field names are usually quite different. Therefore I'd almost like to forbid it entirely, but for compatibility's sake, I'll go with a warning in BP mode.
A warning it is then!
OK, a warning in default and BP modes, and an error in ISO (i.e., OOE) mode. (fjf945*.pas)
Frank
Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
BTW, I don't think many real programs would run into this problem, because object type names and field names are usually quite different. Therefore I'd almost like to forbid it entirely, but for compatibility's sake, I'll go with a warning in BP mode.
A warning it is then!
OK, a warning in default and BP modes, and an error in ISO (i.e., OOE) mode. (fjf945*.pas)
AFAIKS in OOE mode `object' is not (or should not be) a keyword, so part of the problem vanishes. Do we implement `class' already? If yes, then it is worth checking what Delphi is doing.
Waldek Hebisch wrote:
Frank Heckenbach wrote:
Prof A Olowofoyeku (The African Chief) wrote:
BTW, I don't think many real programs would run into this problem, because object type names and field names are usually quite different. Therefore I'd almost like to forbid it entirely, but for compatibility's sake, I'll go with a warning in BP mode.
A warning it is then!
OK, a warning in default and BP modes, and an error in ISO (i.e., OOE) mode. (fjf945*.pas)
AFAIKS in OOE mode `object' is not (or should not be) a keyword, so part of the problem vanishes. Do we implement `class' already?
Not yet, but I don't see how it relates to the issue. The issue, a potential confusion between two syntactically identical things, is the same in BP and OOE object models, AFAICS, so I think it would only add to the confusion to treat it differently based on the object model.
Of course, an OOE test program will need to use `class' then, so I can't test such a program now, if you mean this.
If yes, then it is worth checking what Delphi is doing.
For now I'm treating Delphi like BP here (i.e., only a warning), but if it turns out it should be an error (Chief, did you check this already?), I can change it.
Frank
On 25 May 2004 at 19:10, Frank Heckenbach wrote:
[...]
AFAIKS in OOE mode `object' is not (or should not be) a keyword, so part of the problem vanishes. Do we implement `class' already?
Not yet, but I don't see how it relates to the issue. The issue, a potential confusion between two syntactically identical things, is the same in BP and OOE object models, AFAICS, so I think it would only add to the confusion to treat it differently based on the object model.
Of course, an OOE test program will need to use `class' then, so I can't test such a program now, if you mean this.
If yes, then it is worth checking what Delphi is doing.
For now I'm treating Delphi like BP here (i.e., only a warning), but if it turns out it should be an error (Chief, did you check this already?), I can change it.
I checked it. It is exactly the same as BP, whether using "class" or "object". Below is an example using "class". It prints "99".
program delphi_oop; type o = class function f: Integer; end;
oo = class (o) o: record f: Integer end; procedure p; end;
function o.f: Integer; begin f := 42 end;
procedure oo.p; begin WriteLn (o.f) end;
var v: oo; begin v := oo.create; v.o.f := 99; v.p end.
Best regards, The Chief -------- Prof. Abimbola A. Olowofoyeku (The African Chief) web: http://www.greatchief.plus.com/
On 17:34 25/05/04, Waldek Hebisch wrote:
OK, a warning in default and BP modes, and an error in ISO (i.e., OOE) mode. (fjf945*.pas)
AFAIKS in OOE mode `object' is not (or should not be) a keyword, so part of the problem vanishes. Do we implement `class' already? If yes, then it is worth checking what Delphi is doing.
Oh, oh... While we're on the subject of objects, may we PLEASE have private, public and protected?
Oh, wait... There's a new release. Is it in there? Hrm... I better check. By the way, who maintains the Web site?
On 17:34 25/05/04, Waldek Hebisch wrote:
OK, a warning in default and BP modes, and an error in ISO (i.e., OOE) mode. (fjf945*.pas)
AFAIKS in OOE mode `object' is not (or should not be) a keyword, so part of the problem vanishes. Do we implement `class' already? If yes, then it is worth checking what Delphi is doing.
Oh, oh... While we're on the subject of objects, may we PLEASE have private, public and protected?
Oh, wait... There's a new release. Is it in there?
It's been already in 20030830 (and possibly some releases before that, don't remember exactly).
Hrm... I better check. By the way, who maintains the Web site?
I do.
Frank
On 19:18 25/05/04, Frank Heckenbach wrote:
Oh, oh... While we're on the subject of objects, may we PLEASE have private, public and protected?
Oh, wait... There's a new release. Is it in there?
It's been already in 20030830 (and possibly some releases before that, don't remember exactly).
No, I mean actually implemented, not just being `syntatically accepted but ignored', quoting the manual.
Hrm... I better check. By the way, who maintains the Web site?
I do.
Ah, okay. I have a few ideas at the back my head; now I know who to suggest them to. :D
Neil Santos wrote:
On 19:18 25/05/04, Frank Heckenbach wrote:
Oh, oh... While we're on the subject of objects, may we PLEASE have private, public and protected?
Oh, wait... There's a new release. Is it in there?
It's been already in 20030830 (and possibly some releases before that, don't remember exactly).
No, I mean actually implemented, not just being `syntatically accepted but ignored',
I also mean this. I checked it now, it was implemented in 20030507.
quoting the manual.
OK, in one chapter of the manual it wasn't updated. I'll do this now. (If you have such reports in the future, please include a precise reference so I know what you're referring to.)
Frank