Recent

Author Topic: Generics - correct syntax  (Read 2758 times)

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Generics - correct syntax
« on: April 19, 2024, 11:47:34 pm »
Hi,

I'm trying this Vulkan demo: https://github.com/james-mcjohnson/VulkanLibraryForFreePascal

Why this does not work (unit vulkan_vk_xml_to_pas.pas)?
Code: Pascal  [Select][+][-]
  1.   generic TCreateChildList<T> = class(specialize TFPGObjectList<T>)

Note that it is code from 2017 and {$mode objfpc}.

IMO it should be
Code: Pascal  [Select][+][-]
  1.   generic TCreateChildList<T: class> = class(specialize TFPGObjectList<T>)

but then it crashes later with "vulkan_vk_xml_to_pas.pas(1869,10) Error: Identifier idents no member "FLevel"".
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #1 on: April 19, 2024, 11:58:38 pm »
I don't see any constructors ?

I am sure the object list requires them if anything..

But then again, I could have missed something?
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #2 on: April 20, 2024, 12:09:16 am »
Code: Pascal  [Select][+][-]
  1.   generic TCreateChildList<T> = class(specialize TFPGObjectList<T>);
  2.   TmyType = Specialize TcreateChildList<Tbutton>;
  3. var
  4.   Form1: TForm1;
  5.   Test:TmyType;
  6.  
  7. implementation
  8.  
  9. {$R *.lfm}
  10.  
  11. { TForm1 }
  12.  
  13. procedure TForm1.Button1Click(Sender: TObject);
  14. begin
  15.   Test := TmyType.Create(True);
  16.   //...
  17.   Test.free;
  18. end;                                          
  19.  

Works for me.
The only true wisdom is knowing you know nothing

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Generics - correct syntax
« Reply #3 on: April 20, 2024, 01:57:40 am »
It's this (line 58 of https://github.com/james-mcjohnson/VulkanLibraryForFreePascal/blob/master/vulkan_vk_xml_to_pas.pas)

Code: Pascal  [Select][+][-]
  1. { TCreateChildList }
  2.  
  3.   generic TCreateChildList<T> = class(specialize TFPGObjectList<T>)
  4.     function CreateChild(Level: Integer = -1): T;
  5.     function GetListing(IncludeLastDelimiter: Boolean; aDelimiter: String; NoCRLF: Boolean = False): String;
  6.     function FindIdentifier(aIdentifier: String): T;
  7.     function FindIdentifierIndex(aIdentifier: String): Integer;
  8.     procedure MoveIdentifierBefore(aIdentifier1, aIdentifier2: String);
  9.   end;
  10.  
  11.   TComment = class;
  12.   TExtension = class;
  13.  
  14.   { TListObj }
  15.  
  16.   TListObj = class
  17.     private
  18.       FLevel: Integer;
  19.     public
  20.       Identifier: String;
  21.       CommentInternal: String;
  22.       AcceptLateComment: Boolean;
  23.       PreComment, PostComment: TComment;
  24.       function GetPreComment: String;
  25.       function GetPostComment(curlen: Integer): String;
  26.       function SpaceOutPostComment(curlen: Integer; CommentText: String): String;
  27.       function GetListing(Delimiter: String; NoCRLF: Boolean = False): String;
  28.       function GetInfo(Delimiter: String): String; virtual;
  29.       function GetExtraInfo: String; virtual;
  30.   end;
  31.  
  32.   TPointerDepth = class(TListObj)
  33.     NeededPointerDepth: Integer;
  34.   end;
  35.   TPointerDepthList = specialize TCreateChildList<TPointerDepth>;

EDIT: @jamie
  Your code  also needs
Code: Pascal  [Select][+][-]
  1. generic TCreateChildList<T: class> = class(specialize TFPGObjectList<T>);
with FPC 3.3.1
« Last Edit: April 20, 2024, 02:07:20 am by Blaazen »
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #4 on: April 20, 2024, 03:51:21 pm »
I would need to download that complete project and compile it however; you could be running into a case where the compiler was tightened up which before that allowed private fields to be visible in other units and now they are not.

 private fields are not suppose to be visible in other units as you know.

 It could be an oversite with the generics, maybe.

 Have you tried a lower version compiler, like the 3.2.x ?
The only true wisdom is knowing you know nothing

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Generics - correct syntax
« Reply #5 on: April 20, 2024, 05:07:02 pm »
Changing field to protected or public does not work. I tried both 3.2.2 and the newest 3.3.1.

I wanted to test Vulkan (something simple) but none of the listed repos works: https://wiki.freepascal.org/Vulkan

The PasVulkan from BeRo1985 is active but its a huge 5GB repo and you need to download another 4 repos and still it doesn't compile.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #6 on: April 20, 2024, 07:05:12 pm »
After long studying, I would say that you have found a bug that somehow wasn't there at the time of that distro or a custom FPC was used.

If you change those items to PUBLIC or use a property access in the TListObj, it works. But you shouldn't need to do that.

