Recent

Author Topic: Use Array of Const in a variable  (Read 4333 times)

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Use Array of Const in a variable
« Reply #15 on: January 24, 2023, 01:20:55 pm »
You still not understand. Do not type it direct. Everything is already in RTL.
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$IFDEF MSWINDOWS}{$APPTYPE CONSOLE}{$ENDIF}
  3.  
  4. (*
  5. you can extend the "TestIt" with more types...
  6. const
  7.    vtInteger       = 0;
  8.    vtBoolean       = 1;
  9.    vtChar          = 2;
  10. {$ifndef FPUNONE}
  11.    vtExtended      = 3;
  12. {$endif}
  13.    vtString        = 4;
  14.    vtPointer       = 5;
  15.    vtPChar         = 6;
  16.    vtObject        = 7;
  17.    vtClass         = 8;
  18.    vtWideChar      = 9;
  19.    vtPWideChar     = 10;
  20.    vtAnsiString    = 11;
  21.    vtCurrency      = 12;
  22.    vtVariant       = 13;
  23.    vtInterface     = 14;
  24.    vtWideString    = 15;
  25.    vtInt64         = 16;
  26.    vtQWord         = 17;
  27.    vtUnicodeString = 18;
  28. *)
  29.  
  30. procedure TestIt(const AArgs: array of const);
  31. var
  32.   I : longint;
  33. begin
  34.   If High(AArgs)<0 then
  35.     begin
  36.       Writeln ('No aguments');
  37.       exit;
  38.     end;
  39.   Writeln ('Got ',High(AArgs)+1,' arguments :');
  40.   for i:= Low(AArgs) to High(AArgs) do
  41.     begin
  42.       write ('Argument ',i,' has type ');
  43.       case AArgs[i].vtype of
  44.         vtinteger    :
  45.           Writeln ('Integer, Value : ' , AArgs[i].vinteger);
  46.         vtboolean    :
  47.           Writeln ('Boolean, Value : ' , AArgs[i].vboolean);
  48.         vtchar       :
  49.           Writeln ('Char, value : ' , AArgs[i].vchar);
  50.         vtextended   :
  51.           Writeln ('Extended, value : ', AArgs[i].VExtended^);
  52.         vtString     :
  53.           Writeln ('ShortString, value : ', AArgs[i].VString^);
  54.         vtPointer    :
  55.           Writeln ('Pointer, value : ', Longint(AArgs[i].VPointer));
  56.         vtPChar      :
  57.           Writeln ('PChar, value : ', AArgs[i].VPChar);
  58.         vtObject     :
  59.           Writeln ('Object, name : ', AArgs[i].VObject.Classname);
  60.         vtClass      :
  61.           Writeln ('Class reference, name : ', AArgs[i].VClass.Classname);
  62.         vtAnsiString :
  63.           Writeln ('AnsiString, value : ', AnsiString(AArgs[I].VAnsiString));
  64.       else
  65.         Writeln ('(Unknown) : ', AArgs[i].vtype);
  66.       end;
  67.     end;
  68. end;
  69.  
  70. begin
  71.   TestIt([123, True, 'AnsiString']);
  72.   ReadLn;
  73. end.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Use Array of Const in a variable
« Reply #16 on: January 24, 2023, 01:21:22 pm »
and even if it would work, it would mean to use a temporary s variable.

Like I said: pita  :D

Code: Pascal  [Select][+][-]
  1. program varrecstring;
  2.  
  3. {$mode objfpc}{$H+}
  4. type
  5.   tConstArray  = array of TVarRec;
  6.  
  7. procedure a(const x: array of const);
  8. var
  9.  i: integer;
  10. begin
  11.   For i:=0 to High(x) do
  12.   begin
  13.     write ('Argument ',i,' has type ');
  14.     case x[i].vtype of
  15.        vtAnsiString :  Writeln ('AnsiString, value :',AnsiString(x[I].VAnsiString));
  16.     end;
  17.   end;
  18. end;
  19.  
  20. var
  21.   S : string = 'hello';
  22.   x : TConstArray;
  23. begin
  24.   S := 'goodbye';
  25.   setlength(x,1);
  26.   x[0].vtype := vtAnsiString;
  27.   x[0].VAnsiString := Pointer(S);
  28.   a(x);
  29. end.
  30.  

@KodeZwerg:
I have a hunch that TS main issue is the dynamic creation of such an varrec array. That is what TS seems to be wanting and that is a pita. Ofc. you can sugarcoat it by using wrappers or otherwise.
« Last Edit: January 24, 2023, 01:30:17 pm by TRon »
Today is tomorrow's yesterday.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Use Array of Const in a variable
« Reply #17 on: January 24, 2023, 01:41:17 pm »
@KodeZwerg:
I have a hunch that TS main issue is the dynamic creation of such an varrec array. That is what TS seems to be wanting and that is a pita. Ofc. you can sugarcoat it by using wrappers or otherwise.
Okay, but than I would call within "TestIt" proper methods for the unknown input... but yes, I still might not be fully into this issue  :-[

Ahh now I understand it and yes, such you need to build up piece by piece like TRon showed.
« Last Edit: January 24, 2023, 01:45:12 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Use Array of Const in a variable
« Reply #18 on: January 24, 2023, 01:45:49 pm »
To me it is simply unwillingness to understand array of const, which means an array of at the point of call yet not determined number of parameters only! used as parameters and other things that are called arrays, which are actually arrays.

Array of const has its use but:
a) It is sloowwwww. Due to underlying varrec. Don't use it in loops...
b) It is only meant for parameter passing. And ONLY that!
c) Used and discussed in this way above it is - extremely - bad design since there is a performance requirement.

