Wishlist - (language evolution) lazarus / 64-FPC development ---------------------------------------------------------------------- AlanTheBeast · 2022-07-14 21:52 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 1. Endcase;          // I resort to     end; {case} 2. VAR init lists: 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 VAR     i,j,k: billionbitword = 0; 3. Non 0 based re-dimension of arrays.  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       G: array of array of grapefruit;...     SetLength (G, [1..12],[1..6]); 4. Non-declared local ordinals. Ideally in register.  Only within loop blocks. 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 j := BobIQ;                    // j in scope, i does not existfor i := 1 to Q do  begin         SnapSUM (i, j);     // i is an ordinal of the same type as the for statement range.  If Q=Word, i:word;         PorkBelly(i*x);    end;                          // i ceases to exist ... Repeat     i := 23+j;Until i>400000;            // ceases to exist.  Type has to support the range of j to 400000 ... While j>10 do               //j exists, i doesn't       begin          i := j mod 3;      // i....          littlepiggy(j,i);       end;   5. Ada like value strings; 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             RunwayLength : Float := 2_500.0; ---------------------------------------------------------------------- Martin_fr · 2022-07-14 22:02 At least 2 (init list) and 4 (non declared local) have been discussed to the full extend before..... IIRC more than once. ---------------------------------------------------------------------- AlanTheBeast · 2022-07-14 22:11 Quote from: Martin_fr on July 15, 2022, 12:02:54 amAt least 2 (init list) and 4 (non declared local) have been discussed to the full extend before..... IIRC more than once. I brought up the non-declared local many years ago and got royally tarred and feathered for it.  Not sure if anyone beat me to it. init list I saw someone bring up a year or so ago.  Wasn't fresh then IIRC. ---------------------------------------------------------------------- PascalDragon · 2022-07-15 13:22 Quote from: AlanTheBeast on July 14, 2022, 11:52:40 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 1. Endcase;          // I resort to     end; {case} No. Quote from: AlanTheBeast on July 14, 2022, 11:52:40 pm2. VAR init lists: 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 VAR     i,j,k: billionbitword = 0; Was discussed many times already. Quote from: AlanTheBeast on July 14, 2022, 11:52:40 pm3. Non 0 based re-dimension of arrays.  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       G: array of array of grapefruit;...     SetLength (G, [1..12],[1..6]); No. Quote from: AlanTheBeast on July 14, 2022, 11:52:40 pm4. Non-declared local ordinals. Ideally in register.  Only within loop blocks. 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 j := BobIQ;                    // j in scope, i does not existfor i := 1 to Q do  begin         SnapSUM (i, j);     // i is an ordinal of the same type as the for statement range.  If Q=Word, i:word;         PorkBelly(i*x);    end;                          // i ceases to exist ... Repeat     i := 23+j;Until i>400000;            // ceases to exist.  Type has to support the range of j to 400000 ... While j>10 do               //j exists, i doesn't       begin          i := j mod 3;      // i....          littlepiggy(j,i);       end;   No. Quote from: AlanTheBeast on July 14, 2022, 11:52:40 pm5. Ada like value strings; 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             RunwayLength : Float := 2_500.0; Already supported in main. ---------------------------------------------------------------------- AlanTheBeast · 2022-07-15 15:00 Quote from: PascalDragon on July 15, 2022, 03:22:21 pm Quote from: AlanTheBeast on July 14, 2022, 11:52:40 pm5. Ada like value strings; 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             RunwayLength : Float := 2_500.0; Already supported in main. I'll update from 3.2.0 then ... is this Delphi dependent? ---------------------------------------------------------------------- 440bx · 2022-07-15 15:05 Quote from: PascalDragon on July 15, 2022, 03:22:21 pmQuote from: AlanTheBeast on July 14, 2022, 11:52:40 pm2. VAR init lists: 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 VAR     i,j,k: billionbitword = 0; Was discussed many times already. Just a thought, it would probably no longer be discussed if that feature were included in the compiler.  That would really help prevent future discussions   Plus, I believe I read a while back that a compiler developer had already done about half the work for it. Actually, a feature I'd really like to see is, some sort of optional directive, a la, "inline" that would tell the compiler to zero out the entire space reserved for local variables, something like "Initlocals" after the procedure/function declaration. That would save a number of "ZeroMemory(@structure, sizeof(structure))" and would ensure that none are overlooked.  That would be very useful. ---------------------------------------------------------------------- Martin_fr · 2022-07-15 15:37 Quote from: 440bx on July 15, 2022, 05:05:45 pmQuote from: PascalDragon on July 15, 2022, 03:22:21 pmWas discussed many times already. Just a thought, it would probably no longer be discussed if that feature were included in the compiler.  That would really help prevent future discussions Or the discussion would then be: Just an idea, can this feature be removed...? QuoteThat would save a number of "ZeroMemory(@structure, sizeof(structure))" and would ensure that none are overlooked.  That would be very useful. Well, isn't that what "structure := Default(TStructure);" is for? Or should I insinuate that you crafted the code with certain intention to portrait the image of complexity in such a way that the lack of necessity for its overly extended syntax may be overlooked by the audience and the subtle hidden implication of a greater need than actually exists will be instilled into the readers mind? SCNR ---------------------------------------------------------------------- 440bx · 2022-07-15 16:03 Quote from: Martin_fr on July 15, 2022, 05:37:37 pmQuote from: 440bx on July 15, 2022, 05:05:45 pmQuote from: PascalDragon on July 15, 2022, 03:22:21 pmWas discussed many times already. Just a thought, it would probably no longer be discussed if that feature were included in the compiler.  That would really help prevent future discussions Or the discussion would then be: Just an idea, can this feature be removed...? Quote from: Martin_fr on July 15, 2022, 05:37:37 pmWell, isn't that what "structure := Default(TStructure);" is for? Or should I insinuate that you crafted the code with certain intention to portrait the image of complexity in such a way that the lack of necessity for its overly extended syntax may be overlooked by the audience and the subtle hidden implication of a greater need than actually exists will be instilled into the readers mind? SCNR You're really inspired today.  The "structure := default(TStructure);" has a number of problems, among them, the programmer has to remember (and type) that structure is of type TStructure and, are the "default" values always binary zeroes ? or are they different depending on the field type ? and, lastly, it still requires ensuring that every structure has been "defaulted".  A simple "Initlocals" or "zerolocals" (I'm liking "zerolocals" better now) initializes everything, regardless of type and without requiring the programmer to ensure every structure has been individually initialized.  This is the kind of minutiae compilers should take care of. (simpler than the -gt stuff that is already in FPC) Something along the lines of "zerolocals" would be great to have.  One directive and done!  I would even like to see it as as default behavior for all functions/procedures based on some "modeswitch" or something similar. ---------------------------------------------------------------------- Martin_fr · 2022-07-15 16:36 Quote from: 440bx on July 15, 2022, 06:03:32 pmThe "structure := default(TStructure);" has a number of problems, among them, the programmer has to remember (and type) that structure is of type TStructure We are talking about local vars. And only local vars. And about code that initializes them, code that is at the very top of the routine. Code that is immediately below the declaration of the variables. If the amount of local vars is so big, that you can't see their declaration, then maybe - just maybe - there is a different issue..... Otherwise, the type-name you need, is right there. Quote and, are the "default" values always binary zeroes ? Is all zero always the correct behaviour? 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   TFoo = (foo1 = 11, foo2 = 21);  TBar = 100..110;var   aFoo: TFoo;  aBar: TBar; Initializing aFoo/aBar with zero creates an invalid value. And invalid values can lead to unpredictable behaviour. Upgrade your compiler, or change some settings and the behaviour of your app may change unexpectedly. And if - hypothetically - an option as you advertise should ever come to be, then it should never set invalid values. So it could never be "zero all locals", but if it were to be it could only be "set all locals to default". Quoteand, lastly, it still requires ensuring that every structure has been "defaulted".  As I said "a greater need than exists". This leaves the possibility of an existing need (Clearly you have this need, and others do not). But there are needs for many a thing. Not all of them are significant enough to warrant a new feature. [1] Also, the compiler does already provide the tools to "ensure all have been defaulted" (or rather initialized). If you miss one, you get a compiler hint. --- [1] This is a general statement. This does not place you request into either group of features. However, my personal opinion (which is of no matter towards any decision that may be made on the topic) is that if there were some feature (related to local initialization) that would bring forward such a warrant, it should not be a compiler directive, or any form were *all* locals would be affected by a single command. ---------------------------------------------------------------------- 440bx · 2022-07-15 17:03 The thing is, if there is some method of telling the compiler to automatically set all the locals to binary zeroes then, when debugging, it becomes trivial to see what variables have been initialized _by the code_ or left uninitialized.  Anything else, may be inadvertently confused with a valid value but, it was just junk on the stack. Initializing variables is a good habit and, even if the initialization to zeroes produces invalid values, as your enumeration example showed, at least that's a _predictable_ invalid value instead of whatever junk may have been in the stack which may result in an invalid value or worse, a value that is in the range but not appropriate for the occasion. ---------------------------------------------------------------------- Martin_fr · 2022-07-15 17:37 Quote from: 440bx on July 15, 2022, 07:03:52 pmThe thing is, if there is some method of telling the compiler to automatically set all the locals to binary zeroes then, when debugging, it becomes trivial to see what variables have been initialized _by the code_ or left uninitialized.  Are you arguing for or against your idea? I mean "when debugging" the existing -gt does a marvellous job. Seeing $AAAAAAAA or $55555555 or IIRC $DEADBEEF => those make it more than trivial to spot if something hasn't been initialized. Yet the compiler setting values to zero, does not help spotting this in the compiler, since code could very easily initialize to 0. And that would be indistinguishable from the compiler set value. QuoteInitializing variables is a good habitAgreed. But we do have "Default(...)". And we do have the compiler hint. ---------------------------------------------------------------------- 440bx · 2022-07-15 18:21 Quote from: Martin_fr on July 15, 2022, 07:37:55 pmAre you arguing for or against your idea? I mean "when debugging" the existing -gt does a marvellous job. Seeing $AAAAAAAA or $55555555 or IIRC $DEADBEEF => those make it more than trivial to spot if something hasn't been initialized. Yet the compiler setting values to zero, does not help spotting this in the compiler, since code could very easily initialize to 0. And that would be indistinguishable from the compiler set value. I am arguing for my idea.  I _do not_ want any $AAA..or $555... or any other junk.  In the majority of cases, binary zeroes is the natural initial value and if a variable requires a different value then it can be initialized with that value. For instance, 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 var  MyVariable : integer = 5;the compiler would initialize it to 5 _after_ the code that initializes to zeroes has executed. This way, things keep working just the way they work now but, all "un- initialized" variables have the value zero instead of whatever junk was on the stack. ---------------------------------------------------------------------- Martin_fr · 2022-07-15 19:07 All of the below is only about your "when debugging...." case. Nothing else. Quote from: 440bx on July 15, 2022, 08:21:06 pmI am arguing for my idea.  I _do not_ want any $AAA..or $555... or any other junk. .... I have the feeling you are switching between 2 points here. That very last post of yours reads as if you argue for the zero-ing a general tool. I.e. something that makes it into production code. (i.e. not specially for testing, but part of the actual functionality of that code). If so => That is not what I had replied to in my post In my post before, I was explicitly answering to you saying: Quotewhen debugging, it becomes trivial to see what variables have been initialized _by the code_ or left uninitialized And really when debugging the -gt AAAA/5555/DEADBEAF are easier to spot, because they are distinguishable from a zero that was set by user-code. Those values may not be good for production code. But they are for debugging. So let me ask: Do you believe finding an uninitialized (i.e. not initialized by code) value by watching values in the debugger is easier if that value is 0? As "for trash on the stack": zero is as likely as every other value. In fact it may be likelier... Zero could be on the stack from a previous value on that location. (as could many other values). But compared to zero, how often does data in your apps take the value of "DEADBEAF" ? Please explain to me, when debugging this code 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; zero_all_locals;var a: integer;begin  a := 0;  bar(a);  On line 5: How do you know, if a=0 means the value was or was not initialized by user code? And yes, same problem with -gttt, if your code goes "a := $DEADBEAF;". Only what happens more often in code? "a := 0;" or "a:=$DEADBEAF;" ? ---------------------------------------------------------------------- 440bx · 2022-07-15 20:02 Quote from: Martin_fr on July 15, 2022, 09:07:13 pmI have the feeling you are switching between 2 points here. No, I'm just stating that there is more than 1 reason why this would be a nice feature to have. Quote from: Martin_fr on July 15, 2022, 09:07:13 pmThat very last post of yours reads as if you argue for the zero-ing a general tool. I.e. something that makes it into production code. (i.e. not specially for testing, but part of the actual functionality of that code). Production code often has to be debugged too. Quote from: Martin_fr on July 15, 2022, 09:07:13 pmAnd really when debugging the -gt AAAA/5555/DEADBEAF are easier to spot, because they are distinguishable from a zero that was set by user-code. That stuff is noise.  As I stated before, zeroes is the _natural_ initial value and it is the "clean" value.  I don't want any $AAA or whatever other junk. Quote from: Martin_fr on July 15, 2022, 09:07:13 pmAs "for trash on the stack": zero is as likely as every other value. I've looked at values on the stack often enough to know that zero is not nearly as common as other junk such as old return addresses, old stack pointers and, stale values from other functions/procedures. Quote from: Martin_fr on July 15, 2022, 09:07:13 pmIn fact it may be likelier... Zero could be on the stack from a previous value on that location. (as could many other values). But compared to zero, how often does data in your apps take the value of "DEADBEAF" ? The problem is that often the value is displayed in decimal instead of hex and, -gt doesn't put DEADBEEF and, no value is as commonly useful as zero.  Zero is the natural initialization value.  That's why it would be very useful to have the option of telling the compiler to set all locals to zeroes. Quote from: Martin_fr on July 15, 2022, 09:07:13 pmOn line 5: How do you know, if a=0 means the value was or was not initialized by user code? There cannot be certainty but, the probability is high that it was set by user code and, the probability is also reasonably high that it should eventually be set to a different value. Quote from: Martin_fr on July 15, 2022, 09:07:13 pmAnd yes, same problem with -gttt, if your code goes "a := $DEADBEAF;". Only what happens more often in code? "a := 0;" or "a:=$DEADBEAF;" ? You got something against binary zeroes ?  They are much more often useful than $DEADBEEF. ---------------------------------------------------------------------- Martin_fr · 2022-07-15 21:02 QuoteI'm just stating that there is more than 1 reasonI did at no point challenge that. (i.e. that you have more than one reason) But I though I made it very clear, that I had responded to ONE (and just that one) reason, that you had given at one point. And any response to (or looking at) my response that ignorers this context, will of course not find any sense in my response. So kindly in response to this post of mine => stick to that one reason (which after all was one that you gave) Now I am looking at your latest response. And I try to read it as being in the context (and only in the context) that I had clearly identified as being the one in which my statements have to be read. If I prefix any of your sentences with "When I debug my app, and I want to see if my code initialized the value, then ...." And the only sentences in your reply that indeed makes sense are 1) QuoteThe problem is that often the value is displayed in decimal instead of hexMaybe the debugger should detect those values, and default to show them in hex.... 2) Quote from: 440bx on July 15, 2022, 10:02:55 pmQuote from: Martin_fr on July 15, 2022, 09:07:13 pmOn line 5: How do you know, if a=0 means the value was or was not initialized by user code? There cannot be certainty but, the probability is high that it was set by user code and, the probability is also reasonably high that it should eventually be set to a different value. On topic, but while being on topic, it argues against your point. If (for the value zero): "the probability is high that it was set by user code" => then how can the value zero (also set by the compiler) be helpful to find cases where it was not set by user code. You just said, that probability of the opposite was high. ---------------------------------------------------------------------- kupferstecher · 2022-07-15 22:05 Quote from: 440bx on July 15, 2022, 06:03:32 pmSomething along the lines of "zerolocals" would be great to have.  One directive and done!  I would even like to see it as as default behavior for all functions/procedures based on some "modeswitch" or something similar. I think a modeswitch to activate local var initialization for the whole unit would be more useful. And I'd would rather use it for productive code to make it more fail safe. (But probably wouldn't for performance considerations~). ==== 6. I'd wish for static local variables to replace the misleading writable typed constant stuff (the latter should be default off in mode objfpc). So 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;var  CallCount: Integer = 0; static;begin  CallCount:= CallCount +1;  //...end; Although the variable could be just placed outside the function, for the sake of language completeness it should be available. ==== 7. I'd wish for a placeholder for the left side of an assignment that can be used in the right side. A suitable keyword could be "this". 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 CallCount:= this + 1;Form1.Image1.Picture.Bitmap.Width:= this + 100; SomeVal:= this + k / this; ---------------------------------------------------------------------- ccrause · 2022-07-16 06:22 Quote from: kupferstecher on July 16, 2022, 12:05:27 am==== 6. I'd wish for static local variables to replace the misleading writable typed constant stuff (the latter should be default off in mode objfpc). Indeed, I wish for the keyword const to simply mean runtime constant, in all cases ---------------------------------------------------------------------- MarkMLl · 2022-07-16 06:42 Quote from: Martin_fr on July 15, 2022, 11:02:35 pmQuoteThe problem is that often the value is displayed in decimal instead of hexMaybe the debugger should detect those values, and default to show them in hex.... At the very least, an option to change the default from dismal to- well, basically anything else would be extremely useful. Also an option to use some different character for the overall delineation of strings to avoid confusion when looking at something which is itself quoted... surely there's some suitable UTF-8 character for this? MarkMLl ---------------------------------------------------------------------- 440bx · 2022-07-16 08:34 Quote from: Martin_fr on July 15, 2022, 11:02:35 pmBut I though I made it very clear, that I had responded to ONE (and just that one) reason, that you had given at one point. And any response to (or looking at) my response that ignorers this context, will of course not find any sense in my response. Honestly, by now, I don't think I know what it is we're arguing about. Keeping things simple, I'd like to have the compiler provide some facility to tell it to initialize all local variables to binary zeroes. Among many reasons are: it's nice to have variables automatically initialized to an easily recognizable, consistent value.  The value "binary zeroes" is, almost always, the natural, most useful, initial value. It's that simple.  Any value that is not binary zeroes is simply not as useful and identifiable as an initial value as binary zeroes. ---------------------------------------------------------------------- dseligo · 2022-07-16 08:36 Quote from: ccrause on July 16, 2022, 08:22:58 amQuote from: kupferstecher on July 16, 2022, 12:05:27 am==== 6. I'd wish for static local variables to replace the misleading writable typed constant stuff (the latter should be default off in mode objfpc). Indeed, I wish for the keyword const to simply mean runtime constant, in all cases  I believe that there is a lot of code which uses const for static variables and such change would break that code. So I think there is no chance for this to happen. ---------------------------------------------------------------------- winni · 2022-07-16 08:45 Hi! Typed constants exist since 40 years. Read more: https://forum.lazarus.freepascal.org/index.php/topic,59420.msg443069.h tml#msg443069 Winni ---------------------------------------------------------------------- Thaddy · 2022-07-16 09:24 And untyped const should always stay there: the compiler uses that at compile time and simply uses its value directly, without any storage. A typed const is always stored: in {$J-} state in a readonly section and in {$J+} state in a writable section. So that part is already covered, albeit with different semantics compared to other languages, but that has always been the case. static local variables - or global - are simply typed consts. The difference between local const and local typed const is that the latter is stored outside of the procedure in a section and does not use little stack space apart from a reference. A local untyped const will be replaced by its value at compile time so does not use any stack space at all. ---------------------------------------------------------------------- ccrause · 2022-07-16 12:30 Quote from: Thaddy on July 16, 2022, 11:24:43 amAnd untyped const should always stay there: the compiler uses that at compile time and simply uses its value directly, without any storage. A typed const is always stored: in {$J-} state in a readonly section and in {$J+} state in a writable section. So that part is already covered, albeit with different semantics compared to other languages, but that has always been the case. static local variables - or global - are simply typed consts. The difference between local const and local typed const is that the latter is stored outside of the procedure in a section and does not use little stack space apart from a reference. A local untyped const will be replaced by its value at compile time so does not use any stack space at all. Thank you for illustrating exactly why I don't like the current situation regarding the multi-faceted nature of const.  I wish for the simplicity where const simply means "this value must not be changed".  The compiler is then free to handle and enforce this contract any way it sees fit - including deciding when storage is required. There is already an alternative mechanism for declaring a variable with an initial value, no need to tack this use case to const.  Granted, this is a later development in Pascal, but should we carry the baggage of missing/poor original implementation forever?  I see no use for treating a typed const any different to an untyped const.  The programmer just informed the compiler the type associated with the value, rather than relying on the compiler to infer the type based on language rules. There isn't a Pascal alternative to specify a static local variable, hence my support for a new keyword to indicate this functionality. ---------------------------------------------------------------------- MarkMLl · 2022-07-16 12:47 Quote from: ccrause on July 16, 2022, 02:30:25 pmThank you for illustrating exactly why I don't like the current situation regarding the multi-faceted nature of const.  I wish for the simplicity where const simply means "this value must not be changed".  The compiler is then free to handle and enforce this contract any way it sees fit - including deciding when storage is required. Broadly agreed. I'd suggest that an important detail is that misuse of const as var-static could be detected and warned as deprecated by the compiler, so it would break existing code to a far lesser extent than other changes (e.g. the one to FileExists()) that have been slipped into the language and runtimes. It is specious to argue that because Borland implemented const as mutable in Turbo Pascal then it must have been what Wirth envisaged or intended, since that is definitely not something that was in Pascal /ex/ /cathedra/, and I have no reason to believe that he approved of Borland's hack by incorporating it in his later languages. In fact Wirth's definition of Modula-2 included the statement that constants would always be evaluated by the compiler, which I feel argues strongly that he considered them to be immutable. Static variables are undeniably useful, they are good style since they avoid promoting scope-limited locals to globals, and they continue the semantics of ALGOL's "own" keyword. But I'm sufficiently cautious of the existing syntax to always comment its usage as "(* Static variable *)", just as I'm sufficiently cautious to annotate exit if used inside a try-finally block. MarkMLl ---------------------------------------------------------------------- 440bx · 2022-07-16 13:09 Quote from: ccrause on July 16, 2022, 02:30:25 pmThere isn't a Pascal alternative to specify a static local variable, hence my support for a new keyword to indicate this functionality. I wholeheartedly agree with that. It's ludicrous that an identifier declared as "const" can be modified.  It renders "const" meaningless since it obviously does not mean "constant" in that context. Unfortunately, it seems that if FPC allows one way of implementing something then, a better and clearer implementation will not be considered (unless Delphi does it.) Horrible ideas get perpetuated while new ones, no matter how good they are, get fought against, tooth and nail.  No wonder progress is slow. ---------------------------------------------------------------------- Thaddy · 2022-07-16 13:30 A "static local variable" is exactly the same as a typed const in{$J+} mode. It is just semantics. Shut up  . Even languages that use the expression "static local variable" such constructs are always just a reference and stored outside local. On this topic nothing needs to change. This is wildly borderline..... ---------------------------------------------------------------------- 440bx · 2022-07-16 14:03 Thaddy, I see you are having one of your "good days". ---------------------------------------------------------------------- PascalDragon · 2022-07-16 14:52 Quote from: Martin_fr on July 15, 2022, 06:36:03 pmQuote and, are the "default" values always binary zeroes ? Is all zero always the correct behaviour? 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   TFoo = (foo1 = 11, foo2 = 21);  TBar = 100..110;var   aFoo: TFoo;  aBar: TBar; Initializing aFoo/aBar with zero creates an invalid value. And invalid values can lead to unpredictable behaviour. Upgrade your compiler, or change some settings and the behaviour of your app may change unexpectedly. Default always initializes to 0 even if that value is not valid for the given type. There could even be types for which no unambiguous default exists: 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 TTest = record  case Boolean of    True: (a: -10..-5);    False: (b: 5..10);end; Thus default simply initializes to 0 even if it would be wrong for the type. Quote from: kupferstecher on July 16, 2022, 12:05:27 am6. I'd wish for static local variables to replace the misleading writable typed constant stuff (the latter should be default off in mode objfpc). So 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;var  CallCount: Integer = 0; static;begin  CallCount:= CallCount +1;  //...end; No. There is a way to declare such a variable and thus there won't be another as unintuitive as the existing way may seem. Quote from: kupferstecher on July 16, 2022, 12:05:27 am7. I'd wish for a placeholder for the left side of an assignment that can be used in the right side. A suitable keyword could be "this". 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 CallCount:= this + 1;Form1.Image1.Picture.Bitmap.Width:= this + 100; SomeVal:= this + k / this; No. And at least for cases that don't involve properties you can use the C-style operators or for CallCount you could simply use Inc as well. ---------------------------------------------------------------------- ccrause · 2022-07-16 17:29 Quote from: Thaddy on July 16, 2022, 03:30:29 pmA "static local variable" is exactly the same as a typed const in{$J+} mode. It is just semantics. I prefer const to always mean immutable as noted by Mark.  My intention is not to introduce redundant syntax (although it my appear so), but to clean up the Pascal language to the point where explaining what const means in a program (whether a const section, const parameter or typed const (local or global)) can be described in a simple, short sentence. ---------------------------------------------------------------------- kupferstecher · 2022-07-16 20:03 Quote from: Thaddy on July 16, 2022, 03:30:29 pmA "static local variable" is exactly the same as a typed const in{$J+} mode. It is just semantics. Shut up  It's exactly the same, but the syntax is highly misleading. One of Pascals strength is it's readability. And this is a huge negative example that I would rather expect in C (no insult). And I really think this is a quirk that should be cleaned up. It's not an other call for a fancy new feature, it's just to remove the skeleton from the closet. Quote from: PascalDragon on July 16, 2022, 04:52:40 pmQuote from: kupferstecher on July 16, 2022, 12:05:27 am6. I'd wish for static local variables to replace the misleading writable typed constant stuff (the latter should be default off in mode objfpc). [...] No. There is a way to declare such a variable and thus there won't be another as unintuitive as the existing way may seem. The problem is less the unintuitive usage, but (as stated above) the bad readibility. I would nobody recommend to use a writable typed constant because of that and I also never use it myself. It's also easy to draw wrong conclusions. Lately I translated a unit from C with typed constants, using the typed constant syntax was a mistake I made just because of the misleading syntax. A (ugly) typecast in the constant would have been the correct way. In Delphi as far as I know the writable typed constant is disabled by default, but I'm not sure (don't have Delphi). Quote from: PascalDragon on July 16, 2022, 04:52:40 pmQuote from: kupferstecher on July 16, 2022, 12:05:27 am7. I'd wish for a placeholder for the left side of an assignment that can be used in the right side. A suitable keyword could be "this". [...] No. And at least for cases that don't involve properties you can use the C-style operators or for CallCount you could simply use Inc as well.The c-style operators are very ugly, so I wouldn't use it. I think a "this"-syntax would be very pascal'ish and very readable. Lately when programming for a microcontroller I had a lot of statements like the following to access hardware registers, the register name mostly has to be repeated, as only some bits are to be changed. There the "this"-syntax would be very helpful. 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   // Enable clocks  RCC.APB2PCENR:= RCC.APB2PCENR or RCC_AFIOEN or RCC_IOPBEN or RCC_USART1EN;The c-style doesn't work here (and I wouldn't us it anyways). But repeating the register name is error-prone when doing copy and past as there are often very similar names like RCC.APB1PCENR and RCC.APB2PCENR. ---------------------------------------------------------------------- MarkMLl · 2022-07-16 21:15 Quote from: ccrause on July 16, 2022, 07:29:34 pmI prefer const to always mean immutable as noted by Mark.  My intention is not to introduce redundant syntax (although it my appear so), but to clean up the Pascal language to the point where explaining what const means in a program (whether a const section, const parameter or typed const (local or global)) can be described in a simple, short sentence. There are limits to which a language can buck industry conventions, before it and the community around it becomes a laughing stock. I'm happy to argue against the periodic newbie demand that braces be accepted as an alternative to begin/end keywords. I'm prepared to tolerate the core team's refusal to even consider parameterised macros. But for some to argue that consts being mutable is defensible is... well, indefensible. The industry has eventually adopted or at least noted many of the language features introduced by Wirth in Pascal and Modula-2 (strong typing, modularisation) which in some cases might have been influenced by the UCSD and Borland Pascal implementations (plus of course Borland's Modula-2 implementation). The C and C++ communities have also looked upon Wirth's use of const, and seen that it was good. ALGOL had "own" variables. C, as a rather closer ALGOL derivative than Pascal can claim to be, has long had "static" variables. FPC, plus the tattered remains of Borland, are well out of line conflating "const" and "static". MarkMLl ---------------------------------------------------------------------- 440bx · 2022-07-16 21:34 Quote from: kupferstecher on July 16, 2022, 10:03:57 pmLately when programming for a microcontroller I had a lot of statements like the following to access hardware registers, the register name mostly has to be repeated, as only some bits are to be changed. There the "this"-syntax would be very helpful. 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   // Enable clocks  RCC.APB2PCENR:= RCC.APB2PCENR or RCC_AFIOEN or RCC_IOPBEN or RCC_USART1EN;The c-style doesn't work here (and I wouldn't us it anyways). But repeating the register name is error-prone when doing copy and past as there are often very similar names like RCC.APB1PCENR and RCC.APB2PCENR. In that example, it looks like you could have used "with RCC do" which, IMO, is clearer than "this" since what "this" is, isn't necessarily always clear, whereas "with" always names the record. ---------------------------------------------------------------------- MarkMLl · 2022-07-16 22:24 Quote from: 440bx on July 16, 2022, 11:34:12 pmIn that example, it looks like you could have used "with RCC do" which, IMO, is clearer than "this" since what "this" is, isn't necessarily always clear, whereas "with" always names the record. Although "with" is deprecated, particularly when nested. Some of the problems would be eliminated if it introduced a local constant representing the record it was abbreviating, but that was vetoed long ago. MarkMLl ---------------------------------------------------------------------- 440bx · 2022-07-16 22:41 Quote from: MarkMLl on July 17, 2022, 12:24:40 amAlthough "with" is deprecated, particularly when nested. Do you have a reference for "with" being deprecated ?... I use it all the time and, it is one of the things I miss the most when coding in C. ---------------------------------------------------------------------- MarkMLl · 2022-07-17 07:57 Quote from: 440bx on July 17, 2022, 12:41:46 amDo you have a reference for "with" being deprecated ?... I use it all the time and, it is one of the things I miss the most when coding in C. I didn't so much mean deprecated as a language feature, as that whenever discussion has focussed on it there's a stream of people decrying it because of the ambiguity it introduces. As a particular case, if code in the scope of an object refers to a local field or property and also has a with referring to another object, mayhem will ensue if an RTL modification adds a clashing name to one or the other. Which is why, in the past, there's been suggestions that a shortcut constant should be available in the block governed by the with. MarkMLl ---------------------------------------------------------------------- kupferstecher · 2022-07-17 08:51 Quote from: 440bx on July 16, 2022, 11:34:12 pmIn that example, it looks like you could have used "with RCC do" which, IMO, is clearer than "this" since what "this" is, isn't necessarily always clear, whereas "with" always names the record. The "this" concept doesn't share the ambiguity with "with", as "this" means the complete term that is assigned to. 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 RCC.APB2PCENR:= RCC.APB2PCENR or RCC_AFIOEN or RCC_IOPBEN or RCC_USART1EN;would be identical 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 RCC.APB2PCENR:= this or RCC_AFIOEN or RCC_IOPBEN or RCC_USART1EN; + very readable + reduced redundancy + less error-prone = 100% Pascal It's really a missing feature ---------------------------------------------------------------------- 440bx · 2022-07-17 09:34 Quote from: MarkMLl on July 17, 2022, 09:57:00 ambecause of the ambiguity it introduces. It's true that "with" can introduce ambiguities in a statement but, it very rarely happens when it's used correctly. For instance in the example "with RCC do... ", RCC must be in the current scope and as a result very unlikely to address an unintended field. Only one time, I've had a problem with the "with" statement and, if memory serves it is because Borland added some non-existent fields to a record used in the Winapi which just happened to be named the same as a local variable in my function.  In that case, I think the problem is with Borland sticking fields where they don't belong and not a problem with "with". It's a very useful feature which I sorely miss when coding in C, particularly when using pointers to structures. ---------------------------------------------------------------------- Martin_fr · 2022-07-17 11:57 Quote from: kupferstecher on July 17, 2022, 10:51:40 amCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i RCC.APB2PCENR:= this or RCC_AFIOEN or RCC_IOPBEN or RCC_USART1EN;+ very readable To you and you only (well and a handful of others maybe). Just thinking ahead with upcoming inlined functions, and closures.... Not sure if I get the syntax right, but something like... 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 very_long_name_foo := this + function(bar: T)   begin    SetSomeVal(this + bar); // the outer captured "this" (and bar is also the outer "this")    result := CalcRes();    result := this + Val(); // "this" is result  end(this); // execute the function in place Very readable indeed. Of course arbitrary limitations to the scoping rules could be made... Additional arbitrary rules are after all the best way to make a language clear and readable. ... not. And you can always write your own version of "include" and inline it. 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 SetRegisterBits(RCC.APB2PCENR, RCC_AFIOEN or RCC_IOPBEN or RCC_USART1EN);or 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 SetRegisterBits(RCC.APB2PCENR, [RCC_AFIOEN, RCC_IOPBEN, RCC_USART1EN]); ---------------------------------------------------------------------- marcov · 2022-07-17 12:15 Quote from: MarkMLl on July 16, 2022, 11:15:31 pm There are limits to which a language can buck industry conventions, before it and the community around it If you choose a language is not in the top 3 advocated languages for enterprise, plus one or two OSS darlings, then you are already bucking industry conventions. Quotebecomes a laughing stock. Such empty remarks are baseless, except as a whip to try to whip people into action. However the devels have gotten a thick skin after 20 years. ---------------------------------------------------------------------- MarkMLl · 2022-07-17 12:46 Quote from: marcov on July 17, 2022, 02:15:58 pmSuch empty remarks are baseless, except as a whip to try to whip people into action. However the devels have gotten a thick skin after 20 years. Was it really that long ago that I appeared on the mailing list? :-) MarkMLl ---------------------------------------------------------------------- marcov · 2022-07-17 13:11 Quote from: MarkMLl on July 17, 2022, 02:46:24 pmQuote from: marcov on July 17, 2022, 02:15:58 pmSuch empty remarks are baseless, except as a whip to try to whip people into action. However the devels have gotten a thick skin after 20 years. Was it really that long ago that I appeared on the mailing list? :-) No, not yet. But there was always comp.lang.modula2. ---------------------------------------------------------------------- 440bx · 2022-07-17 13:15 While I don't think the "writable constant" gimmick should be corrected because it is anathema to industry trends, it is really embarrassing to tell a programmer who is learning Pascal that, in order to get a static variable, the programmer has to declare a writable "constant". It's like saying, in Pascal, to draw a circle the programmer has to call the "rectangle" API.  It really makes anyone wonder what other absurdities are part of the language.  The presence of such gimmicks, justifiably, reflect poorly on the language. ---------------------------------------------------------------------- MarkMLl · 2022-07-17 13:40 Quote from: marcov on July 17, 2022, 03:11:08 pmNo, not yet. But there was always comp.lang.modula2. :-) ...where I was fairly subdued for corporate reasons. OTOH M2 was a much smaller language than the monster into which Pascal has matured, although as I've said before I still feel that there's a really nice core language in there struggling to get out. MarkMLl ---------------------------------------------------------------------- zamtmn · 2022-07-17 13:44 I'm missing simple things: https://gitlab.com/freepascal.org/fpc/source/-/issues/39527 ---------------------------------------------------------------------- marcov · 2022-07-17 13:52 Quote from: zamtmn on July 17, 2022, 03:44:02 pmI'm missing simple things: https://gitlab.com/freepascal.org/fpc/source/-/issues/39527 Just create the files if they don't exist in some prebuild event. If it is not needed, it shouldn't be in the compiler. ---------------------------------------------------------------------- zamtmn · 2022-07-17 14:03 QuoteJust create the files if they don't exist in some prebuild event. If it is not needed, it shouldn't be in the compiler. Then it will be possible to compile it only with this build tool. I'm not suggesting that I use this for any serious purposes, just for early initialization ---------------------------------------------------------------------- dseligo · 2022-07-17 14:27 Quote from: 440bx on July 17, 2022, 03:15:03 pmit is really embarrassing to tell a programmer who is learning Pascal that, in order to get a static variable, the programmer has to declare a writable "constant". And what is "static variable"? If you don't come from "C" languages it isn't intuitive as well. Also, meaning of "static" and "constant" is somewhat similar. And I'm sure that C also has it's own "embarrassing" things for new programmers. ---------------------------------------------------------------------- Martin_fr · 2022-07-17 14:55 Quote from: dseligo on July 17, 2022, 04:27:25 pmQuote from: 440bx on July 17, 2022, 03:15:03 pmit is really embarrassing to tell a programmer who is learning Pascal that, in order to get a static variable, the programmer has to declare a writable "constant". And what is "static variable"? If you don't come from "C" languages it isn't intuitive as well. Also, meaning of "static" and "constant" is somewhat similar. And I'm sure that C also has it's own "embarrassing" things for new programmers. From the English language point of view: yes. From the point of view to have different words for different concepts (unchangeable vs life-span): It's just to chosen tokens, with a new defined meaning vaguely based on the underlaying English term. Anyway, while entertaining the idea, if something were to be done, why base it on the "c" syntax? There are plenty of other possibilities: 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;unit var  a: integer; at least "unit" is a reserved word, and wont cause clashes. Or "program var" or "const var". (well...) If needs must "procedure Foo; static {var} a: integer; begin". Btw, then we all could start asking for the next feature. 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 TMyClass.Foo;object var  a: integer; A field on TMyClass that is only accessible in this function. So the function has a persistent local var for each instance. ---------------------------------------------------------------------- kupferstecher · 2022-07-17 15:22 Quote from: Martin_fr on July 17, 2022, 01:57:10 pmJust thinking ahead with upcoming inlined functions, and closures.... Not sure if I get the syntax right, but something like... 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 very_long_name_foo := this + function(bar: T)   begin    SetSomeVal(this + bar); // the outer captured "this" (and bar is also the outer "this")    result := CalcRes();    result := this + Val(); // "this" is result  end(this); // execute the function in placeYes, it's a tricky example, but I wouldn't see the body of the inline function as part of the statement, so the second use of "this" wouldn't be valid: 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 SetSomeVal(this + bar); //Syntax error, place holder "this" may only be used in assignments.So scoping is not an issue. (But you may call this an arbitrary limitation.) QuoteVery readable indeed. Of course arbitrary limitations to the scoping rules could be made... Additional arbitrary rules are after all the best way to make a language clear and readable. ... not.I don't see the limitation as arbitrary. The only case where an assignment can be part of an overlaying assignment is in the case of the inlined function, isn't? You could argue that one couldn't do fancy stuff with this, but that's also not intended. The idea is to have a very local place holder. QuoteAnd you can always write your own version of "include" and inline it.Then I'd rather write the variable twice. Here a comparison of a startup code for the clock configuration. (Yes, it's only touched once...) 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 SystemInit;begin    RCC.CTLR := RCC.CTLR  or  $00000001;    RCC.CFGR0:= RCC.CFGR0 and $F8FF0000;    RCC.CTLR := RCC.CTLR  and $FEF6FFFF;    RCC.CTLR := RCC.CTLR  and $FFFBFFFF;    RCC.CFGR0:= RCC.CFGR0 and $FF80FFFF;    RCC.INTR := $009F0000;    SetSysClockTo72;end; Better: 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 SystemInit;begin    RCC.CTLR := this or  $00000001;    RCC.CFGR0:= this and $F8FF0000;    RCC.CTLR := this and $FEF6FFFF;    RCC.CTLR := this and $FFFBFFFF;    RCC.CFGR0:= this and $FF80FFFF;    RCC.INTR := $009F0000;    SetSysClockTo72;end; And the original c code: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i void SystemInit(void){    RCC->CTLR  |= (uint32_t)0x00000001;    RCC->CFGR0 &= (uint32_t)0xF8FF0000;    RCC->CTLR  &= (uint32_t)0xFEF6FFFF;    RCC->CTLR  &= (uint32_t)0xFFFBFFFF;    RCC->CFGR0 &= (uint32_t)0xFF80FFFF;    RCC->INTR  = 0x009F0000;    SetSysClock();} (Just in hope that you guys see the beauty in "this" concept  ) ---------------------------------------------------------------------- kupferstecher · 2022-07-17 15:35 Quote from: Martin_fr on July 17, 2022, 04:55:32 pmAnyway, while entertaining the idea, if something were to be done, why base it on the "c" syntax? There are plenty of other possibilities:I'm definitely not fixed on the "c" naming. QuoteCode: 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;unit var  a: integer; at least "unit" is a reserved word, and wont cause clashes. Or "program var" or "const var". (well...) Would the "static;" modifier cause clashes? In which way? It's used for static class methods as well and doesn't clash there. Even I'd say the meaning is comparable in some way. ---------------------------------------------------------------------- Handoko · 2022-07-17 15:40 Quote from: kupferstecher on July 17, 2022, 05:22:05 pmCode: 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 SystemInit;begin    RCC.CTLR := this or  $00000001;    RCC.CFGR0:= this and $F8FF0000;    RCC.CTLR := this and $FEF6FFFF;    RCC.CTLR := this and $FFFBFFFF;    RCC.CFGR0:= this and $FF80FFFF;    RCC.INTR := $009F0000;    SetSysClockTo72;end; Because for Something := Something + 1; we have inc(Something), I would suggest: 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   OrVal (RCC.CTLR,  $00000001);  AndVal(RCC.CFGR0, $F8FF0000);  AndVal(RCC.CTLR,  $FEF6FFFF);  AndVal(RCC.CTLR,  $FFFBFFFF);  AndVal(RCC.CFGR0, $FF80FFFF); ---------------------------------------------------------------------- alpine · 2022-07-17 16:08 Quote from: kupferstecher on July 17, 2022, 05:22:05 pm*snip* Here a comparison of a startup code for the clock configuration. (Yes, it's only touched once...) 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 SystemInit;begin    RCC.CTLR := RCC.CTLR  or  $00000001;    RCC.CFGR0:= RCC.CFGR0 and $F8FF0000;    RCC.CTLR := RCC.CTLR  and $FEF6FFFF;    RCC.CTLR := RCC.CTLR  and $FFFBFFFF;    RCC.CFGR0:= RCC.CFGR0 and $FF80FFFF;    RCC.INTR := $009F0000;    SetSysClockTo72;end; Better: 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 SystemInit;begin    RCC.CTLR := this or  $00000001;    RCC.CFGR0:= this and $F8FF0000;    RCC.CTLR := this and $FEF6FFFF;    RCC.CTLR := this and $FFFBFFFF;    RCC.CFGR0:= this and $FF80FFFF;    RCC.INTR := $009F0000;    SetSysClockTo72;end; And the original c code: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i void SystemInit(void){    RCC->CTLR  |= (uint32_t)0x00000001;    RCC->CFGR0 &= (uint32_t)0xF8FF0000;    RCC->CTLR  &= (uint32_t)0xFEF6FFFF;    RCC->CTLR  &= (uint32_t)0xFFFBFFFF;    RCC->CFGR0 &= (uint32_t)0xFF80FFFF;    RCC->INTR  = 0x009F0000;    SetSysClock();} (Just in hope that you guys see the beauty in "this" concept  ) OT, It should be noted here, that working with peripheral registers is very specific, sometimes two distinct registers may share same address one for reading, other for writing... or just accessing of register may have side effect, so 'read-modify-then write' is/maybe not advisable. C compiler may recognize the assignment operators such as |= and &= and replace them with bitset,bitclear instructions. AFAIK this is not the case in FPC, where such a shorthand assignments are just syntactical shorthands. The Handokos suggestion is a way more acceptable as those can be intrinsics: Quote from: Handoko on July 17, 2022, 05:40:10 pm*snip* Because for Something := Something + 1; we have inc(Something), I would suggest: 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   OrVal (RCC.CTLR,  $00000001);  AndVal(RCC.CFGR0, $F8FF0000);  AndVal(RCC.CTLR,  $FEF6FFFF);  AndVal(RCC.CTLR,  $FFFBFFFF);  AndVal(RCC.CFGR0, $FF80FFFF); ---------------------------------------------------------------------- Martin_fr · 2022-07-17 16:09 Quote from: kupferstecher on July 17, 2022, 05:35:19 pmWould the "static;" modifier cause clashes? In which way? It's used for static class methods as well and doesn't clash there. Even I'd say the meaning is comparable in some way. That depends.... The proposal from earlier in this thread Quote from: kupferstecher on July 16, 2022, 12:05:27 amCode: 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;var  CallCount: Integer = 0; static;  "static" could then not be used as a name for a variable.  Because the compiler has already eaten it as modifier. And no, the compiler doesn't look ahead.... Take the example of "cvar" https://www.freepascal.org/docs- html/ref/refse22.html WORKS: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 var  cvar: integer;  a: integer; ERROR: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 var  a: integer;  cvar: integer; Of course omit the ";" (like for deprecated), and that changes 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 var a: integer static; But then like with deprecated, you need to be aware if and when a ";" is needed. Deprecate a method => needs ";" / deprecate a variable => no ";". That is not exactly user friendly either. And like (real) const and var (and type) have their own sections, why not *keep* the global-life-span vars in their own section too? (yeah, ok, we have a shared section for writeable and non-writeable const) ---------------------------------------------------------------------- 440bx · 2022-07-17 16:26 Quote from: dseligo on July 17, 2022, 04:27:25 pmAnd what is "static variable"? If you don't come from "C" languages it isn't intuitive as well. you have a point there but, C is the de-facto lingua franca in programming which means, a very significant percentage of programmers would instantly recognize what "static" is for and what it does.  That said, I am not against a different keyword that is a bit more appropriate than "const" (just about anything is more appropriate.) Quote from: dseligo on July 17, 2022, 04:27:25 pmAnd I'm sure that C also has it's own "embarrassing" things for new programmers. The C language itself is an embarrassment.  I think it is the reason why the missing link is still missing, too embarrassed to be in the C club but, while its design is an atrocity, its feature set is quite well thought out, particularly for low level programming. The bottom line is, just about anything would likely be less contradictory, counter-intuitive and embarrassing as "writable constant" ---------------------------------------------------------------------- PascalDragon · 2022-07-18 12:20 Quote from: y.ivanov on July 17, 2022, 06:08:38 pmC compiler may recognize the assignment operators such as |= and &= and replace them with bitset,bitclear instructions. AFAIK this is not the case in FPC, where such a shorthand assignments are just syntactical shorthands. FPC main supports the UseLoadModifyStore optimizations which optimizes statements of the kind Target := Target OP Value (it's implicitly also applied to the C-style operators). For bit fields FPC would then either need to detect that the right side of the operator is only a single bit and do a suitable bitwise operation or - if you use a set as base type - optimize the set operators (though if you use Include and Exclude that will result in similar code. 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 treadmodify; {$OPTIMIZATION USELOADMODIFYSTORE} type  TRec = record  f1: LongInt;    s1: set of 1..32;  end; procedure Test;var  r: TRec;begin  r.f1 := $20;  r.f1 := r.f1 or $400;  r.f1 := r.f1 + $800;  r.s1 := [];  r.s1 := r.s1 + [4]; // currently not optimized  Include(r.s1, 4);end; begin  Test;end. Without optimization on i386-win32: Code: ASM  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i .section .text.n_p$treadmodify_$$_test,"ax"        .balign 16,0x90.globl  P$TREADMODIFY_$$_TESTP$TREADMODIFY_$$_TEST:# [treadmodify.pp]# [14] begin        pushl   %ebp        movl    %esp,%ebp        leal    -36(%esp),%esp        pushl   %esi        pushl   %edi# Var r located at ebp-36, size=OS_NO# [15] r.f1 := $20;        movl    $32,-36(%ebp)# [16] r.f1 := r.f1 or $400;        movl    -36(%ebp),%eax        orl   $1024,%eax        movl    %eax,-36(%ebp)# [17] r.f1 := r.f1 + $800;      movl    -36(%ebp),%eax        leal    2048(%eax),%eax        movl    %eax,-36(%ebp)# [18] r.s1 := [];        leal    -32(%ebp),%edi        movl    $_$TREADMODIFY$_Ld1,%esi        movl    $8,%ecx        rep        movsl# [19] r.s1 := r.s1 + [4]; // currently not optimized        pushl   $32        leal    -32(%ebp),%ecx        movl    $_$TREADMODIFY$_Ld2,%edx        leal    -32(%ebp),%eax        call    fpc_varset_add_sets# [20] Include(r.s1, 4);        orl     $16,-32(%ebp)# [21] end;        popl    %edi        popl    %esi      movl    %ebp,%esp        popl    %ebp        ret With optimization on i386-win32: Code: ASM  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i .section .text.n_p$treadmodify_$$_test,"ax"        .balign 16,0x90.globl  P$TREADMODIFY_$$_TESTP$TREADMODIFY_$$_TEST:# [treadmodify.pp]# [14] begin        pushl   %ebp        movl    %esp,%ebp        leal    -36(%esp),%esp        pushl   %esi        pushl   %edi# Var r located at ebp-36, size=OS_NO# [15] r.f1 := $20;        movl    $32,-36(%ebp)# [16] r.f1 := r.f1 or $400;        orl     $1024,-36(%ebp)# [17] r.f1 := r.f1 + $800;        addl    $2048,-36(%ebp)# [18] r.s1 := [];      leal    -32(%ebp),%edi        movl    $_$TREADMODIFY$_Ld1,%esi      movl    $8,%ecx        rep        movsl# [19] r.s1 := r.s1 + [4]; // currently not optimized        pushl   $32        leal    -32(%ebp),%ecx        movl    $_$TREADMODIFY$_Ld2,%edx        leal    -32(%ebp),%eax        call    fpc_varset_add_sets# [20] Include(r.s1, 4);        orl     $16,-32(%ebp)# [21] end;        popl    %edi      popl    %esi        movl    %ebp,%esp        popl    %ebp        ret FPK and Nikolay might be interested in suggestions for improvements here. Quote from: kupferstecher on July 17, 2022, 05:35:19 pmQuoteCode: 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;unit var  a: integer; at least "unit" is a reserved word, and wont cause clashes. Or "program var" or "const var". (well...) Would the "static;" modifier cause clashes? In which way? It's used for static class methods as well and doesn't clash there. Even I'd say the meaning is comparable in some way. If at all I'd definitely prefer a separate section to a modifier (after all with threadvar we have something similar already). ---------------------------------------------------------------------- 440bx · 2022-07-18 12:25 Quote from: PascalDragon on July 18, 2022, 02:20:40 pmIf at all I'd definitely prefer a separate section to a modifier (after all with threadvar we have something similar already). Definitely, a separate section would allow grouping those variables that behave differently.  That's another one of the problems with "const".  Static variables are mixed with plain/real constants (apples and oranges) ---------------------------------------------------------------------- MarkMLl · 2022-07-18 20:06 Quote from: PascalDragon on July 18, 2022, 02:20:40 pmIf at all I'd definitely prefer a separate section to a modifier (after all with threadvar we have something similar already). I don't much like proliferating keywords needlessly, but am inclined to agree. The existing var modifiers are all (?) concerned with external allocation etc. MarkMLl ---------------------------------------------------------------------- PascalDragon · 2022-07-19 06:48 Quote from: MarkMLl on July 18, 2022, 10:06:38 pmQuote from: PascalDragon on July 18, 2022, 02:20:40 pmIf at all I'd definitely prefer a separate section to a modifier (after all with threadvar we have something similar already). I don't much like proliferating keywords needlessly, but am inclined to agree. The existing var modifiers are all (?) concerned with external allocation etc. It wouldn't have to be a single keyword. Using an existing keyword that is otherwise not valid in this context as a prefix would be suitable as well (e.g. unit as suggested by kupferstecher). ---------------------------------------------------------------------- kupferstecher · 2022-07-19 09:19 I think the most important thing is that syntax is consitent. There are already a lot of different ways, which makes it imho not so easy to achive. var and const are the most used sections. threadvar, resourcestring defines sections with very special meaning. class var in classes is kind of a section as well, but in opposite to the others it consists of two seperated words. Then there are the modifiers: export, cvar, external are all seperated from the declaration itself with a semicolon. absolute instead isn't seperated by a semicolon. There is also a modifier for consts describing the place where the const should be saved: 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 const  HelloStr: string[5] = 'Hello'; section '.progmem'; For persistant local variables (static vars) what we actually do is to tell the compiler to put the local variable on the static memory (surprise~) instead of the stack. But on the other hand having such persistent variables is a high level language feature, the programmer doesn't need to know about the internals, the storage place. So in that regard its very different to the "section '.progmem';" feature. Then there are also the procedure modifiers, outside of classes they don't know sections at all. I'd still tend to a modifier. Quote from: PascalDragon on July 19, 2022, 08:48:03 am(e.g. unit as suggested by kupferstecher). The credits shoud go to Martin_fr. Using unit does really follow some logic, i.e. where the variable belongs to. But simultaneously it doesn't expose the purpose of that special variable at all. E.g. persistent would be more telling. But still I'd rather go with "static", no matter if its done as section or as modifier. ---------------------------------------------------------------------- Thaddy · 2022-07-19 09:28 QuoteFor persistant local variables (static vars) what we actually do is to tell the compiler to put the local variable on the static memory (surprise~) instead of the stack.You can already do that for typed consts to some extend. These have a stack reference, but are stored on the heap. It depends on {$J-/+} if it is stored in a read-only section or a writable section as I explained earlier. ---------------------------------------------------------------------- MarkMLl · 2022-07-19 10:12 Quote from: kupferstecher on July 19, 2022, 11:19:03 amexport, cvar, external are all seperated from the declaration itself with a semicolon. absolute instead isn't seperated by a semicolon. ...which sets up an analogy between "; export" etc. and Wirth's usage of "; forward" in Classic Pascal, which I think is the only type of modifier (for want of a better word) that he allowed for. Quotethat special variable at all. E.g. persistent would be more telling. But still I'd rather go with "static", no matter if its done as section or as modifier. "static" has the advantage it's the term that the broader community has settled on. I'm a bit unhappy about "persistent" since there have in the past been languages which allowed (global) variables to persist across program invocations, e.g. in particular PS-algol but also noting https://en.wikipedia.org/wiki/Persistence_(computer_science) etc. MarkMLl