It appears the compiler thinks the type assemblies are taking place in remote units and thus the PRIVATE is blocking it.

Maybe there is compiler switch that is missing?



The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #7 on: April 21, 2024, 02:48:38 am »
With FPC 3.0.4, if I comment out the Private in the TlistObj,  I get past that, it compiles.

There is another one that has "fused" doing the same thing there also fixes it.

But that is using fpc 3.0.4.

 With 3.2.2 and I assume up!, not even bringing it to public will make it work...


At this point I would say that FPC 3.2.x and up is very limited with Generics of that type.

If you change the TFpgObjectList to a TFpgList, it then compiles with 3.2.2, but you don't have the extra options for ownership.

For some reason, TFPgObjectList has a  TOBJECT requirement for 3.2.2 whereas, 3.0.4 does not.

 This is causing all sorts of issues because the compiler is filtering out the Private access, assuming because a TOBJECT does not  = CLASS verbose wise. That is all I can come up with atm.


The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #8 on: April 21, 2024, 03:18:15 am »
OK: Update.

it seems with 3.0.4 I need to unhide it regardless and it works.

With 3.2.2 and up.

You need to locally implement the TFPGObjectList from the TfpgList and that works, no need to fully implement it, just use the Fgplist members.


have fun.
The only true wisdom is knowing you know nothing

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Generics - correct syntax
« Reply #9 on: April 21, 2024, 07:12:34 pm »
I decided to write it from scratch. Original author uses several generic lists (and probably a treeview) to generate include files. To generate include files is great idea but IMO it can be done directly from parsed XML without any additional data structure.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

PascalDragon

  • Hero Member
  • *****
  • Posts: 5508
  • Compiler Developer
Re: Generics - correct syntax
« Reply #10 on: April 21, 2024, 09:08:42 pm »
IMO it should be
Code: Pascal  [Select][+][-]
  1.   generic TCreateChildList<T: class> = class(specialize TFPGObjectList<T>)

Correct. Nowadways TFPGObjectList<> requires the type parameter to be a class and thus generics that inherit from it need to declare that as well.

but then it crashes later with "vulkan_vk_xml_to_pas.pas(1869,10) Error: Identifier idents no member "FLevel"".

That is not a crash, that is simply the compiler telling you an error. That's a difference.

Also the compiler was recently adjusted so that accessing private/protected fields works according to the generic and not the specialization, so that might be an issue in that code.

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #11 on: April 21, 2024, 09:54:11 pm »
@Pascal

 The definition of what I have in the FPC 3.2.2 is this
Code: Pascal  [Select][+][-]
  1.  generic TCreateChildList<T: TObject> = class(specialize TFPGObjectList<T>)
  2.  
                                      ^^^^^^^^^
AS you can see, it does not work correctly this way. Doing so hides the field and I can only assume is due to the fact that
the Class that is being introduced as the type is a CLASS and here we have  a TOBJECT for which the version compiler I am using does not seem to understand.

So I guess It would be fine if it was CLASS, but it isn't and I get the same exact behavior.

If I create a local implementation of what is expected it works.

Have good day.


The only true wisdom is knowing you know nothing

VisualLab

  • Sr. Member
  • ****
  • Posts: 355
Re: Generics - correct syntax
« Reply #12 on: April 22, 2024, 10:02:24 am »
Code: Pascal  [Select][+][-]
  1.  generic TCreateChildList<T: TObject> = class(specialize TFPGObjectList<T>)
  2.  

When and in what combinations can the keywords generic and specialize be used together, and when should they be used separately? Is there documentation detailing the use/application of these keywords when defining and using generic types in your code? So far, I have used the Delphi mode (most often) or, to a limited extent, the ObjFpc mode with the above-mentioned keywords. I have the impression that at this point the readability and clarity of Object Pascal is approaching the proverbial "readability and clarity" of some C++ mechanisms (that is, the mechanisms are useful, but their writing in the code is unclear and ill-considered, resulting in the impression of gibberish <- note in brackets applies to C++).

jamie

  • Hero Member
  • *****
  • Posts: 6217
Re: Generics - correct syntax
« Reply #13 on: April 23, 2024, 12:11:50 am »
I don't know what to tell you?

"Generic" is basically the same as a "Template"

 ObjFpc mode requires the "Specialize" keyword when it's time to assemble a type from a generic template.

  Delphi mode just automatically does that if none of that assembly exist with the given type your code indicates.

 Other than that, I can't offer anything. Sorry.





The only true wisdom is knowing you know nothing

VisualLab

  • Sr. Member
  • ****
  • Posts: 355
Re: Generics - correct syntax
« Reply #14 on: April 23, 2024, 10:23:16 am »
I don't know what to tell you?

Basically the question was for people who know something about the documentation detailing generic types in FPC mode. Of course, I do not rule out that there is no detailed documentation on this subject. Still, it would be very useful. Programming using the "Macayev method" (also known as the "Grope method", "battle reconnaissance" or "trial and error :)) is ineffective and error-prone.

 

TinyPortal © 2005-2018