Finally some movement is happening on implicit function specialization and I'm 
almost finished now except some questions about precedence have been raised 
again. Initially I thought we decided on non-generic functions taking 
precedence in the case of *any* name collisions (the original thread 
https://lists.freepascal.org/pipermail/fpc-pascal/2018-December/055225.html) 
but Sven is saying now that this isn't the case (see the remarks on the bug 
report https://bugs.freepascal.org/view.php?id=35261). I'm asking this here not 
to go over Svens head but in hopes to get some answers quicker (it can take us 
weeks sometimes to round trip even simple questions).

Currently what I implemented is that in the case below non-generic Test() will 
take precedence even though Test<T> could be specialized and indeed even comes 
after.  My questions:

1) What is required for Delphi compatibility? I never used Delphi and I thought 
we decided this initially for Delphi compatibility. Of course we can make a 
Delphi mode only option if we need to.

2) Svens final remarks on the bug tracker are "Right now your code will pick 
the existing String overload even if specializing the generic might be the 
better choice. If the user really wants the String one (or if the specializing 
the generic does not work) the user can still force the String overload by 
casting the parameter to a String.". I'm confused about this because 
Test(String) and Test<String> are both identical and thus I don't see what is 
the "better choice".

Personally I feel like we should fallback to the non-generic function as a way 
to resolve ambiguity but I can also see why Test<T> should take precedence 
simply because it comes after Test().

================

{$mode objfpc}{$H+}
{$modeswitch IMPLICITFUNCTIONSPECIALIZATION}

function Test(const aStr: String): LongInt;
begin
  Result := 1;
end;

generic function Test<T>(aT: T): LongInt;
begin
  Result := 2;
end;

begin
  Writeln(Test('Hello World'));
end.

================

And just to be clear even if the name is the same but parameters do not match 
the generic function will be selected. For example below Test<T> will be 
specialized because Test() doesn't have a compatible signature.

================

function Test(const aStr: String): LongInt;
begin
  Result := 1;
end;

generic function Test<T>(aT: T; aInt: Integer): LongInt;
begin
  Result := 2;
end;

begin
  Writeln(Test('Hello World', 1));    // prints "2"
end.

================

Regards,
        Ryan Joseph

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

Reply via email to