On 2/22/23 15:11, Sven Barth wrote:
Kostas Michalopoulos via fpc-devel <fpc-devel@lists.freepascal.org <mailto:fpc-devel@lists.freepascal.org>> schrieb am Mi., 22. Feb. 2023, 10:37:

     > Because Delphi doesn't have them and when constraints were
    implemented
     > they were implemented for Delphi compatibility.

    Can they be added? The original announcement ~13 years ago mentioned
    that those could be added at some point. "object" and "operator X"
    would
    be quite useful for me.


Some additional constraints might be added. However I have none of them planned currently and enough other things to do.


    I tried to use constraints at some point in my code but they proven too
    limited in functionality - the biggest issue i faced was that i
    couldn't
    use a specialization with a forward declared class (which is the entire
    point of the forward declaration). For example i have a generic
    collection that only works on TSerializable subclasses so i gave it
    that
    constraint, but in another unit i need to define a specialization
    for it
    before it was defined (so the class was available with a forward class
    declaration) since that specialization also needs to be used by the
    class itself. In general it seems like having constrained generic work
    with a tree structure of derived types that use the generic itself is
    impossible.

    Wouldn't storing a list of "specializations to confirm later in this
    unit" work (with later being when the class is actually defined in the
    unit)? The language already has forward declarations for a bunch of
    other things.


Forward declarations can not be used for constraints, because a specialization of the generic might be used before the forward declared type is fully defined and the compiler *must* be able to check whether the parameter in question is compatible at the time the specialization is declared.

Regards,
Sven


That is what the compiler does now, but can't it be changed to treat
constraints that use forward declarations as unconstrained (at least as
far as these forward declarations are concerned) until the moment they
are declared and validate those constraints at that point?

After all the code below does work if there is no constraint despite the
specialization being used before the forward declaration:

----
program Test;
{$MODE OBJFPC}{$H+}
type
   TProvidesFoo = class
     function Foo: Integer; virtual; abstract;
   end;

   // The following with a constraint could be instead:
   // generic TGetFoo<T: TProvidesFoo> = class
   generic TGetFoo<T> = class
     Wrap: T;
     function GetFoo: Integer;
   end;

type
   TForwardClass = class;
   // Instead of making the test here, add it to a list to check later...
   TFCHasFoo = specialize TGetFoo<TForwardClass>;

procedure DumpFoo(FCHasFoo: TFCHasFoo);
begin
   Writeln(FCHasFoo.GetFoo);
end;

function TGetFoo.GetFoo: Integer;
begin
   Result:=Wrap.Foo;
end;

type
   // ...and when this is declared check the if any of the remaining
   // checks in the list will be valid or not and remove it from the list
   TForwardClass = class(TProvidesFoo)
     function Foo: Integer; override;
   end;
   function TForwardClass.Foo: Integer;
   begin
     Result:=42;
   end;

var
   FC: TForwardClass;
   HF: TFCHasFoo;
begin
   HF:=TFCHasFoo.Create;
   HF.Wrap:=TForwardClass.Create;
   DumpFoo(HF);
   HF.Wrap.Free;
   HF.Free;
end.
----

At the end of the day this isn't a major flaw, after all if the expected
functionality wasn't there (e.g. the generic code tried to access
something the type used in the specialization didn't provide) you'd
still get a compile error anyway, though it does feel a bit like there a
hole in Free Pascal's type safety here (e.g. imagine passing a type to a
specialization that happens to have the same function call so the code
compiles but the call does something different than what you'd expect).

Kostas

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to