Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Ryan Joseph via fpc-pascal


> On Dec 27, 2019, at 1:39 PM, Adriaan van Os  wrote:
> 
> etcetera. The disadvantage of this approach is that for example a default 
> DoKeyCommand must be written three times, for TApplication, TDocument and 
> TView, where the code for TDocument.DoKeyCommand and TView.DoKeyCommand is 
> identical.
> 
> Identical code is clumsy. Therefore my wish that a helper object could 
> somehow be put in the namespace of the importing object, including the 
> ability to override the imported methods. I hope that answers you question.

This makes perfect sense to me but see what Sven says. I've encountered this 
same problem many times over the years where you want code modularity but can't 
use inheritance. There is absolutely a need for this syntax in my opinion and 
that fact Apple is holding developer conferences over it further shows this 
(https://developer.apple.com/videos/wwdc/2015/?id=408). 

The interface delegation has so much boiler plate and doesn't help with the 
namespace issues so I'm not sure why it's better then making your TQDGraphPort 
and TEventHandler records and just including them as fields in the main class. 
I think they were designed for some other pattern that I'm not familiar with 
myself. The idea of traits/aspects is similar but falls under the umbrella of 
class composition as an alternative to inheritance.

The article I posted before 
(http://machinethink.net/blog/mixins-and-traits-in-swift-2.0/) actually has 
some good use case examples including pretty charts and pictures. Swift uses 
protocol extensions to accomplish "Protocol-Oriented Programming" which would 
be the equivalent of interface helpers in Object Pascal. We can't use fields in 
interfaces or helpers though so this won't work for us I'm afraid.

program mixin;

type
  IBrain = interface
procedure Eat;
  end;

type
  IPhysics = interface
procedure Apply;
  end;

type
  TPhysicsHelper = interface helper for IPhysics
procedure Apply;
  end;

procedure TPhysicsHelper.Apply;
begin
  // ... we can't add fields in helpers or interfaces!
end;

type
  TPerson = class(IBrain, IPhysics)
  end;

begin
  // calls TPhysicsHelper.Apply via the IPhysics interface in TPerson
  person.Apply;
end.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Adriaan van Os

Ryan Joseph via fpc-pascal wrote:


Adriaan, what was your idea you had in mind when you brought this up?


Well, to give you an idea, here is an example (somewhat simplified for clarity). I am currently 
porting MacApp to 64-bit. MacApp currently has


TView = class( TEventHandler)

However, I have a TQDGraphPort class with QuickDraw emulation. For the QuickDraw emulation to work 
with current application code, TQDGraphPort methods (like TQDGraphPort.MoveTo, TQDGraphPort.LineTo, 
etcetera) have to be methods (or be in the namespace) of TView. So, I would really need


TView = class( TQDGraphPort, TEventHandler)

The TEventHandler methods have to be methods (or be in the namespace) of TView, because existing 
application code overrides the methods of TEventHandler in objects inheriting from TView. This 
mechanism needs to continue working.


Other classes also inherit from TEventHandler: TDocument, TPrintHandler and 
TApplication.

I solved this now by defining four event-handling interfaces: IIdleHandler, IMenuHandler, 
IKeyHandler, IMouseHandler, all inheriting from IEventHandler, Something like:


IEventHandler   =
  interface
  [ 'IEventHandler']

   function GetNextEventObj : TObject;
  end;

IKeyHandler =
  interface
( IEventHandler)
  [ 'IKeyHandler' ]

   function DoKeyCommand
  ( theChar : char;
theKeyCode  : Int16;
var theEventInfo: EventInfo): TCommand;

   function DoCommandKey
  ( theChar : char;
var theEventInfo: EventInfo): TCommand;
  end;

etcetera. The event-handling classes can now import the interfaces:

TApplication = class( TRefCountObj, IKeyHandler, iMenuHandler, IIdleHandler)
TDocument = class( TDBFile, IKeyHandler, iMenuHandler, IIdleHandler)
TView = class( TMacAppGraphPort, IKeyHandler, IMenuHandler, IIdleHandler, 
IMouseHandler)

etcetera. The disadvantage of this approach is that for example a default DoKeyCommand must be 
written three times, for TApplication, TDocument and TView, where the code for 
TDocument.DoKeyCommand and TView.DoKeyCommand is identical.


Identical code is clumsy. Therefore my wish that a helper object could somehow be put in the 
namespace of the importing object, including the ability to override the imported methods. I hope 
that answers you question.


I admit however that with some clever interface programming, the duplicated code can be reduced in 
the above case to a single line. As follows:


 function GetObjEventHandler
( theObj  : TObject): IEventHandler;
  var
theEventHandler   : IEventHandler;
begin
  if ( theObj <> nil) and theObj.GetInterface
   ( IEventHandler, theEventHandler)
then GetObjEventHandler   := theEventHandler
else GetObjEventHandler   := nil
end;

 function GetObjKeyHandler
( theObj  : TObject): IKeyHandler;
  var
theKeyHandler : IKeyHandler;
begin
  if ( theObj <> nil) and theObj.GetInterface
   ( IKeyHandler, theKeyHandler)
then GetObjKeyHandler := theKeyHandler
else GetObjKeyHandler := nil
end;

 function NextKeyCommand
( theObj  : TObject;
  theChar : char;
  theKeyCode  : Int16;
  var theEventInfo: EventInfo): TCommand;
  var
theEventHandler   : IEventHandler;
theKeyHandler : IKeyHandler;
begin
  theKeyHandler   := nil;
  while ( theObj <> nil) and ( theKeyHandler = nil) do
  begin
theEventHandler   := GetObjEventHandler
  ( theObj);
if theEventHandler = nil
  then theObj := nil
  else theObj := theEventHandler.GetNextEventObj;
theKeyHandler := GetObjKeyHandler
  ( theObj)
  end;
  if theKeyHandler <> nil
then NextKeyCommand   := theKeyHandler.DoKeyCommand
   ( theChar, theKeyCode, theEventInfo)
else NextKeyCommand   := nil
end;

 function TDocument.DoKeyCommand
( theChar : char;
  theKeyCode  : Int16;
  var theEventInfo: EventInfo): TCommand;
begin
  DoKeyCommand:= NextKeyCommand
( self, theChar, theKeyCode, theEventInfo)
end;

 function TView.DoKeyCommand
( theChar : char;
  theKeyCode  : Int16;
  var theEventInfo: EventInfo): TCommand;
begin
  DoKeyCommand:= 

Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Ryan Joseph via fpc-pascal


> On Dec 27, 2019, at 10:29 AM, Ryan Joseph  wrote:
> 
> It's really just about the namespace and avoiding deeply nested this.that.do 
> kind of syntax. We could accomplish this using just plain records, no need to 
> even get involved with the complicated interface syntax. According to the 
> wiki https://en.wikipedia.org/wiki/Trait_(computer_programming) lots of other 
> languages are having this need to build component like systems and want a 
> syntax that formalizes the concept.

I also wanted to mention this article which talks about default interface 
implementation (protocols in Swift) which exists in at least C# and Swift. Is 
that a viable route perhaps since we already have interfaces?

http://machinethink.net/blog/mixins-and-traits-in-swift-2.0/

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Ryan Joseph via fpc-pascal


> On Dec 27, 2019, at 10:01 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> To be clear: with declaration time I mean when the type is written (" = class 
> ... end") versus creation time (either "var x: tmyclass" or "x := tmyclass 
> .create"). The difference would be that the user of the class would decide 
> what is supported instead of the declarer of the class. Adding something at 
> creation time would of course require that the functionality can only be 
> accessed dynamically (similar to GetInterface, though like that it can be 
> hidden behind e.g. the "as" operator) and that the functionality needs to be 
> independant of the existing class.

Got it.

> 
>> - Importing fields/properties is easy because we can just add symbols to the 
>> symbol table but I'm not sure what it means in terms of the compiler to 
>> import a method from another class. The method needs to be cloned or perhaps 
>> synthesized as I've seen the term used in the compiler.  Because the traits 
>> aren't actually allocated like a class or record we need to copy the code 
>> out into the class that uses them.
> 
> You don't need to do any copying of the functions. You need to partition the 
> instance so that fields that belong to a specific trait are grouped together 
> and then you pass an adjusted self pointer to the trait's methods so that 
> this only sees accesses its own fields (and properties are the same as 
> methods or field access: use the correct Self part).

Can you explain or gives some function names of where/how the importation of 
fields/methods happens for inheritance? For fields I'm seeing that the struct 
data size expands when a super class is parsed and then in searchsym_in_class 
the correct symbol is found but I don't know what happens after that. The data 
must be copied at some point but I don't know when.

For method calling I think you're saying we merely pass a different self 
pointer depending on which class in the hierarchy makes the call.

> 
> What I'm still missing however is a real use case. What you have presented as 
> an example can just as easily be done with the existing delegates. And just 
> to avoid having to cast the instance to the interface is in my opinion not 
> enough reason for a new feature.

It's really just about the namespace and avoiding deeply nested this.that.do 
kind of syntax. We could accomplish this using just plain records, no need to 
even get involved with the complicated interface syntax. According to the wiki 
https://en.wikipedia.org/wiki/Trait_(computer_programming) lots of other 
languages are having this need to build component like systems and want a 
syntax that formalizes the concept.

Adriaan, what was your idea you had in mind when you brought this up?



program test;

type
  TBrain = record
procedure Eat;
procedure Fight;
  end;

type
  TPhysics = record
x, y, z: float;
procedure Apply;
  end;

type
  TPerson = class
physics: TPhysics;
brain: TBrain;
  end;

var
  p: TPerson;
begin
  p.brain.DoThis;
  p.physics.x += 1;
end.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Sven Barth via fpc-pascal

Am 26.12.2019 um 20:32 schrieb Ryan Joseph via fpc-pascal:



On Dec 24, 2019, at 1:16 AM, Sven Barth via fpc-pascal 
 wrote:

Basically, yes, though of course syntax, implementation and behavior need to be 
nicely defined first. For example there is the difference whether something is 
added at declaration time of the class or the creation time of the class 
(though that might be the difference between mixins and aspect oriented 
programming).


I hope you're all having a wonderful Christmas season. :)

Some more thoughts on this:

- My initial thought was that importing would happen at definition time simply 
because I don't know what the difference would be to import at declaration time.


To be clear: with declaration time I mean when the type is written (" = 
class ... end") versus creation time (either "var x: tmyclass" or "x := 
tmyclass .create"). The difference would be that the user of the class 
would decide what is supported instead of the declarer of the class. 
Adding something at creation time would of course require that the 
functionality can only be accessed dynamically (similar to GetInterface, 
though like that it can be hidden behind e.g. the "as" operator) and 
that the functionality needs to be independant of the existing class.



- Importing fields/properties is easy because we can just add symbols to the 
symbol table but I'm not sure what it means in terms of the compiler to import 
a method from another class. The method needs to be cloned or perhaps 
synthesized as I've seen the term used in the compiler.  Because the traits 
aren't actually allocated like a class or record we need to copy the code out 
into the class that uses them.


You don't need to do any copying of the functions. You need to partition 
the instance so that fields that belong to a specific trait are grouped 
together and then you pass an adjusted self pointer to the trait's 
methods so that this only sees accesses its own fields (and properties 
are the same as methods or field access: use the correct Self part).


What I'm still missing however is a real use case. What you have 
presented as an example can just as easily be done with the existing 
delegates. And just to avoid having to cast the instance to the 
interface is in my opinion not enough reason for a new feature.


Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Ryan Joseph via fpc-pascal


> On Dec 27, 2019, at 8:21 AM, Adriaan van Os  wrote:
> 
> The code of a "mixin" or "trait" or "delegate" (or whatever 
> implementing-something) can be referenced and it can put virtually into the 
> namespace of an object. The one thing you cannot do however, is copy the 
> code, because then the basic problem of mutiple-inheritance pops-up again --- 
> which is what route for virtual methods to take in a multiple-inheritance 
> "tree" that is no longer a tree but a graph. For the same reason, methods 
> overriding methods imported from the implementing-something will still 
> actually override the methods in the implementing-something, even if they 
> virtually seem to be in the namespace of the importing object.

Should the traits/aspects even be overridable then? If they are it sounds like 
they need to be implemented the same as inheritance and this would basically 
just make them a different syntax for multiple inheritance. I don't think 
that's what Sven had it mind and if he did why not just do proper multiple 
inheritance using the existing syntax that interfaces uses?

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-27 Thread Adriaan van Os

Ryan Joseph via fpc-pascal wrote:


- Importing fields/properties is easy because we can just add symbols to the 
symbol table but I'm not sure what it means in terms of the compiler to import 
a method from another class. The method needs to be cloned or perhaps 
synthesized as I've seen the term used in the compiler.  Because the traits 
aren't actually allocated like a class or record we need to copy the code out 
into the class that uses them.


The code of a "mixin" or "trait" or "delegate" (or whatever implementing-something) can be 
referenced and it can put virtually into the namespace of an object. The one thing you cannot do 
however, is copy the code, because then the basic problem of mutiple-inheritance pops-up again --- 
which is what route for virtual methods to take in a multiple-inheritance "tree" that is no longer 
a tree but a graph. For the same reason, methods overriding methods imported from the 
implementing-something will still actually override the methods in the implementing-something, even 
if they virtually seem to be in the namespace of the importing object.


Regards,

Adriaan van Os

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-26 Thread Ryan Joseph via fpc-pascal


> On Dec 24, 2019, at 1:16 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> Basically, yes, though of course syntax, implementation and behavior need to 
> be nicely defined first. For example there is the difference whether 
> something is added at declaration time of the class or the creation time of 
> the class (though that might be the difference between mixins and aspect 
> oriented programming). 
> 

I hope you're all having a wonderful Christmas season. :)

Some more thoughts on this:

- My initial thought was that importing would happen at definition time simply 
because I don't know what the difference would be to import at declaration time.

- Importing fields/properties is easy because we can just add symbols to the 
symbol table but I'm not sure what it means in terms of the compiler to import 
a method from another class. The method needs to be cloned or perhaps 
synthesized as I've seen the term used in the compiler.  Because the traits 
aren't actually allocated like a class or record we need to copy the code out 
into the class that uses them.

program mixin;

type
  TBrain = trait
procedure DoStuff; virtual;
  end;

procedure TBrain.DoStuff;
begin
  writeln('do something');
end;

type
  TBase = class
use TBrain;
  end;

// TBase.DoStuff is synthesized from TBrain.DoStuff
procedure TBase.DoStuff;
begin
  writeln('do something');
end;

begin
end.


- What about generics? Looks complicated and dubious so maybe that could be a 
feature added later simply in the interest of taking things in small steps.

program mixin;

type
  generic TBrain = trait
procedure DoStuff(param: T); virtual;
  end;

type
  generic TBase = class
private
  use specialize TBrain;
public
  procedure DoStuff(param: T); override;
  end;

begin
end.

- Is overriding allowed? This presents a dilemma because we need to synthesize 
the method from the trait (or whatever they will be called) and allow an 
additional method which can call "inherited" and get the super method in the 
same class. This would be new functionally for the inherited keyword since the 
overriding is happening in the same class.

program mixin;

type
  TBrain = trait
procedure DoStuff; virtual;
  end;

procedure TBrain.DoStuff;
begin
  writeln('do something');
end;

type
  TBase = class
use TBrain;
procedure DoStuff; override;
  end;

// TBase.TBrain_DoStuff is synthesized from TBrain.DoStuff
// and renamed to prevent name collisions
procedure TBase.TBrain_DoStuff;
begin
  writeln('do something');
end;

procedure TBase.DoStuff;
begin
  // inherited calls TBase.TBrain_DoStuff
  inherited;
  writeln('do more stuff');
end;

begin
end.




Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-24 Thread Sven Barth via fpc-pascal
Ryan Joseph via fpc-pascal  schrieb am
Di., 24. Dez. 2019, 02:47:

>
>
> > On Dec 23, 2019, at 7:57 PM, Ryan Joseph  wrote:
> >
> > I never heard of "mixin" before but I'll study the wiki.
> >
> > I assume that the compiler team has decided multiple inheritance is a
> bad idea correct? Personally I don't have enough experience to know but I
> see there is a need to delegate work between classes and share a common
> namespace. I'm happy with any way to achieve that.
>
> Here's what I got from reading. I saw this concept of "trait" from PHP
> (didn't even know it existed until now) and I think it would look like this
> in Pascal. From what I gather the "trait" is new kind of object that merely
> is injected into an object but it can't itself be allocated or assigned.
> Does that sound like what you had in mind?
>

Basically, yes, though of course syntax, implementation and behavior need
to be nicely defined first. For example there is the difference whether
something is added at declaration time of the class or the creation time of
the class (though that might be the difference between mixins and aspect
oriented programming).

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-23 Thread Ryan Joseph via fpc-pascal


> On Dec 23, 2019, at 7:57 PM, Ryan Joseph  wrote:
> 
> I never heard of "mixin" before but I'll study the wiki. 
> 
> I assume that the compiler team has decided multiple inheritance is a bad 
> idea correct? Personally I don't have enough experience to know but I see 
> there is a need to delegate work between classes and share a common 
> namespace. I'm happy with any way to achieve that.

Here's what I got from reading. I saw this concept of "trait" from PHP (didn't 
even know it existed until now) and I think it would look like this in Pascal. 
From what I gather the "trait" is new kind of object that merely is injected 
into an object but it can't itself be allocated or assigned. Does that sound 
like what you had in mind?



program mixin;

type
  TBrain = trait
procedure Eat;
procedure Fight;
  end;

type
  TPhysics = trait
x, y, z: float;
procedure Apply;
  end;

type
  TBase = class
use TPhysics, TRendering, TBrain;
  end;

begin
end.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-23 Thread Ryan Joseph via fpc-pascal


> On Dec 23, 2019, at 2:02 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> What might be more interesting in this context than multiple inheritance is 
> the concept of aspects (aka aspect oriented programming though you might also 
> want to look for "mixin"; there's an old thread about that: 
> https://lists.freepascal.org/fpc-pascal/2009-December/023815.html). If we 
> could find an agreeable syntax and implementation for that then we'd be 
> potentially inclined to include that as a new feature as there had been 
> experiments for that in the past. 
> 

I never heard of "mixin" before but I'll study the wiki. 

I assume that the compiler team has decided multiple inheritance is a bad idea 
correct? Personally I don't have enough experience to know but I see there is a 
need to delegate work between classes and share a common namespace. I'm happy 
with any way to achieve that.

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-22 Thread Sven Barth via fpc-pascal
Adriaan van Os  schrieb am So., 22. Dez. 2019, 20:53:

> I have always wondered why hierarchies in object-oriented programming are
> idolized, where in the
> database world hierarchical databases are something of the past and
> everything is relational there
> now .
>

Because in object oriented programming languages one tends to try to work
with the common denominator to ease up the dependencies between the
concrete implementations. E.g. the LCL relies on TComponent and TControl,
it does not need to know that there is a TMyWhateverControl. I even miss
inheritance in databases as well as that would make the tables simpler.

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-22 Thread Sven Barth via fpc-pascal
Ryan Joseph via fpc-pascal 
>
> > On Dec 22, 2019, at 5:26 AM, Sven Barth via fpc-pascal <
> fpc-pascal@lists.freepascal.org> wrote:
> >
> > You don't seem to understand what implementing an interface means in
> Object Pascal. It means that a class can be cast to an interface. It does
> *not* mean that the interface's methods are available from that class.
>
> I guess I'm not seeing the design pattern which they was invented for and
> I've never come across it in my own work. Not against the idea in any way
> however.
>
> My mind went in the same direction as Adriaan's did when I saw
> "implements" I thought that one class could be built from many smaller
> classes but share the same namespace (like in multiple inheritance or
> entity/component designs). If a class implements an interface via a
> delegate then I would expect this to function the same as inheritance, i.e.
> the namespaces are merged and share functions. Doesn't that make sense?
>

It does make sense, but not in the context of interfaces. They are not
there to provide implementations, but to provide a known API to the user.



> Maybe what I mean to say is that there's a need for a delegation syntax
> that functions like multiple inheritance and avoids the traps of deeply
> nested single inheritance hierarchies. Does anyone else agree?
>

What might be more interesting in this context than multiple inheritance is
the concept of aspects (aka aspect oriented programming though you might
also want to look for "mixin"; there's an old thread about that:
https://lists.freepascal.org/fpc-pascal/2009-December/023815.html). If we
could find an agreeable syntax and implementation for that then we'd be
potentially inclined to include that as a new feature as there had been
experiments for that in the past.

Regards,
Sven

>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-22 Thread Adriaan van Os

Ryan Joseph via fpc-pascal wrote:



I guess I'm not seeing the design pattern which they was invented for and I've 
never come across it in my own work. Not against the idea in any way however.

My mind went in the same direction as Adriaan's did when I saw "implements" I 
thought that one class could be built from many smaller classes but share the same 
namespace (like in multiple inheritance or entity/component designs). If a class 
implements an interface via a delegate then I would expect this to function the same as 
inheritance, i.e. the namespaces are merged and share functions. Doesn't that make sense?

Maybe what I mean to say is that there's a need for a delegation syntax that functions like multiple inheritance and avoids the traps of deeply nested single inheritance hierarchies. Does anyone else agree? 


Compare this with relational databases where the columns of related, say "delegate", tables can be 
put side-to-side with columns of the main table in so-called database views 
.


I have always wondered why hierarchies in object-oriented programming are idolized, where in the 
database world hierarchical databases are something of the past and everything is relational there 
now .


Regards,

Adriaan van Os

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-22 Thread Ryan Joseph via fpc-pascal


> On Dec 22, 2019, at 5:26 AM, Sven Barth via fpc-pascal 
>  wrote:
> 
> You don't seem to understand what implementing an interface means in Object 
> Pascal. It means that a class can be cast to an interface. It does *not* mean 
> that the interface's methods are available from that class.

I guess I'm not seeing the design pattern which they was invented for and I've 
never come across it in my own work. Not against the idea in any way however.

My mind went in the same direction as Adriaan's did when I saw "implements" I 
thought that one class could be built from many smaller classes but share the 
same namespace (like in multiple inheritance or entity/component designs). If a 
class implements an interface via a delegate then I would expect this to 
function the same as inheritance, i.e. the namespaces are merged and share 
functions. Doesn't that make sense?

Maybe what I mean to say is that there's a need for a delegation syntax that 
functions like multiple inheritance and avoids the traps of deeply nested 
single inheritance hierarchies. Does anyone else agree? 

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-22 Thread Sven Barth via fpc-pascal

Am 22.12.2019 um 04:44 schrieb Ryan Joseph via fpc-pascal:



On Dec 21, 2019, at 10:49 AM, Adriaan van Os  wrote:

I had hoped that procedure IMyInterface2.P2 would now be visible as a method of 
TMyClass. This would be quite helpful in implementing multiple-inheritance. But 
no, the implements specifier completely hides it. I assume this has been 
discussed before.

That's exactly what I was ranting about some months back with the idea of "default 
properties". I would expect that syntax to pull the methods names into the current 
namespace and this would be very helpful.

It's by design as Sven pointed out but this makes no sense whatsoever to me. If 
the compiler team agrees I will personally make a mode switch or whatever is 
permitted to accomplish this. :)

Vetoed.

You don't seem to understand what implementing an interface means in 
Object Pascal. It means that a class can be cast to an interface. It 
does *not* mean that the interface's methods are available from that class.


Take this:

=== code begin ===

program tintftest;

{$mode objfpc}
{$interfaces corba}

type
  ITest = interface
    procedure Test;
  end;

  TTest = class(TObject, ITest)
  strict private
    procedure Test;
  end;

procedure TTest.Test;
begin
end;

var
  t: TTest;
  i: ITest;
begin
  t := TTest.Create;
  //t.Test; // this does not compile
  i := t;
  i.Test;
end.

=== code end ===

An implementor can decide to have the interface's methods not accessible 
from outside.


Or take this:

=== code begin ===

program tintftest;

{$mode objfpc}
{$interfaces corba}

type
  ITest = interface
    procedure Test;
  end;

  TTest = class(TObject, ITest)
  public
    procedure ITest.Test = IntfTest;
    procedure IntfTest;
    procedure Test;
  end;

procedure TTest.Test;
begin
  Writeln('Test');
end;

procedure TTest.IntfTest;
begin
  Writeln('IntfTest');
end;

var
  t: TTest;
  i: ITest;
begin
  t := TTest.Create;
  t.Test;
  i := t;
  i.Test;
end.

=== code end ===

This will output

=== output begin ===

PS C:\fpc\git> .\testoutput\tintftest
Test
IntfTest

=== output end ===

So while TTest implements the ITest interface it's methods are not the 
same as the interface's.


Similar for delegates. The delegation property can be private (mostly 
protected though to avoid a "unused private symbol" warning), so you 
only get access to the delegated field by casting the class to the 
implemented interface.


Your proposal to hoist the methods of a delegated interface would 
conflict with this. Or it would require an alternative syntax to give 
the implementor the necessary control of the visibility.


TL;DR: in Object Pascal a class implementing an interface can be cast to 
that interface, but it does not need to present the methods of said 
interface.


Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-21 Thread Ryan Joseph via fpc-pascal


> On Dec 21, 2019, at 10:49 AM, Adriaan van Os  wrote:
> 
> I had hoped that procedure IMyInterface2.P2 would now be visible as a method 
> of TMyClass. This would be quite helpful in implementing 
> multiple-inheritance. But no, the implements specifier completely hides it. I 
> assume this has been discussed before.

That's exactly what I was ranting about some months back with the idea of 
"default properties". I would expect that syntax to pull the methods names into 
the current namespace and this would be very helpful.

It's by design as Sven pointed out but this makes no sense whatsoever to me. If 
the compiler team agrees I will personally make a mode switch or whatever is 
permitted to accomplish this. :)

Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Interface delegates and the implements property specifier

2019-12-21 Thread Sven Barth via fpc-pascal

Am 21.12.2019 um 16:49 schrieb Adriaan van Os:
Section 7.4 Interface delegation 
 
of the FPC Language Reference Guide discusses interface delegates and 
the implements property specifier.


For example

$interfaces corba}
type
  IMyInterface = interface
    procedure P1;
  end;

  IMyInterface2 = interface
    procedure P2;
  end;

  TMyClass = class(TInterfacedObject,
   IMyInterface, IMyInterface2)
    FI2 : IMyInterface2;
  protected
    procedure IMyInterface.P1 = MyP1;
    procedure MyP1;
  public
    property MyInterface: IMyInterface2
   read FI2 implements IMyInterface2;

I had hoped that procedure IMyInterface2.P2 would now be visible as a 
method of TMyClass. This would be quite helpful in implementing 
multiple-inheritance. But no, the implements specifier completely 
hides it. I assume this has been discussed before.


Yes, this is by design, because the idea of the interface delegation is 
that the class can be cast to the designated interface type (thus 
supporting the interface) and then be used as if it directly implemented 
the interface.




However (after adding an identifying string to IMyInterface and 
IMyInterface2), TObject.GetInterface( IMyInterface2) fails for the FI2 
delegate but succeeds for an object of TMyClass. This seems 
contradictory, as IMyInterface2 is really part of the F12 delegate, 
not of TMyClass.


I don't get what you're saying here. Would you please provide code that 
illustrates your problem?


Regards,
Sven
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] Interface delegates and the implements property specifier

2019-12-21 Thread Adriaan van Os
Section 7.4 Interface delegation 
 of the FPC Language 
Reference Guide discusses interface delegates and the implements property specifier.


For example

$interfaces corba}
type
  IMyInterface = interface
procedure P1;
  end;

  IMyInterface2 = interface
procedure P2;
  end;

  TMyClass = class(TInterfacedObject,
   IMyInterface, IMyInterface2)
FI2 : IMyInterface2;
  protected
procedure IMyInterface.P1 = MyP1;
procedure MyP1;
  public
property MyInterface: IMyInterface2
   read FI2 implements IMyInterface2;

I had hoped that procedure IMyInterface2.P2 would now be visible as a method of TMyClass. This 
would be quite helpful in implementing multiple-inheritance. But no, the implements specifier 
completely hides it. I assume this has been discussed before.


However (after adding an identifying string to IMyInterface and IMyInterface2), 
TObject.GetInterface( IMyInterface2) fails for the FI2 delegate but succeeds for an object of 
TMyClass. This seems contradictory, as IMyInterface2 is really part of the F12 delegate, not of 
TMyClass.


Regards,

Adriaan van Os

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal