Recent

Author Topic: generics in fpc 3.20  (Read 2063 times)

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
generics in fpc 3.20
« on: July 14, 2020, 03:25:53 pm »
If FPC 3.2 has generics build in like delphi, why is tobjectlist not found?
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses generics.collections, generics.defaults;
  4.  
  5. type
  6.  
  7. { TPerson }
  8.  
  9.  TPerson = class
  10.   fName : string;
  11.   fAge  : integer;
  12.   public
  13.     constructor Create(const aName : string; const aAge : integer);
  14. end;
  15.  
  16. { TPerson }
  17.  
  18. constructor TPerson.Create(const aName: string; const aAge: integer);
  19. begin
  20.   fName := aName;
  21.   fAge  := aAge;
  22. end;
  23.  
  24. var Persona : TObjectlist<TPerson>;
  25.     Person  : TPerson;
  26. begin
  27.   Persona := TObjectlist<TPerson>.create;
  28.   try
  29.     Person := TPerson.Create('John',50);
  30.     Persona.Add(Person);
  31.     Person := TPerson.Create('Jack',30);
  32.     Persona.Add(Person);
  33.     for Person in Persona do
  34.       writeln(person.fName,' ',person.fAge);
  35.     readln;
  36.   finally
  37.     Persona.free;
  38.   end;
  39. end.                
  40.  
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: generics in fpc 3.20
« Reply #1 on: July 14, 2020, 03:34:48 pm »
You need to explicitly set a mode that is Object Pascal, and you need to specialize the generic type.
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses generics.collections, generics.defaults;
  6.  
  7. type
  8.  
  9.  TPerson = class
  10.   fName : string;
  11.   fAge  : integer;
  12.   public
  13.     constructor Create(const aName : string; const aAge : integer);
  14. end;
  15.  
  16.  TPersonObjectList = specialize TObjectList<TPerson>;
  17.  
  18. constructor TPerson.Create(const aName: string; const aAge: integer);
  19. begin
  20.   fName := aName;
  21.   fAge  := aAge;
  22. end;
  23.  
  24. var
  25.     Persona : TPersonObjectList;
  26.     Person  : TPerson;
  27. begin
  28.   Persona := TPersonObjectList.Create();
  29.   try
  30.     Person := TPerson.Create('John',50);
  31.     Persona.Add(Person);
  32.     Person := TPerson.Create('Jack',30);
  33.     Persona.Add(Person);
  34.     for Person in Persona do
  35.       writeln(person.fName,' ',person.fAge);
  36.     readln;
  37.   finally
  38.     Persona.free;
  39.   end;
  40. end.

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: generics in fpc 3.20
« Reply #2 on: July 14, 2020, 04:43:25 pm »
Thank you howardpc.

You still need 'specialize' for using generics like fgl. I didn't know that.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: generics in fpc 3.20
« Reply #3 on: July 14, 2020, 05:15:59 pm »
Or {$mode Delphi}

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: generics in fpc 3.20
« Reply #4 on: July 14, 2020, 06:23:43 pm »
Or {$mode Delphi}
Which I would recommend to most... (Although there are some subtle things that can only be done in mode objfpc, these are rare/specialist stuff -the latter pun intended- )
Specialize a type, not a var.

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: generics in fpc 3.20
« Reply #5 on: July 15, 2020, 08:17:37 am »
It could, but with {$mode Delphi} I can better stuck with Delphi.
Lazarus is objfpc.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: generics in fpc 3.20
« Reply #6 on: July 15, 2020, 08:23:07 am »
Lazarus is objfpc.
Lazarus is perfectly fine with Delphi mode too.
Specialize a type, not a var.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: generics in fpc 3.20
« Reply #7 on: July 15, 2020, 09:40:41 am »
You still need 'specialize' for using generics like fgl. I didn't know that.

The requirement of the generic keywords has nothing to do with the used units, only with the language dialect you're using in your current unit.

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: generics in fpc 3.20
« Reply #8 on: July 15, 2020, 04:31:02 pm »
Lazarus is perfectly fine with Delphi mode too.
Lazarus really does not like Delphi style Generics, auto generation (ctrl + shift + c) sometimes looses params or reorders the params.

I don't have an example lying around right now, but it was was something like this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TFoo<T, U> = record
  3.   ...
  4.     class operator Implicit(var a: TFoo<T, U>);
  5.   ...
  6.  
  7. // Generated:
  8. class operator TFoo<U, T>.Implicit(var a: TFoo<>);
That said, I am working on lazarus trunk, and I don't know which revision I was exactly on

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: generics in fpc 3.20
« Reply #9 on: July 15, 2020, 05:05:36 pm »
I don't have an example lying around right now, but it was was something like this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TFoo<T, U> = record
  3.   ...
  4.     class operator Implicit(var a: TFoo<T, U>);
  5.   ...
  6.  
  7. // Generated:
  8. class operator TFoo<U, T>.Implicit(var a: TFoo<>);
That said, I am working on lazarus trunk, and I don't know which revision I was exactly on

