Recent

Author Topic: *Implements* keyword feature  (Read 2706 times)

denis.totoliciu

  • New Member
  • *
  • Posts: 11
*Implements* keyword feature
« on: September 29, 2019, 09:50:35 am »
Hello guys,
Here is an idea about a small, but effective extension for the usage of the implements keyword.

Say we have to deal with the following piece of source code:
Code: Pascal  [Select]
  1. {$INTERFACES CORBA}
  2.  
  3. type
  4.   IUserIntf = interface
  5.   ['{B817AB72-1F3E-4FE6-B406-C2B5A17E58A2}']
  6.     procedure ShowUser();
  7.   end;
  8.  
  9.   IExplIntf = interface
  10.   ['{B817AB72-1F3E-4FE6-B406-C2B5A17E58A2}']
  11.     procedure Explain();
  12.   end;
  13.  
  14.   { TInternalObject }
  15.  
  16.   TInternalObject = class(TObject, IUserIntf, IExplIntf)
  17.   public
  18.     procedure ShowUser();
  19.     procedure Explain();
  20.   end;
  21.  
  22.   { TUserObject }
  23.  
  24.   TUserObject = class(TObject, IUserIntf, IExplIntf)
  25.   private
  26.     FInteral: TInternalObject;
  27.   public
  28.     property Internal: TInternalObject read FInternal implements IUserIntf, IExplIntf;
  29.   end;
  30.  
  31. var
  32.   UserObj: TUserObject;
  33.  

Situation:
The programmer might be required to have the implementer Internal hidden from public view, but also have access to members of IUserIntf and IExplIntf directly through UserObj, without querying for an interface pointer, such as:
Code: Pascal  [Select]
  1. UserObj.Explain();
  2.  
This would require that the programmer copy-paste all the members from both interfaces and redirect each call to Internal.

The possible solution to avoid such copy-pastes would be:
Code: Pascal  [Select]
  1.   TUserObject = class(TObject, IUserIntf, IExplIntf)
  2.   private
  3.     FInteral: TInternalObject;
  4.   protected
  5.     property Internal: TInternalObject read FInternal implements
  6.       public IUserIntf,
  7.       protected IExplIntf;
  8.   end;
  9.  
in which those public UserIntf and protected IExplIntf would make the members of IUserIntf available as public members of TUserObject, while those of IExplIntf as protected members.

Advantages of this solution:
1. Hides the actual implementer Internal, i.e. when using composition, but the implemented interface members can be accessed directly through TUserObject.
2. Avoids manual promotion of the interface members usually done using copy-paste and a lot of boilerplate source code that, in general, it only redirects the code to the internal object.
3. Reduces a lot the time to maintain source code when the members of the interfaces change.

The compiler would do the redirection of calls as the programmer would do it manually.

Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: *Implements* keyword feature
« Reply #1 on: September 29, 2019, 10:48:22 am »
How would you go about that with {$interfaces COM}? Because of QueryInterface.... You would need to override that, so the interface really does not leak.
also related to equus asinus.

PascalDragon

  • Hero Member
  • *****
  • Posts: 735
  • Compiler Developer
Re: *Implements* keyword feature
« Reply #2 on: September 30, 2019, 09:31:40 am »
Situation:
The programmer might be required to have the implementer Internal hidden from public view, but also have access to members of IUserIntf and IExplIntf directly through UserObj, without querying for an interface pointer, such as:
Code: Pascal  [Select]
  1. UserObj.Explain();
  2.  
This would require that the programmer copy-paste all the members from both interfaces and redirect each call to Internal.
Yes and that is by design. The class implements the interface, but it does not provide the methods themselves. So it would be wrong for the class to provide the methods due to some keywords.

How would you go about that with {$interfaces COM}? Because of QueryInterface.... You would need to override that, so the interface really does not leak.
That has nothing to do with the suggested feature as the added visibility specifier wouldn't change anything there. Not to mention that reference counting in context with implements is an advanced topic anyway (there was a recent thread about that).

Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: *Implements* keyword feature
« Reply #3 on: September 30, 2019, 10:16:37 am »
How would you go about that with {$interfaces COM}? Because of QueryInterface.... You would need to override that, so the interface really does not leak.
That has nothing to do with the suggested feature as the added visibility specifier wouldn't change anything there. Not to mention that reference counting in context with implements is an advanced topic anyway (there was a recent thread about that).
I am aware of that. I pointed out that if the GUID is known, QueryInterface would still return the interface in {$INTERFACES COM} mode.  It requires extra steps over CORBA mode because of the nature of IUnknown....
Am I wrong to point that out?
« Last Edit: September 30, 2019, 10:22:20 am by Thaddy »
also related to equus asinus.

PascalDragon

  • Hero Member
  • *****
  • Posts: 735
  • Compiler Developer
Re: *Implements* keyword feature
« Reply #4 on: October 01, 2019, 09:17:09 am »
How would you go about that with {$interfaces COM}? Because of QueryInterface.... You would need to override that, so the interface really does not leak.
That has nothing to do with the suggested feature as the added visibility specifier wouldn't change anything there. Not to mention that reference counting in context with implements is an advanced topic anyway (there was a recent thread about that).
I am aware of that. I pointed out that if the GUID is known, QueryInterface would still return the interface in {$INTERFACES COM} mode.  It requires extra steps over CORBA mode because of the nature of IUnknown....
Am I wrong to point that out?
Yes, because it has nothing to do with the requested feature, it's orthogonal to it. You need to let go of always trying to correct other people's code especially if that's not the point they want to show.

Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: *Implements* keyword feature
« Reply #5 on: October 01, 2019, 09:29:41 am »
Yes, because it has nothing to do with the requested feature, it's orthogonal to it. You need to let go of always trying to correct other people's code especially if that's not the point they want to show.
I do not understand that, unless the feature is requested for {$interfaces corba} only. I am not against such a feature, merely pointed out a pitfall. That's not orthogonal or correcting code. It is adding to it.
also related to equus asinus.

denis.totoliciu

  • New Member
  • *
  • Posts: 11
Re: *Implements* keyword feature
« Reply #6 on: October 01, 2019, 10:26:18 am »
Indeed, using {$INTERFACES COM} would require a redirection of IUnknown methods of the inner object to the outer object to keep reference count in sync.

In general terms, this feature would seem to be more about a redirection mechanism for interface methods.


Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: *Implements* keyword feature
« Reply #7 on: October 01, 2019, 12:02:44 pm »
I could not have explained that better.
also related to equus asinus.

PascalDragon

  • Hero Member
  • *****
  • Posts: 735
  • Compiler Developer
Re: *Implements* keyword feature
« Reply #8 on: October 02, 2019, 09:24:28 am »
Yes, because it has nothing to do with the requested feature, it's orthogonal to it. You need to let go of always trying to correct other people's code especially if that's not the point they want to show.
I do not understand that, unless the feature is requested for {$interfaces corba} only. I am not against such a feature, merely pointed out a pitfall. That's not orthogonal or correcting code. It is adding to it.
But that pitfall exists even without that feature, due to how delegated interfaces work. That does not change with the feature. And in the case of the suggested feature it would be the compiler's task anyway to handle that correctly as the user can't control it in that case.