Recent

Author Topic: Initialize list in function parameter  (Read 1506 times)

PeterHu

  • Jr. Member
  • **
  • Posts: 60
Initialize list in function parameter
« on: November 07, 2025, 03:20:26 pm »
May I ask does fp support initialize list like below?
Code: Pascal  [Select][+][-]
  1. apple:=('apple',1);
  2. apple:=TFruit('apple',1);
  3. list.pushBack(['apple',1]);
  4. list.pushBack(('apple',1));
  5. list.pushBack(TFruit('apple',1));

full code:

Code: Pascal  [Select][+][-]
  1. program project1;
  2. uses
  3.     gvector;
  4.  
  5. type
  6.   TFruit=record
  7.     name:String;
  8.     color:Integer;
  9.     end;
  10. type
  11.   TFruitList=specialize TVector<TFruit>;
  12. var
  13.   flist:TFruitList;
  14.   fruit:TFruit;
  15. begin
  16.   flist:=TFruitList.Create;
  17. // flist.pushback(('apple',1));// flist.PushBack(TFruit('Apple',1));
  18.   fruit.name:='apple';
  19.   fruit.color:=1;
  20.   flist.PushBack(fruit);
  21.   WriteLn(flist[0].name);
  22.   flist.Destroy;
  23.   ReadLn;
  24. end.          
  25.  
« Last Edit: November 07, 2025, 03:26:37 pm by PeterHu »

Thaddy

  • Hero Member
  • *****
  • Posts: 18519
  • Here stood a man who saw the Elbe and jumped it.
Re: Initialize list in function parameter
« Reply #1 on: November 07, 2025, 04:47:21 pm »
I think that is a bug:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. uses
  3.     gvector;
  4.  
  5. type
  6.   TFruit=record
  7.     name:String;
  8.     color:Integer;
  9.     end;
  10. type
  11.   TFruitList=TVector<TFruit>;
  12.  
  13. var
  14.   flist:TFruitList;
  15.   fruit:TFruit = (name:'pear';color:255);// allowed, should also be allowed later.
  16. begin
  17.   flist:=TFruitList.Create;
  18.   flist.PushBack(Fruit);
  19.   // flist.pushback((name:'pear';color:255));// fails, but should be legal syntax
  20.   WriteLn(flist[0].name);
  21.   flist.Free;
  22.   ReadLn;
  23. end.
It is not a bug in gvector. The syntax: (name:'pear';color:255) should be allowed as parameter when the parameter is of type TFruit.
I am almost sure this is intended to work, but doesn't. It should not even need a cast.
Note that you also made a small syntax error, by using a comma. But that is not really relevant.

Other replies are very welcome.

Note it also fails in Delphi, using a TList<T>  for reference.
« Last Edit: November 07, 2025, 05:47:16 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

bytebites

  • Hero Member
  • *****
  • Posts: 765
Re: Initialize list in function parameter
« Reply #2 on: November 07, 2025, 10:05:30 pm »
Code: Pascal  [Select][+][-]
  1.    flist.pushback((name:'pear';color:255));// fails, but should be legal syntax

Really? Are you kidding?

jamie

  • Hero Member
  • *****
  • Posts: 7402
Re: Initialize list in function parameter
« Reply #3 on: November 08, 2025, 12:06:06 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,Gvector;
  9.  
  10. type
  11.  
  12.   { TFruit }
  13.  
  14.   TFruit=record
  15.     name:String;
  16.     color:Integer;
  17.     Constructor Create(aName:String;AColor:Integer);
  18.     end;
  19.   TFruitList=TVector<TFruit>;
  20.  
  21.   { TForm1 }
  22.  
  23.   TForm1 = class(TForm)
  24.     Button1: TButton;
  25.     procedure Button1Click(Sender: TObject);
  26.   private
  27.  
  28.   public
  29.  
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TFruit }
  40.  
  41. constructor TFruit.Create(aName: String; AColor: Integer);
  42. begin
  43.   Name := AName; Color := AColor;
  44. end;
  45.  
  46. { TForm1 }
  47.  
  48. procedure TForm1.Button1Click(Sender: TObject);
  49. var
  50.   flist:TFruitList;
  51.   fruit:TFruit = (name:'pear';color:255);// allowed, should also be allowed later.
  52. begin
  53.   flist:=TFruitList.Create;
  54.   flist.PushBack(Fruit);
  55.   flist.pushback(TFruit.Create('pear',255));//<< This works now! // fails, but should be legal syntax
  56.   Caption := Flist[0].Name;
  57.   flist.Free;
  58. end;
  59.  
  60. end.
  61.  
  62.  

