Recent

Author Topic: function: set/array of something impossible?  (Read 743 times)

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
function: set/array of something impossible?
« on: August 15, 2024, 09:39:34 am »
It seems like returning a function result as a set/array without making the set a declared type doesn't work? The documentation seems to be a bit cryptic on that "The result type of a function can be any previously declared type".

In other words this doesn't compile:

Code: Pascal  [Select][+][-]
  1. function A: set of Byte; // Error: Type identifier expected

neither does this

Code: Pascal  [Select][+][-]
  1. function B: array of Byte; // Error: Type identifier expected

While this works:

Code: Pascal  [Select][+][-]
  1. type
  2.   TSetOfByte = set of Byte;
  3. function A: TSetOfByte;
  4. type
  5.   TArrayOfByte = array of Byte;
  6. function B: TArrayOfByte;

Also this works:

Code: Pascal  [Select][+][-]
  1. function A: specialize TList<Byte>;

To be more specific about my usecase, I wanted to make a function that does the following:

Code: Pascal  [Select][+][-]
  1. generic function StringToEnumsSet<T>(const AString: String): set of T;

I don't think I can forward-declare type set of T, can I?
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

MarkMLl

  • Hero Member
  • *****
  • Posts: 7451
Re: function: set/array of something impossible?
« Reply #1 on: August 15, 2024, 10:26:46 am »
That sounds like the same rule that the type of a parameter has to be predefined.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Warfley

  • Hero Member
  • *****
  • Posts: 1522
Re: function: set/array of something impossible?
« Reply #2 on: August 15, 2024, 01:00:39 pm »
Yes this is currently not possible with generic functions, you could make a generic type to do a workaround:
Code: Pascal  [Select][+][-]
  1. type
  2.   generic TStringToEnumSet<T> = record
  3.     type TEnumSet = set of T;
  4.     class function Convert(const AString: String): TEnumSet;
  5.   end;

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: function: set/array of something impossible?
« Reply #3 on: August 15, 2024, 01:04:31 pm »
Oh, that makes sense! Should fit my usecase. I'll try it :) Thank you!
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

Thaddy

  • Hero Member
  • *****
  • Posts: 15496
  • Censorship about opinions does not belong here.
Re: function: set/array of something impossible?
« Reply #4 on: August 15, 2024, 01:15:40 pm »
For the array, simply add types to the uses clause
Code: Pascal  [Select][+][-]
  1. uses types;
  2. function test:TByteDynArray;
There are many more predeclared dynarrays in types.
Also note that in trunk it is possible to forward declare generic methods/functions/procedures.
https://wiki.freepascal.org/FPC_New_Features_Trunk#Support_for_forward_declarations_of_generic_types
« Last Edit: August 15, 2024, 01:22:49 pm by Thaddy »
My great hero has found the key to the highway. Rest in peace John Mayall.
Playing: "Broken Wings" in your honour. As well as taking out some mouth organs.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5644
  • Compiler Developer
Re: function: set/array of something impossible?
« Reply #5 on: August 15, 2024, 07:23:23 pm »
Also this works:

Code: Pascal  [Select][+][-]
  1. function A: specialize TList<Byte>;

This is because specializations are considered declared types. That also means that you can use specialize TArray<Byte> for example as result type.

To be more specific about my usecase, I wanted to make a function that does the following:

Code: Pascal  [Select][+][-]
  1. generic function StringToEnumsSet<T>(const AString: String): set of T;

I don't think I can forward-declare type set of T, can I?

For sets you currently need to use the workaround that Warfley mentioned.

Also note that in trunk it is possible to forward declare generic methods/functions/procedures.
https://wiki.freepascal.org/FPC_New_Features_Trunk#Support_for_forward_declarations_of_generic_types

Thaddy, please, read and understand things you're posting: The link you mentioned talks about forward declaring generic types and you say generic methods/functions/procedures.
Newsflash: for generic methods forward declaration is not necessary, because they're always forward declared inside a type anyway and generic functions/procedures supported forward declaration since their introduction.

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: function: set/array of something impossible?
« Reply #6 on: August 16, 2024, 12:54:03 am »
Got to try the workaround, unfortunately it doesn't seem to work...? Or maybe I'm doing something wrong?
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

jamie

  • Hero Member
  • *****
  • Posts: 6515
Re: function: set/array of something impossible?
« Reply #7 on: August 16, 2024, 03:55:24 am »
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode Delphi}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   generics.collections;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     procedure Button1Click(Sender: TObject);
  18.   private
  19.  
  20.   public
  21.  
  22.   end;
  23. Function Test<T>(A:array of T):THashSet<T>;
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. Function Test<T>(A:Array of T):THashSet<T>;
  32. var
  33.   I:T;
  34. Begin
  35.    result := ThashSet<T>.Create;
  36.    For I in A do Result.Add(I);
  37. end;
  38.  
  39. { TForm1 }
  40.  
  41. procedure TForm1.Button1Click(Sender: TObject);
  42. Var
  43.   S:THashSet<Byte>;
  44. begin
  45.   S:=Test<Byte>([34,56,23,89,12]);
  46.   Caption := S.Extract(56).ToString; //Returns 0 if not found
  47.   S.Free;
  48. end;
  49.  
  50. end.
  51.  
  52.  

is this what you are looking for? a SET generics.

I used the currently available one in the tools, but I wrote one using  the fgl.
the Generics.Colllections is a  little heavy, but it get you there.
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018