Recent

Author Topic: Helper for TArray  (Read 3787 times)

Molochnik

  • Jr. Member
  • **
  • Posts: 80
Helper for TArray
« on: March 07, 2024, 05:28:48 pm »
While converting a Delphi project I encountered with the errors:
either:
Identifier not found "Generics"
or (when TArray is used instead of Generics.Collections.TArray):
Generics without specialization cannot be used as a type for a variable
What do these errors mean and how to get rid of them?

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$IFDEF FPC}
  3. {$MODE Delphi}
  4. {$ENDIF}
  5. interface
  6. uses Generics.Defaults, Generics.Collections;
  7.  
  8. type
  9.   TArrayHelper = class helper for Generics.Collections.TArray
  10.   end;
« Last Edit: March 07, 2024, 06:57:41 pm by Molochnik »

Nitorami

  • Hero Member
  • *****
  • Posts: 598
Re: Helper for TArray
« Reply #1 on: March 07, 2024, 05:58:14 pm »
Hi
First, the "interface" should be before the "uses" clause.
Second, the type TArrayHelper already exists in Generics.Collections. What are you trying to achieve by redeclaring it ?

Molochnik

  • Jr. Member
  • **
  • Posts: 80
Re: Helper for TArray
« Reply #2 on: March 07, 2024, 06:58:58 pm »
Corrected the code. I would like to add some helper methods like Contains.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Helper for TArray
« Reply #3 on: March 07, 2024, 07:31:43 pm »
I do not know from memory if helpers already supported multiple helpers (at the same time) but in case it doesn't you would have to derive your helper from TArrayHelper in order to be able to extend it.

Code: Pascal  [Select][+][-]
  1. TArrayHelper = class helper(generics.Collections.TArrayHelper) for Generics.Collections.TArray
  2.  
I do not know the original location/name of the original class helper to I just took generics.Collections.TArrayHelper as an example. Simply replace with the correct one.

Today is tomorrow's yesterday.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12536
  • FPC developer.
Re: Helper for TArray
« Reply #4 on: March 07, 2024, 07:36:21 pm »
(maybe make the helper also a generic, and then later specialize it?)

Thaddy

  • Hero Member
  • *****
  • Posts: 18364
  • Here stood a man who saw the Elbe and jumped it.
Re: Helper for TArray
« Reply #5 on: March 07, 2024, 07:41:35 pm »
(maybe make the helper also a generic, and then later specialize it?)
In trunk there are even two other options:
1. {$modeswitch multihelpers}
2. You can inherit from another helper. (Tron also bringed that to mind)
But AFAIK these are not yet available in 3.2.2.
3. More in general, also with 3.2.2, you can create an in operator for contains.
That can be free standing but needs a specialized array. (for now)
If you want I can give you an example of all three
Just ask.
« Last Edit: March 07, 2024, 07:59:15 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Helper for TArray
« Reply #6 on: March 07, 2024, 08:27:38 pm »
(maybe make the helper also a generic, and then later specialize it?)
To my knowledge that is not (yet) possible. If I remember correctly PascalDragon made a remark about that a couple of weeks ago at someone else trying to write/declare a generalized helper (is that even the proper terminology for the context ?).
Today is tomorrow's yesterday.

Thaddy

  • Hero Member
  • *****
  • Posts: 18364
  • Here stood a man who saw the Elbe and jumped it.
Re: Helper for TArray
« Reply #7 on: March 07, 2024, 08:39:05 pm »
Sven/Sarah suggested it was on the todo list, but you know a queue.
Give PascalDragon the time.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Helper for TArray
« Reply #8 on: March 07, 2024, 08:42:02 pm »
For sure Thaddy.

The only reason I remembered is because I am (also) looking forward for it to be implemented but there is no need to rush (I am aware that PD is very busy atm).
Today is tomorrow's yesterday.

Molochnik

  • Jr. Member
  • **
  • Posts: 80
Re: Helper for TArray
« Reply #9 on: March 07, 2024, 08:55:51 pm »
If you want I can give you an example of all three
Just ask.
Yes, that would be great! Thanks!

Thaddy

  • Hero Member
  • *****
  • Posts: 18364
  • Here stood a man who saw the Elbe and jumped it.