This should be ok.

Jamie
The only true wisdom is knowing you know nothing

simone

  • Hero Member
  • *****
  • Posts: 681
Re: Initialize list in function parameter
« Reply #4 on: November 08, 2025, 12:33:09 am »
Code: Pascal  [Select][+][-]
  1.    flist.pushback((name:'pear';color:255));// fails, but should be legal syntax

Really? Are you kidding?

As far as I know, record constants of the form (field1:value1; field2:value2; ...) are only supported to initialize record-type variables (or constants) in declarations, but not as parameters, nor in assignment statements.
« Last Edit: November 09, 2025, 12:52:17 am by simone »
Microsoft Windows 10/11 64 bit - Lazarus 3.8/4.0 FPC 3.2.2 x86_64-win64-win32/win64

speter

  • Sr. Member
  • ****
  • Posts: 451
Re: Initialize list in function parameter
« Reply #5 on: November 08, 2025, 12:38:40 am »
You could also do this:
Code: Pascal  [Select][+][-]
  1. function init(aName:String;AColor:Integer) : tfruit;
  2. begin
  3.   result.Name := AName;
  4.   result.Color := AColor;
  5. end;
  6. {...}
  7. procedure TForm1.Button1Click(Sender: TObject);
  8. var
  9.   flist : TFruitList;
  10.   fruit : TFruit = (name:'pear';color:255);
  11. begin
  12.   flist := tfruitlist.create;
  13.   flist.pushback(fruit);
  14.   flist.pushback(init('orange',222));
  15. end;
But, I don't think it offers any advantages over Jamie's suggestion. :o

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

jamie

  • Hero Member
  • *****
  • Posts: 7402
Re: Initialize list in function parameter
« Reply #6 on: November 08, 2025, 12:40:04 am »
Maybe we should have Default Constructors or functions?

Code: Pascal  [Select][+][-]
  1.  
  2. ...Tfruit() or TFruit('Tex't,255);
  3.  

Then we could be like the other guys! :o
The only true wisdom is knowing you know nothing

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 305
  • I use FPC [main] 💪🐯💪
Re: Initialize list in function parameter
« Reply #7 on: November 08, 2025, 04:01:30 am »
You may also consider this option:

Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$mode objfpc}{$h+}
  3. {$modeswitch advancedrecords}
  4.  
  5. uses gvector;
  6.  
  7. type
  8.   TFruit=record
  9.     name:String;
  10.     color:Integer;
  11.     class operator :=(const data: array of const): TFruit;
  12.   end;
  13.  
  14. class operator TFruit.:=(const data: array of const): TFruit;
  15. begin
  16.   Pointer(Result.name):=data[0].VAnsiString;
  17.   Result.color:=data[1].VInteger;
  18. end;
  19.  
  20. begin
  21.   with (specialize TVector<TFruit>.Create) do
  22.   begin
  23.     pushback(['apple',1]);
  24.     WriteLn(items[0].name);
  25.   end;
  26.   ReadLn;
  27. end.
I may seem rude - please don't take it personally

PeterHu

  • Jr. Member
  • **
  • Posts: 60
Re: Initialize list in function parameter
« Reply #8 on: November 08, 2025, 05:31:27 am »
Thank you all!

The init version is much convenient when to fill a vector or array of record in a vector.pushback.
the operator= version is almost as convenient as std::vector.emplace_back({struct initialize list}) even std::vector.emplace_back(initialize_list).

For the operator= version,I encountered an issue.when providing a widestring like Chinese character to vector's pushBack and trying to get back with writeln,the characters are garbled.{$codepage utf8} and uses lazutf8 doesn't help much.I have no clue where to do conversions.

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 305
  • I use FPC [main] 💪🐯💪