I think the swapped parameter one was already reported, I don't know about the removed parameters. Please report such bugs when you find them. After all generics will be used more and more and if the CodeTools are not up to it, that's bad. :-X

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: generics in fpc 3.20
« Reply #10 on: July 15, 2020, 05:39:11 pm »
I think the swapped parameter one was already reported, I don't know about the removed parameters. Please report such bugs when you find them. After all generics will be used more and more and if the CodeTools are not up to it, that's bad. :-X

Yeah, I actually have a text file with a lot of bugs, which occured during a project. The problem with that I currently don't have much time to my hand, and when filing a bug report I want to at least properly test this, with different versions (I work on trunk, and it simply happens that something is broken there, so the question is if it is also broken on a stable branch and/or if my trunk version is the most current one) and find a minimal example, so when I have a little more time I will work this list.

Some of these bugs are really weird, because sometimes lazarus thinks the function was not defined, and produces a new function of an already defined function which of course leads to compilation errors, but I wasn't able to consistently produce this bug at all (it just happens in exactly one file of my project, and I can't commit a full project as bug report)

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: generics in fpc 3.20
« Reply #11 on: July 15, 2020, 06:55:00 pm »
Code: Pascal  [Select][+][-]
  1. type
  2.   TFoo<T, U> = record
  3.   ...
  4.     class operator Implicit(var a: TFoo<T, U>);
  5.  

Code completed correctly in version 63557

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: generics in fpc 3.20
« Reply #12 on: July 16, 2020, 05:31:29 pm »
Some of these bugs are really weird, because sometimes lazarus thinks the function was not defined, and produces a new function of an already defined function which of course leads to compilation errors

I had this error and it sometimes is due to a "silly" difference between interface and implementation. If you define
Code: Pascal  [Select][+][-]
  1.    function MyFunction: Boolean;
  2.  
but you implement it like this:
Code: Pascal  [Select][+][-]
  1. function TMyClass.MyFunction(): Boolean;
  2. begin
  3. end;
  4.  

The extra parenthesis on implementation (or in the interface) causes the problem. There are other cases which i didn't pay attention to the cause and could have happened for a different reason.
ETA:
Other case is when you have a property declared like this:
Code: Pascal  [Select][+][-]
  1.    TMyClass = Class(TObject)
  2.    private
  3.       FMyData: Integer;
  4.    public
  5.       procedure SetMyData(const SomeValue: Integer);
  6.       property MyData: Integer read FMyData write SetMyaData;
  7.    end;
  8.  
On this case if you add a new method or property to the class and then press Ctrl+J youwill have a new SetMyData on the private section.

I, personally would prefer if functions, procedures and methods without parameters where forced to have parenthesis not for what I described above but because it confused the compiler with some procedural types. Example:
Code: Pascal  [Select][+][-]
  1. type
  2.    TProc1 = procedure of object;
  3.    TProc2 = procedure () of object;
  4.  
  5. var
  6.    Proc1: TProc1;
  7.    Proc2: TProc2
  8. {....}
  9.    if Assigned(Proc2) then
  10.       Proc2();
  11.    if Assigned(Proc1) then
  12.       Proc1; //< Error ":=" expected but ";" found
  13.  

It also makes more visible when something is a property and when is a method.
« Last Edit: July 16, 2020, 05:40:35 pm by garlar27 »

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: generics in fpc 3.20
« Reply #13 on: July 17, 2020, 09:40:10 am »
The extra parenthesis on implementation (or in the interface) causes the problem. There are other cases which i didn't pay attention to the cause and could have happened for a different reason.

Would be good to report such bugs.

Other case is when you have a property declared like this:
Code: Pascal  [Select][+][-]
  1.    TMyClass = Class(TObject)
  2.    private
  3.       FMyData: Integer;
  4.    public
  5.       procedure SetMyData(const SomeValue: Integer);
  6.       property MyData: Integer read FMyData write SetMyaData;
  7.    end;
  8.  
On this case if you add a new method or property to the class and then press Ctrl+J youwill have a new SetMyData on the private section.

In this case there is not much that can be done, cause the setter is definitely a different identifier for the IDE and some kind of automagic detection will lead to problems sooner or later.

I, personally would prefer if functions, procedures and methods without parameters where forced to have parenthesis not for what I described above but because it confused the compiler with some procedural types. Example:
Code: Pascal  [Select][+][-]
  1. type
  2.    TProc1 = procedure of object;
  3.    TProc2 = procedure () of object;
  4.  
  5. var
  6.    Proc1: TProc1;
  7.    Proc2: TProc2
  8. {....}
  9.    if Assigned(Proc2) then
  10.       Proc2();
  11.    if Assigned(Proc1) then
  12.       Proc1; //< Error ":=" expected but ";" found
  13.  

It also makes more visible when something is a property and when is a method.

With FPC 3.2.0 mode ObjFPC and Delphi have no problem here. If you still have a problem, then please provide a full example.

 

TinyPortal © 2005-2018