Recent

Author Topic: self-contained Generic functions in classes not at prime time, IE etc.  (Read 2243 times)

jamie

  • Hero Member
  • *****
  • Posts: 6550
Trying to implement generic functions inside a class only works to a limited extent and also, not cross boundaries of units.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.   TForm1 = class(TForm)
  14.     Button1: TButton;
  15.     procedure Button1Click(Sender: TObject);
  16.   public
  17.   Generic Function Test<T:Class>(A:T):Boolean;
  18.   Public
  19.    Test2:Specialize Test<TGRAPHIC>; // IE= 2015061207
  20.   end;
  21.  
  22. var
  23.   Form1: TForm1;
  24.  
  25. implementation
  26.  
  27. {$R *.lfm}
  28. procedure TForm1.Button1Click(Sender: TObject);
  29. begin
  30.  If specialize Test<TFORM>(Self) Then Beep;  //works
  31.  If Specialize Test<TButton>(Button1) Then Beep; //Works
  32. end;
  33.  
  34. Generic Function Tform1.Test<T>(A:T):Boolean;  //TForm1.Test<T:Class>(A:T):Boolean gives header does not match error.
  35. Begin
  36.   Result := A <> Nil;
  37. End;
  38. end.
  39.  
  40.  

Trying to specialize a function within the class body fails with an internal error.

Something to look at I guess.

This is Fpc 3.2.2
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 15639
  • Censorship about opinions does not belong here.
Not every T can be nil, so you are confusing the compiler. An internal error should not happen anyway, but what if you use the generics restrictions, like <T:class>?

You are making assumptions about the type of T and that is a programmer mistake.
Report the error, though, if it was not already reported.

(A class can be nil, but e.g. an integer can't)
You are basically half-way and you are aware of that issue.
« Last Edit: August 03, 2024, 05:04:17 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

bytebites

  • Hero Member
  • *****
  • Posts: 672
Trunk gives following error

Quote
unit1.pas(19,21) Error: Identifier not found "Test"
unit1.pas(19,25) Error: Error in type definition
unit1.pas(19,25) Error: Syntax error, ";" expected but "<" found

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10293
  • Debugger - SynEdit - and more
    • wiki
Not every T can be nil, so you are confusing the compiler.

Ahem, did you confuse something? T is specified to be a class, so yes, any T in this scenario can be nil.

Thaddy

  • Hero Member
  • *****
  • Posts: 15639
  • Censorship about opinions does not belong here.
Ahum,
if you edit your question after you get the clue you mean?  >:D
If I smell bad code it usually is bad code and that includes my own code.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10293
  • Debugger - SynEdit - and more
    • wiki
Ahum,
if you edit your question after you get the clue you mean?  >:D
Even at this time, that I write the reply to the quoted statement of yours, the original post (which contains the "class") has not been edited.

The forum adds a note when posts are edited, and that post does not have that note.

Your reply had been edited at some point, but that does not change what the OT had written. And it does not change what you had written (at the time I quoted you on that response)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10293
  • Debugger - SynEdit - and more
    • wiki
Just to amend, there is a grace period (either 30 seconds, or 60 seconds) where no such "last edit by" note is shown.

But since your response was 30 minutes after the post, if the post had been edited based on your reply, it would be outside that period.

jamie

  • Hero Member
  • *****
  • Posts: 6550
Does this mean I am at a loss ?  :o
The only true wisdom is knowing you know nothing

ASerge

  • Hero Member
  • *****
  • Posts: 2320
Trying to specialize a function within the class body fails with an internal error.
Something to look at I guess.
1. I think that unlike types, functions can only be specialized in the place of the call. Therefore, declaring a type as a specialized function, much less a variable, will not work.
2. Generic constraints are not allowed for implementations. This is Delphi compatible.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5672
  • Compiler Developer
Trying to specialize a function within the class body fails with an internal error.

Generic routines can only be specialized at call time, not when declaring them.

(Though an internal error should not happen :-[ So it would be nice if you'd report this with a self contained example)

jamie

  • Hero Member
  • *****
  • Posts: 6550
Re: self-contained Generic functions in classes not at prime time, IE etc.
« Reply #10 on: August 06, 2024, 01:47:10 am »
It looks like the IE has been resolved in trunk as someone has already checked and it simply reports a user code error.

However, although those methods I showed that do work here in the test, I cannot call a class generic member from another unit, the compiler only see's the name with no prototype.
   
  I assume the reason for this is due to the compiler needing to know everything while building the unit.

  This came about when I was in let's say unit1 calling a generic function within an instance of a class that lives in unit2.

  Basically, what I was trying to do was only useful as long as I stayed in the unit2 where the definition was.

  So, then my next attempt was to duplicate the same generic but with different type info being introduced but that lead to a problem of duplication errors and overloading wasn't helping.

 Thanks anyways, great work on the project btw.

The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 5672
  • Compiler Developer
Re: self-contained Generic functions in classes not at prime time, IE etc.
« Reply #11 on: August 08, 2024, 09:26:58 pm »
However, although those methods I showed that do work here in the test, I cannot call a class generic member from another unit, the compiler only see's the name with no prototype.
   
  I assume the reason for this is due to the compiler needing to know everything while building the unit.

  This came about when I was in let's say unit1 calling a generic function within an instance of a class that lives in unit2.

  Basically, what I was trying to do was only useful as long as I stayed in the unit2 where the definition was.

  So, then my next attempt was to duplicate the same generic but with different type info being introduced but that lead to a problem of duplication errors and overloading wasn't helping.

Without explicit example it's hard to imagine what you're doing and whether it could work in principle.

Khrys

  • Jr. Member
  • **
  • Posts: 90
Re: self-contained Generic functions in classes not at prime time, IE etc.
« Reply #12 on: August 09, 2024, 07:54:24 am »
I've had a similiar issue in a database-related class method for retrieving an entire column as a typed array (FPC 3.2.0,  i386-win32):

Code: Pascal  [Select][+][-]
  1. generic function TDBAdapter.ColumnAs<T>(const Name: String): specialize TArray<T>;

I'd get  Error: Compilation raised exception internally  when specializing it in another unit (like so):

Code: Pascal  [Select][+][-]
  1. PostalCodes := DB.specialize ColumnAs<Integer>('ZIP');

Eventually I found a workaround that involved extracting the method to a type helper:

Code: Pascal  [Select][+][-]
  1. TDBAdapterHelper = class helper for TDBAdapter
  2.   generic function ColumnAs<T>(const Name: String): specialize TArray<T>;
  3. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 15639
  • Censorship about opinions does not belong here.
Re: self-contained Generic functions in classes not at prime time, IE etc.
« Reply #13 on: August 09, 2024, 08:41:01 am »
That*is*neat! Never thought of that.
If I smell bad code it usually is bad code and that includes my own code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5672
  • Compiler Developer
Re: self-contained Generic functions in classes not at prime time, IE etc.
« Reply #14 on: August 11, 2024, 08:34:56 pm »
I've had a similiar issue in a database-related class method for retrieving an entire column as a typed array (FPC 3.2.0,  i386-win32):

Have you tested this works correctly in 3.2.2, 3.2.3 and/or 3.3.1?

 

TinyPortal © 2005-2018