Re: Initialize list in function parameter
« Reply #9 on: November 08, 2025, 07:57:19 am »
Chinese character

Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$mode objfpc}{$h+}
  3. {$codepage utf8}
  4. {$modeswitch advancedrecords}
  5.  
  6. uses gvector;
  7.  
  8. type
  9.   TFruit=record
  10.     name: UnicodeString;
  11.     color: Integer;
  12.     class operator :=(const data: array of const): TFruit;
  13.   end;
  14.  
  15. class operator TFruit.:=(const data: array of const): TFruit;
  16. begin
  17.   WriteLn(data[0].VType);
  18.  
  19.  
  20.   Pointer(Result.name):=data[0].VUnicodeString;
  21.   Result.color:=data[1].VInteger;
  22. end;
  23.  
  24. begin
  25.   with (specialize TVector<TFruit>.Create) do
  26.   begin
  27.     pushback(['apple',1]);
  28.     WriteLn(items[0].name);
  29.   end;
  30.   ReadLn;
  31. end.
I may seem rude - please don't take it personally

PeterHu

  • Jr. Member
  • **
  • Posts: 60
Re: Initialize list in function parameter
« Reply #10 on: November 08, 2025, 08:26:37 am »
Chinese character

Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$mode objfpc}{$h+}
  3. {$codepage utf8}
  4. {$modeswitch advancedrecords}
  5.  
  6. uses gvector;
  7.  
  8. type
  9.   TFruit=record
  10.     name: UnicodeString;
  11.     color: Integer;
  12.     class operator :=(const data: array of const): TFruit;
  13.   end;
  14.  
  15. class operator TFruit.:=(const data: array of const): TFruit;
  16. begin
  17.   WriteLn(data[0].VType);
  18.  
  19.  
  20.   Pointer(Result.name):=data[0].VUnicodeString;
  21.   Result.color:=data[1].VInteger;
  22. end;
  23.  
  24. begin
  25.   with (specialize TVector<TFruit>.Create) do
  26.   begin
  27.     pushback(['apple',1]);
  28.     WriteLn(items[0].name);
  29.   end;
  30.   ReadLn;
  31. end.

Now it display the name field properly when it is in Chinese.But may I ask what happended behind
Code: Pascal  [Select][+][-]
  1. Pointer(Result.name):=data[0].VUnicodeString;
  2.  
as I noticed that:
1. in other routines I always declare string variables as string(or ansistring),rarelly  as widestring or unicode string,they (type string) all displayed properly with utf8 sets.
2. in this example,when changing name from string to unicodestring,data[0].vstring|vWideString|vUnicodeString all works as expected.
« Last Edit: November 08, 2025, 08:32:15 am by PeterHu »

cdbc

  • Hero Member
  • *****
  • Posts: 2522
    • http://www.cdbc.dk
Re: Initialize list in function parameter
« Reply #11 on: November 08, 2025, 09:34:35 am »
Hi
Please don't show example code that leaks!!!
Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$mode objfpc}{$h+}
  3. {$codepage utf8}
  4. {$modeswitch advancedrecords}
  5.  
  6. uses gvector;
  7.  
  8. type
  9.   TFruit=record
  10.     name: UnicodeString;
  11.     color: Integer;
  12.     class operator :=(const data: array of const): TFruit;
  13.   end;
  14.  
  15. class operator TFruit.:=(const data: array of const): TFruit;
  16. begin
  17.   WriteLn(data[0].VType);
  18.  
  19.  
  20.   Pointer(Result.name):=data[0].VUnicodeString;
  21.   Result.color:=data[1].VInteger;
  22. end;
  23.  
  24. begin
  25.   /// WHERE IS FREE / DESTROY??? ///
  26.   with (specialize TVector<TFruit>.Create) do
  27.   begin
  28.     pushback(['apple',1]);
  29.     WriteLn(items[0].name);
  30.   end;
  31.   ReadLn;
  32.   /// WHERE IS FREE / DESTROY??? ///
  33. end.
Noobs read threads too...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 305
  • I use FPC [main] 💪🐯💪