Re: Helper for TArray
« Reply #10 on: March 07, 2024, 09:00:01 pm »
Will be here tomorrow UTC+1 10:00. I am almost asleep.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Helper for TArray
« Reply #11 on: March 07, 2024, 11:44:42 pm »
Identifier not found "Generics"
Free pascal does not seem to support unit names in helpers (yet)

Quote
or (when TArray is used instead of Generics.Collections.TArray):
Generics without specialization cannot be used as a type for a variable
TArray is defined in Free Pascal as (generic) array of T, and not as a class (in generics.collection), hence the error as you did not specialize the array.

Unfortunately Free Pascal does not support generic helpers (yet)

What you are probably looking for is class TArrayHelper in generics.collection, but also there you first would have to specialize the helper.

Thus something along the line of:
Code: Pascal  [Select][+][-]
  1.   TMySpecializedArrayHelper = specialize TArrayHelper<integer>;
  2.   TMyArrayHelper = class helper for TMySpecializedArrayHelper
  3.    // your stuff
  4.   end;
  5.  
Today is tomorrow's yesterday.

Molochnik

  • Jr. Member
  • **
  • Posts: 80
Re: Helper for TArray
« Reply #12 on: March 08, 2024, 06:13:57 am »
you first would have to specialize the helper.
I dont like the idea of specializing a helper cause it reduces the value of such helper almost to zero, in Delphi I used to use it for constructing and manipulating arrays of various records of fixed size like:
Code: Pascal  [Select][+][-]
  1.   TA=record
  2.     i:Int32;
  3.     i64:Int64;
  4.     s: string [10];
  5.   end;
And they could and should be easily compared using Lazarus IEqualityComparer interface without specializing
« Last Edit: March 08, 2024, 01:50:34 pm by Molochnik »

Thaddy

  • Hero Member
  • *****
  • Posts: 18364
  • Here stood a man who saw the Elbe and jumped it.
Re: Helper for TArray
« Reply #13 on: March 08, 2024, 03:31:16 pm »
Corrected the code. I would like to add some helper methods like Contains.
Here's an example using a generic function, the example needs trunk, though.
I think this is a different but short and elegant approach.
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$modeswitch ImplicitFunctionSpecialization}
  2. { does not need any units }
  3. generic function Contains<T>(arr: specialize Tarray<T>;value: T): Boolean;
  4. var
  5.   e:T;
  6. begin
  7.   Result := false;
  8.   for e in arr do
  9.     if e = value then
  10.     begin
  11.       result :=true;
  12.       break;
  13.     end;
  14. end;
  15. var
  16.   a:specialize TArray<integer> = (1,2,3,5,6,7,8,9);
  17. begin
  18.   writeln(Contains(a,4));  // prints false. implicit specialization
  19.   writeln(Contains(a,7));  // prints true;
  20. end.
You can declare generic procedures, functions, methods on any T or TArray<T>.
(generic operators do not work yet, generic functions were introduced in 3.2.0 and implicit specialization in trunk)

In mode delphi it looks like this, but note Delphi does not support implicit specialization, so you can not use this technique in both Delphi and FPC. I just add it because it is an even more compact syntax:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}{$modeswitch ImplicitFunctionSpecialization}
  2. { does not need any units }
  3. function Contains<T>(arr:Tarray<T>;value: T): Boolean;inline;
  4. var
  5.   e:T;
  6. begin
  7.   Result := false;
  8.   for e in arr do
  9.     if e = value then
  10.     begin
  11.       result :=true;
  12.       break;
  13.     end;
  14. end;
  15.  
  16. var
  17.   a:TArray<single> = [1,2,3,5,6,7,8,9];
  18.   s:TArray<string> = ['test','me'];
  19. begin
  20.   { implicit specializations }
  21.   writeln(Contains(a,4));//false
  22.   writeln(Contains(a,7));//true
  23.   writeln(Contains(s,'whatever'));// false
  24.   writeln(Contains(s,'me'));      // true
  25. end.
  26.  

« Last Edit: March 08, 2024, 07:02:39 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6195
  • Compiler Developer
Re: Helper for TArray
« Reply #14 on: March 08, 2024, 09:54:27 pm »
In mode delphi it looks like this, but note Delphi does not support implicit specialization, so you can not use this technique in both Delphi and FPC.

Delphi does support implicit specializations, that's one of the reasons why we added it. What Delphi does not support is global generic functions, only generic methods.

 

TinyPortal © 2005-2018