Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2014-10

suggestion: virtual method co-variance

9 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marco van de Voort

I recently had to dive a bit into C++ again, and reconnected with a feature I liked at first sight, the C++ covariance of virtual methods (changing the return type of a overriden method to a descendant of the original type). Googling a bit it seems that some languages(C#) also seem to allow this for parameters. (not just return types)

I suddenly wondered why it was never proposed or talked about for FPC, since it seems such a nice feature. Is there something particularly wrong with it?

To a certain degree it can be emulated with generics, but that it requires a generic for every type, and must be prepared in the library code.

Reply by email

Sven Barth
to Marco van de Voort
"Marco van de Voort" wrote
I recently had to dive a bit into C++ again, and reconnected with a

feature

I liked at first sight, the C++ covariance of virtual methods (changing

the

return type of a overriden method to a descendant of the original type). Googling a bit it seems that some languages(C#) also seem to allow this

for

Show quoted text 5 lines
parameters. (not just return types) I suddenly wondered why it was never proposed or talked about for FPC, since it seems such a nice feature. Is there something particularly wrong with it?

At least at first sight there don't seem to be any real (technical) reasons to not covariance for return values. Parameters would be a different topic though...

Just so I get the idea right:

=== code begin ===

type
  TBar = class
    function Test: TObject; virtual;
  end;
  TFooBar = class(TBar)
    function Test: TStrings; override;
  end;
//...
var
  b: TBar;
  f: TFooBar;
  s: TStrings;
begin
  f := TFooBar.Create;
  b := f;
  // this would work
  s := f.Test;
  // but this not
  s := b.Test;
end.

=== code end ===

Would this be the correct equivalent in Object Pascal?

Regards,
Sven

Reply by email

Marco van de Voort
to Sven Barth

In our previous episode, Sven Barth said:

At least at first sight there don't seem to be any real (technical) reasons to not covariance for return values. Parameters would be a different topic though...

Specially since afaik we can't overload on returnvalue and require override, so there is no ambiguity.

Would this be the correct equivalent in Object Pascal?

Yes, that is about it. Mostly useful for layered frameworks, so that you can add a bit of typing on every level.

Reply by email

Jonas Maebe
to Sven Barth: feature the for At least at first sight there don't seem to be any real (technical)…
Sven Barth wrote
At least at first sight there don't seem to be any real (technical) reasons to not covariance for return values.

Delphi and/or FPC already support it to a certain extent, and the compiler contains some code for it (see
compatible_childmethod_resultdef in defcmp.pas and its use in nobj.pas). I don't know the exact scenario under which it currently works in though.

jonas

Reply by email

Flávio Etrusco
to Marco van de Voort: I recently had to dive a bit into C++ again, and reconnected with a feature I liked at…
Marco van de Voort wrote 14 lines
I recently had to dive a bit into C++ again, and reconnected with a feature I liked at first sight, the C++ covariance of virtual methods (changing the return type of a overriden method to a descendant of the original type). Googling a bit it seems that some languages(C#) also seem to allow this for parameters. (not just return types) I suddenly wondered why it was never proposed or talked about for FPC, since it seems such a nice feature. Is there something particularly wrong with it? To a certain degree it can be emulated with generics, but that it requires a generic for every type, and must be prepared in the library code.

Actually this was kind of talked ;-)
http://lists.freepascal.org/pipermail/fpc-devel/2014-February/033394.html

Best regards,
Flávio

Reply by email

Hans-Peter Diettrich
to Sven Barth: feature the for At least at first sight there don't seem to be any real (technical)…
Show quoted text 18 lines
At least at first sight there don't seem to be any real (technical) reasons to not covariance for return values. Parameters would be a different topic though... Just so I get the idea right: === code begin === type TBar = class function Test: TObject; virtual; end; TFooBar = class(TBar) function Test: TStrings; override; end; //...

I just wonder about the purpose and use of such refinement. Should the compiler relate on an more specific return type, based on the *static* type of an object reference? I'd use different names for specialized methods/properties instead.

OTOH it would be nice to have specialized lists without much coding, i.e. without writing getters (and setters) which only do typecasts of their results. Something like

type
   TBar = class
     property Test: TObject ...; virtual;
   end;
   TFooBar = class(TBar)
     property Test: TStrings; override;
   end;

Please note that this kind of override should not require to override the getters/setters, it only would enforce (static) type checks/casts, as doable at compile time.

But that smells like Generics, which already have their place in OPL...

Parameters would require different handling, because a single type mismatch would defer to the base class implementation, with possibly strange effects when this results in an bypass of the modified code in the overridden methods. That's another argument for my above suggestion, which should not only eliminate the need for overriding related methods, but should *disallow* explicit getter/setter overrides - so we were back again at generics?

DoDi

Reply by email

Sven Barth
to Jonas Maebe: Delphi and/or FPC already support it to a certain extent, and the compiler contains some…
Jonas Maebe wrote 11 lines
On 14 Oct 2014, at 14:21, Sven Barth wrote: > At least at first sight there don't seem to be any real (technical) > reasons > to not covariance for return values. Delphi and/or FPC already support it to a certain extent, and the compiler contains some code for it (see compatible_childmethod_resultdef in defcmp.pas and its use in nobj.pas). I don't know the exact scenario under which it currently works in though.

I just tested my example code (filled in the holes I left of course) and it works. So... we already have covariance support for result types! ;)

Regards,
Sven

Reply by email

Sven Barth
to Hans-Peter Diettrich: I just wonder about the purpose and use of such refinement. Should the compiler relate on…
Hans-Peter Diettrich wrote 25 lines
Sven Barth schrieb: > At least at first sight there don't seem to be any real (technical) > reasons to not covariance for return values. Parameters would be a > different topic though... > > Just so I get the idea right: > > === code begin === > > type > TBar = class > function Test: TObject; virtual; > end; > > TFooBar = class(TBar) > function Test: TStrings; override; > end; > > //... I just wonder about the purpose and use of such refinement. Should the compiler relate on an more specific return type, based on the *static* type of an object reference? I'd use different names for specialized methods/properties instead.

The compiler should take into account the type of the variable on which the method is called. See the example code which you have snipped away. ;)

And btw: the compiler even already does that! :)

Show quoted text 16 lines
OTOH it would be nice to have specialized lists without much coding, i.e. without writing getters (and setters) which only do typecasts of their results. Something like type TBar = class property Test: TObject ...; virtual; end; TFooBar = class(TBar) property Test: TStrings; override; end; Please note that this kind of override should not require to override the getters/setters, it only would enforce (static) type checks/casts, as doable at compile time.

But here the compiler can't guarantee that the Getter behind the property is really a TStrings instead of a TObject. And for the setter we would have the same problem as for methods: if I call the property using a TBar variable and pass something else than a TStrings than the inherited Setter will be called and then (to use the example of a list) a foreign object will reside in the list.

Regards,
Sven

Reply by email

Thaddy de Koning
to Marco van de Voort: I recently had to dive a bit into C++ again, and reconnected with a feature I liked at…

Isn't that exactly what is done in C++?
It is prepared in library code.

Marco van de Voort wrote 18 lines
I recently had to dive a bit into C++ again, and reconnected with a feature I liked at first sight, the C++ covariance of virtual methods (changing the return type of a overriden method to a descendant of the original type). Googling a bit it seems that some languages(C#) also seem to allow this for parameters. (not just return types) I suddenly wondered why it was never proposed or talked about for FPC, since it seems such a nice feature. Is there something particularly wrong with it? To a certain degree it can be emulated with generics, but that it requires a generic for every type, and must be prepared in the library code. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email