Re: Initialize list in function parameter
« Reply #12 on: November 08, 2025, 02:27:18 pm »
But may I ask what happended behind
as I noticed that:
1. in other routines I always declare string variables as string(or ansistring),rarelly  as widestring or unicode string,they (type string) all displayed properly with utf8 sets.
2. in this example,when changing name from string to unicodestring,data[0].vstring|vWideString|vUnicodeString all works as expected.

I apologize, but it is difficult to explain in a few words, and I am concerned that a detailed and understandable explanation would take a long time to convey in writing.

But I can probably say that it's all because the compiler inserts implicit string format conversion calls, and code pages are also taken into account.

The easiest way to understand this is to compile FPC with debug information and go through the functions using F7/F8.

Another option you can practice with:

Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$mode objfpc}{$h+}
  3. //{$codepage utf8}
  4. {$modeswitch advancedrecords}
  5.  
  6. uses gvector;
  7.  
  8. type
  9.   TFruit=record
  10.     name: String;
  11.     color: Integer;
  12.     class operator :=(const data: array of const): TFruit;
  13.   end;
  14.  
  15. class operator TFruit.:=(const data: array of const): TFruit;
  16. begin
  17.   case data[0].VType of
  18.     vtAnsiString: Result.name := String(data[0].VAnsiString);
  19.     vtUnicodeString: Result.name := UnicodeString(data[0].VUnicodeString);
  20.   end;
  21.  
  22.   Result.color:=data[1].VInteger;
  23. end;
  24.  
  25. procedure print(s: String);
  26. begin
  27.   WriteLn(s);
  28. end;
  29.  
  30. begin
  31.   with (specialize TVector<TFruit>.Create) do
  32.   begin
  33.     pushback(['apple',1]);
  34.     WriteLn(items[0].name);
  35.     Free;
  36.   end;
  37.  
  38.   print('apple');
  39.   ReadLn;
  40. end.
I may seem rude - please don't take it personally

PascalDragon

  • Hero Member
  • *****
  • Posts: 6235
  • Compiler Developer
Re: Initialize list in function parameter
« Reply #13 on: November 08, 2025, 06:24:02 pm »
It is not a bug in gvector. The syntax: (name:'pear';color:255) should be allowed as parameter when the parameter is of type TFruit.
I am almost sure this is intended to work, but doesn't. It should not even need a cast.

It is definitely not intended to work. Untyped record constants are simply not supported which this would require. Variables and typds constants simply have specific initializers which are not general purpose expressions. Not to mention that even if it would work then you would get problems if you had an overload of the function which accepts two different records that happen to have the same field names.

If untyped record constants will ever be supported they'd use the same syntax that ISO Extended Pascal uses: TFruit[name:'pear'; color: 255].

PeterHu

  • Jr. Member
  • **
  • Posts: 60
Re: Initialize list in function parameter
« Reply #14 on: November 09, 2025, 03:56:26 am »

Another option you can practice with:

Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$mode objfpc}{$h+}
  3. //{$codepage utf8}
  4. {$modeswitch advancedrecords}
  5.  
  6. uses gvector;
  7.  
  8. type
  9.   TFruit=record
  10.     name: String;
  11.     color: Integer;
  12.     class operator :=(const data: array of const): TFruit;
  13.   end;
  14.  
  15. class operator TFruit.:=(const data: array of const): TFruit;
  16. begin
  17.   case data[0].VType of
  18.     vtAnsiString: Result.name := String(data[0].VAnsiString);
  19.     vtUnicodeString: Result.name := UnicodeString(data[0].VUnicodeString);
  20.   end;
  21.  
  22.   Result.color:=data[1].VInteger;
  23. end;
  24.  
  25. procedure print(s: String);
  26. begin
  27.   WriteLn(s);
  28. end;
  29.  
  30. begin
  31.   with (specialize TVector<TFruit>.Create) do
  32.   begin
  33.     pushback(['apple',1]);
  34.     WriteLn(items[0].name);
  35.     Free;
  36.   end;
  37.  
  38.   print('apple');
  39.   ReadLn;
  40. end.

Thanks.This version is easier to understand to me.I see it as if data( const array of const) is make up of 'Variant' type.

 

TinyPortal © 2005-2018