I know where it comes from: just the naming convention for array of const vs other/real  array types is misleading.
Array of const is merely varargs in other languages like in C.
Inappropiately chosen wording in the language definition, alas.
« Last Edit: January 24, 2023, 01:55:37 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

alpine

  • Hero Member
  • *****
  • Posts: 1412
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

jollytall

  • Sr. Member
  • ****
  • Posts: 377
Re: Use Array of Const in a variable
« Reply #20 on: January 24, 2023, 02:42:57 pm »
@TRon,

Thanks, that was it. I tried @s, while it should have been pointer(s).

@Thaddy,

Thanks, Yes, I try to solve something that is needed due to the complex design of TensorFlow, far beyond me. Probably I will have to pass an array of pointers and another array with the type of the actual variables in the first array.
This is btw. very much in line with the way, how arguments are also built in three arrays, one array of string with the argument name, one with the argument type (array of integer, with types having their code, just like in tVarRec) and a third one with the pointers pointing to the values.

@alpine

Thanks, that wrapper looks interesting, but as I can only have a very limited number of types (two for inputs and if I need to mix in then two more for outputs) a second array with the type (or with a boolean if only two need to be separated) seems easier at this point.

Warfley

  • Hero Member
  • *****
  • Posts: 2038
Re: Use Array of Const in a variable
« Reply #21 on: January 24, 2023, 03:33:47 pm »
My advice, stay away from Variants. They try to provide type polymorphism on a very general level, such that they are quite complicated to use, while also still being limited to only base types.

If you want to use type polymorphism, the best way is to simply create your own polymorphic types. For example, a while ago I implemented a TUnion type, which allows to have a data type that can be one of two types: https://github.com/Warfley/ObjPasUtils/tree/master/src/dynamictypes
Code: Pascal  [Select][+][-]
  1. var
  2.   union: TUnion<String, Integer>;
  3. begin
  4.   union := EmptyUnion; // Empty
  5.   union := None; // Same as EmptyUnion;
  6.   union := 'Hello World'; // Set the value to being a string
  7.   union := 42; // Set the value to being an integer
  8.   // Accessing
  9.   if union.isFirst then
  10.     WriteLn('Union is String: ', Union.First);
  11.   if union.isSecond then
  12.     WriteLn('Union is Integer: ', Union.Second);
You can of course extend this to your own liking with as many types as you wish.

This gives you much more flexibility than Variants (as variants can for example not hold record types), while the definition and usage is under your full control, as you create your own types, when you don't like something, you can just change it.

Variants are a relic from a time where due to lack of modern language features, such as operator overloading, management operators or generics, there was no easy way to build this yourself, so variant with it's derivates like array of const and co where introduced, which does the same things you can now do yourself with these new features, but with a lot of compiler magic hardcoded.

It's simply not really necessary anymore
« Last Edit: January 24, 2023, 03:39:10 pm by Warfley »

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Use Array of Const in a variable
« Reply #22 on: January 24, 2023, 06:54:01 pm »
You may also be interested in the manual, of course:
https://www.freepascal.org/docs-html/3.0.0/ref/refsu88.html
Note that it is not Delphi compatible but it is compatible with C and C++.
This may ease your TensorFlow solution a bit. ( be careful: cdecl need)
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

PascalDragon

  • Hero Member
  • *****
  • Posts: 6322
  • Compiler Developer
Re: Use Array of Const in a variable
« Reply #23 on: January 24, 2023, 10:01:19 pm »
Depending on the types you want to support I would consider using an array of Variant - or in Delphi I would probably use an array of TValue - I don't know how far the development of System.Rtti is in the FPC RTL.

With 3.2.2 it works for most types:

Code: Pascal  [Select][+][-]
  1. program trtti;
  2.  
  3. uses
  4.   Rtti;
  5.  
  6. procedure Test(aArg: array of TValue);
  7. begin
  8. end;
  9.  
  10. procedure Test2(aArg: TValueArray);
  11. begin
  12. end;
  13.  
  14. var
  15.   arr: TValueArray;
  16. begin
  17.   Test([42, 'Test']);
  18.   Test2([42, 'Test']);
  19.   arr := [42, 'Test'];
  20.   Test2(arr);
  21. end.

Array of const has its use but:
a) It is sloowwwww. Due to underlying varrec. Don't use it in loops...

No, it's not. It's faster than Variant or TValue as the compiler constructs an open array on the stack and simply assigns the values.

You may also be interested in the manual, of course:
https://www.freepascal.org/docs-html/3.0.0/ref/refsu88.html
Note that it is not Delphi compatible but it is compatible with C and C++.
This may ease your TensorFlow solution a bit. ( be careful: cdecl need)

varargs can only be used for external functions thus if you want to create convenient Pascal wrappers for C functions you can't use that.

 

TinyPortal © 2005-2018