Is there any way to set default record values? lazarus / 21-General ---------------------------------------------------------------------- egsuh · 2023-11-24 07:19 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    RMyRecord = record        i : integer;        s : string;    end;  procedure Test (a, b: integer; myRec:RMyRecord = (i:0; s:'')); will this work? ---------------------------------------------------------------------- balazsszekely · 2023-11-24 08:42 1. With advanced records: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; {$mode objfpc}{$H+}{$modeswitch ADVANCEDRECORDS} uses  {$IFDEF UNIX}  cthreads,  {$ENDIF}  Classes; type  TMyRecord = record    FInt: Integer;    FStr: String;  public    constructor Create(AInt: Integer; AStr: String);  end; constructor TMyRecord.Create(AInt: Integer; AStr: String);begin  FInt := AInt;  FStr := AStr;end; var  MyRecord: TMyRecord;begin  MyRecord := TMyRecord.Create(0, 'test');  Writeln(MyRecord.FInt);  Writeln(MyRecord.FStr);end.   2. With constant record Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; {$mode objfpc}{$H+} uses  {$IFDEF UNIX}  cthreads,  {$ENDIF}  Classes; type  TMyRecord = record    FInt: Integer;    FStr: String;  end; const  cMyDefRecord: TMyRecord = (FInt: 0; FStr: 'test');var  MyRecord: TMyRecord;begin  MyRecord := TMyRecord(cMyDefRecord);  Writeln(MyRecord.FInt);  Writeln(MyRecord.FStr);end. ---------------------------------------------------------------------- Warfley · 2023-11-24 08:45 With function overloading: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure Test(a, b: integer; myRec:RMyRecord);... procedure Test(a, b: integer); inline;const  defRec: RMyRecord = (0, 'test');begin  Test(a, b, defRec);end; ---------------------------------------------------------------------- jamie · 2023-11-24 12:14 IT would be nice if the compiler could call a Function that returns the expected type for a Default parameter. This would make it a lot of sense to me. But in any case, how about employing the managed Class operator initialize for the record? ---------------------------------------------------------------------- Zvoni · 2023-11-24 13:19 Well, if we're fooling around..... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1;{$modeswitch advancedrecords} Type  PRec = ^TRec;  TRec = Record    Fint:Integer;    FStr:String;    class operator initialize(var arec:TRec);  end; Procedure test(a, b:Integer;aRec:PRec=Nil);Var  c:Boolean;Begin  c:=Assigned(Arec);  If not c Then new(arec);  Writeln(arec^.Fint);  Writeln(arec^.FStr);  If Not c then Dispose(arec);End; Var  b,c:Trec; class operator TRec.initialize(var arec: TRec);begin  arec.Fint:=42;  arec.FStr:='I''m your father...';end; begin  b.fint:=128;  b.FStr:='Some test';  test(0,1);  test(0,1,@b);  test(0,1,@c); end. ---------------------------------------------------------------------- Warfley · 2023-11-24 17:17 Quote from: jamie on November 24, 2023, 01:14:45 pmIT would be nice if the compiler could call a Function that returns the expected type for a Default parameter. The question then is, when is the function called, once or on every function call? Because python implements it only once, which gets the following behavior, which can be extremely frustrating: Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i def foo(lst: List[int] = []) -> List[int]:  lst.Add(1)  return lst print(foo()) # prints [1]print(foo()) # prints [1, 1] The reason for this is that the value is set at "compile time" (in python more or less at startup) to reference a global object, so every subsequent call gets the same object, so modifications to that object will carry throughout subsequent calls. It may seem obvious to then use the alternative, to only call the function every time, and while it fixes the problem above, in a lot of situations you may want to use something constant (e.g. in the example that is in this thread, as records are copy by value, it should simply be a copy of the same record every time). In those cases, it would massively impair the performance to have an additional function call, if you could just call the function once, and simply copy the result. The best way to solve this is to simply not allow it, and use function overloading instead. This behaves exactly like a default parameter, while allowing you to customize it completely to your needs ---------------------------------------------------------------------- ASerge · 2023-11-24 18:27 Quote from: Warfley on November 24, 2023, 09:45:36 amWith function overloading: +1 ---------------------------------------------------------------------- jamie · 2023-11-24 20:11 I don't get it? Either we are not on the same page, or someone does not understand what I am talking about? What is the difference between these two? procedure  name(SomeInput:Integer; SomeOption:Integer=1); and this Procedure Name(SomeInput:Integer;Someoption:integer=SomeFunctionThatre turnsAInteger); From what I am grasping here, either way, one that is currently supported and one that would fail from whatever scenario you are talking about.  The only issue is the compiler can only allow one or the other definition.  The idea was to simply define a procedure/Function that would accept only a function or a constant as a default. Thus, Name(SomeIntegerInput); would resolve to either the constant or the function type, which ever one you declared. or you could simply specify it on the fly.  Name(1, 3);  of course, you need to implement the default function too and that can come with parameter options on top of that. We already have that kind of flex manually, no reason the compiler can't figure that out as a default function in cases of these prototypes. I see a worldwide view of advantages here. Oh well, don't mind me. I am just some old fart getting ready to collect on the GOV. ---------------------------------------------------------------------- Warfley · 2023-11-24 20:26 Quote from: jamie on November 24, 2023, 09:11:02 pmI don't get it? Either we are not on the same page, or someone does not understand what I am talking about? What is the difference between these two? procedure  name(SomeInput:Integer; SomeOption:Integer=1); and this Procedure Name(SomeInput:Integer;Someoption:integer=SomeFunctionThatre turnsAInteger); The first is constant and known at compile time, the second requires evaluation at runtime. So the question is, when will that evaluation happen? Only once and then the same result is used in every subsequent call, or every time the function is called. This is a very important question, because if it is called only once and reused afterwards, the compiler can do a lot of neat optimizations and can make this really fast, and would be the closest to what is currently supportet with compile time constants. This is why python is doing it that way (speed is a very important consideration for interpreted languages) If you perform the call every time, that gives you more flexibility, but also gives a performance penalty. Note that I'm the last person who cares about performance, the average program will spend most of the time waiting for IO or user inputs, etc. so in 90% of all cases the performance does not matter. But while I don't think the performance penalty is a problem in it self, it's a performance penalty that the user of the function is responsible, but the implementation of which is up to the implementer of the function. If I have the following function: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure  foo(bar: Integer=1);And it is replaced with: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure  foo(bar: Integer=FooBar);and FooBar is some non trivial function, I need to treat calls to foo completely differently. It changes the whole dynamic on how optional parameters work right now. Also note that you already can archieve the exact same thing: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure foo(bar: Integer);... procedure foo; inline;begin  foo(FooBar);end; It's 4 additional lines of code, not pretty, but also not that much effort that it warrants completly chaning the underlying assumptions about how default parameters operate. ---------------------------------------------------------------------- PascalDragon · 2023-11-25 17:02 Quote from: egsuh on November 24, 2023, 08:19:17 am Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type    RMyRecord = record        i : integer;        s : string;    end;  procedure Test (a, b: integer; myRec:RMyRecord = (i:0; s:'')); will this work? No. Only untyped constants are supported for default parameters and for record types untyped constants are not supported. ---------------------------------------------------------------------- egsuh · 2023-11-26 04:20 This seems the practical approach. QuoteWith function overloading:     procedure Test(a, b: integer; myRec:RMyRecord);     ...         procedure Test(a, b: integer); inline;     const       defRec: RMyRecord = (0, 'test');     begin       Test(a, b, defRec);     end; What's difference between using "inline" instead of simply "overload"? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     procedure Test(a, b: integer; myRec:RMyRecord); overload;     procedure Test(a, b: integer); overload; ---------------------------------------------------------------------- egsuh · 2023-11-26 04:25 QuoteWhat's difference between using "inline" instead of simply "overload"? I got it. Thank you for your example.