Recent

Author Topic: Generic Class specialization  (Read 2348 times)

darksky666

  • New Member
  • *
  • Posts: 38
Generic Class specialization
« on: April 05, 2018, 12:14:03 pm »
Quote
As of version 3.0 of Free Pascal, the specialize keyword can also be used in a variable declaration:
Code: Pascal  [Select][+][-]
  1. Var  
  2.   P : specialize TList<Pointer>;

In the above case, assuming a specialized class type has not been created, how do i create the class instance. the following gave error:

Code: Pascal  [Select][+][-]
  1.   class_instance := specialize class_name<type1>.create;
  2.  


Thanks

Thaddy

  • Hero Member
  • *****
  • Posts: 10467
Re: Generic Class specialization
« Reply #1 on: April 05, 2018, 12:45:23 pm »
Gimme code and I can test  8-)
Anyway:
Code: Pascal  [Select][+][-]
  1. program woah_1;
  2. {$mode delphi}
  3. type
  4.   class_name<t> = class
  5.   end;
  6.   type1 = integer;
  7. var
  8.   class_instance: class_name<type1>;
  9. begin
  10. // usually you create here.....
  11. end.
  12.  
A var is not a type.....but of a type.......... An instance is a var............... Basic :D programmer functionality failure. :)

And plz do not use museum syntax. (how good it once was)

And just a teaser from a teacher:
Code: Pascal  [Select][+][-]
  1. program woah_2;
  2. {$mode delphi}
  3. type
  4.   class_name<t> = class
  5.   end;
  6.   type1 = integer;
  7.   class_instance = class_name<type1>; // but now it is not an instance but a type....
  8. var
  9.   SomeInstance: class_instance;  
  10. begin  
  11.   // create something...
  12. end.

Let me know if it helped....
« Last Edit: April 05, 2018, 01:06:01 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

darksky666

  • New Member
  • *
  • Posts: 38
Re: Generic Class specialization
« Reply #2 on: April 05, 2018, 01:24:09 pm »
Thanks Thaddy but this is what i meant:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}
  3.  
  4. type
  5.   { TMyClass }
  6.   generic TMyClass<TType> = class
  7.     a : ansistring;
  8.     procedure test;
  9.   end;
  10.  
  11.   TMyIntClass = specialize TMyClass<integer>;
  12.  
  13. { TMyClass }
  14.  
  15. var
  16.   (* According to Manual, FPC 3.0 and above allows this *)
  17.   generic_class_instance : specialize TMyClass<integer>;
  18.  
  19. begin
  20.   {
  21.   // Something like this is not allowed
  22.   generic_class_instance := specialize TMyClass<integer>.Create;
  23.   }
  24.   // The statement below works
  25.   generic_class_instance := TMyIntClass.Create;
  26.  
  27.   generic_class_instance.test;
  28.   generic_class_instance.Free;
  29. end.  

So ultimately a specialized Type (TMyIntClass in this case) had to be created and used for the Class variable to be successfully instantiated. Then what is the benefit of FPC 3.0 allowing users to write:

Code: Pascal  [Select][+][-]
  1. var
  2.   generic_class_instance : specialize TMyClass<integer>;
  3.  

if something like this (code below) is not allowed?
Code: Pascal  [Select][+][-]
  1. generic_class_instance := specialize TMyClass<integer>.Create;

It's like saying "oh btw now you can use specialize keyword in var section in FPC 3 too (instead of using a specialized type), but to instantiate it, you will still have to create a specialized type up in the type section and use that".
How did that new construct in FPC 3 and above even help FPC users?

Thanks
« Last Edit: April 05, 2018, 02:31:52 pm by darksky666 »

darksky666

  • New Member
  • *
  • Posts: 38
Re: Generic Class specialization
« Reply #3 on: April 05, 2018, 03:06:13 pm »
Okay, to summarize the issue: the following code works in Delphi:

Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. ...
  3. var
  4.   (* According to Manual, FPC 3.0 and above allows this *)
  5.   generic_class_instance : { specialize } TMyClass<integer>;
  6.  
  7. begin                                                  
  8.   generic_class_instance := {specialize } TMyClass<integer>.Create;
  9.   ...
  10.  

In Delphi mode you could use generic class without declaring a separate type, it was your choice as to whether you want to declare a type or not.
 
FPC 3 tried to give this feature for OBJFPC mode (which requires use of generic and specialize keywords), it allowed users to use specialize keyword in var section.. but since specialize keyword isn't allowed inside begin..end, you will have to declare a specialized type of generic class and use that to call the constructor.

It isn't a big deal really but that FPC 3 addition kind of seems .. pointless..   

Thaddy

  • Hero Member
  • *****
  • Posts: 10467
Re: Generic Class specialization
« Reply #4 on: April 05, 2018, 03:36:50 pm »
My code works in modern delphi's and in freepascal. Your code does not. And generics were in FPC since 2.2.
I still do not understand what you exactly mean?
« Last Edit: April 05, 2018, 03:39:52 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

darksky666

  • New Member
  • *
  • Posts: 38
Re: Generic Class specialization
« Reply #5 on: April 05, 2018, 05:00:18 pm »
Hmm, it's strange, the example code from my second post compiled fine for me (except i remove the procedure definition part to shorten the post).. i'm using FPC 3.0.4 (i dont have delphi though.. it gave an error during installation in my pirated Windows 8.1 Pro   :-X)

Anyway, I have reached a conclusion that it's just an incomplete feature.. so please disregard this question..


But if you still want to know what i was babbling about then here is the mess for you to read:

Assume you have a generic class called some_generic_class:

Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. type
  3.  TMyIntClass = some_generic_class<integer>;
  4.  
  5. var
  6.   variable : some_generic_class<integer>;
  7.  
  8. begin
  9.   (* Both of the following work, you can use either one *)
  10.   variable := some_generic_class<integer>.Create;
  11.   variable := TMyIntClass.Create
  12.  


You didn't need to create a separate type to call the constructor.

But in ObjFPC mode, you need to declare a separate type.. So Ref-Manual says (starting with FPC 3), you can use specialize keyword in var section also, meaning you can do:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2.  
  3. var
  4.   variable : specialize some_generic_class<integer>;
  5.  

But (apparently) you still can't do this:
Code: Pascal  [Select][+][-]
  1. begin
  2.   (* It will give "identifier not found" error*)
  3.   variable := specialize some_generic_class<integer>.create;
  4.  

You have to do:

Code: Pascal  [Select][+][-]
  1. type
  2.  TMyIntClass = specialize some_generic_class<integer>;
  3. ...
  4. var
  5. ...
  6. begin
  7.   variable := TMyIntClass.Create;
  8.  

Even though specialize keyword was allowed in var section, the specialize keyword is still not allowed in begin..end, trying to compile it gives "identifier not found" error, so you will have to define a type that specializes that generic class and use that type to call the constructor

if you have to declare the type anyway, why have that (specialize keyword allowed in var section) feature at all? Seems kind of pointless.. so i reached the conclusion that the feature is incomplete (unless there is something more to this feature in FPC 3 which i am not aware of)..
« Last Edit: April 05, 2018, 05:55:58 pm by darksky666 »

PascalDragon

  • Hero Member
  • *****
  • Posts: 2132
  • Compiler Developer
Re: Generic Class specialization
« Reply #6 on: April 06, 2018, 03:50:20 pm »
Inline specialization in var-sections is supported from 3.0 on, but inline specialization in code sections (what you're trying with specialize TSomeClass<TSomeType>.Create is only supported in trunk (I added that when I added support for generic routines).  :-[

 

TinyPortal © 2005-2018