Recent

Author Topic: Wishlist - (language evolution)  (Read 8860 times)

zamtmn

  • Hero Member
  • *****
  • Posts: 668
Re: Wishlist - (language evolution)
« Reply #45 on: July 17, 2022, 04:03:41 pm »
Quote
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.
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

  • Hero Member
  • *****
  • Posts: 1532
Re: Wishlist - (language evolution)
« Reply #46 on: July 17, 2022, 04:27:25 pm »
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".

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

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
Re: Wishlist - (language evolution)
« Reply #47 on: July 17, 2022, 04:55:32 pm »
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".

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][+][-]
  1. Procedure Foo;
  2. unit var
  3.   a: integer;
  4.  
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][+][-]
  1. Procedure TMyClass.Foo;
  2. object var
  3.   a: integer;
  4.  
A field on TMyClass that is only accessible in this function. So the function has a persistent local var for each instance. ;) :) ;)



kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Wishlist - (language evolution)
« Reply #48 on: July 17, 2022, 05:22:05 pm »
Just thinking ahead with upcoming inlined functions, and closures.... Not sure if I get the syntax right, but something like...
Code: Pascal  [Select][+][-]
  1. very_long_name_foo := this + function(bar: T)
  2.   begin
  3.     SetSomeVal(this + bar); // the outer captured "this" (and bar is also the outer "this")
  4.     result := CalcRes();
  5.     result := this + Val(); // "this" is result
  6.   end(this); // execute the function in place
Yes, 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][+][-]
  1. 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.)

Quote
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.
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.

Quote
And 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][+][-]
  1. procedure SystemInit;
  2. begin
  3.     RCC.CTLR := RCC.CTLR  or  $00000001;
  4.     RCC.CFGR0:= RCC.CFGR0 and $F8FF0000;
  5.     RCC.CTLR := RCC.CTLR  and $FEF6FFFF;
  6.     RCC.CTLR := RCC.CTLR  and $FFFBFFFF;
  7.     RCC.CFGR0:= RCC.CFGR0 and $FF80FFFF;
  8.     RCC.INTR := $009F0000;
  9.     SetSysClockTo72;
  10. end;

Better:
Code: Pascal  [Select][+][-]
  1. procedure SystemInit;
  2. begin
  3.     RCC.CTLR := this or  $00000001;
  4.     RCC.CFGR0:= this and $F8FF0000;
  5.     RCC.CTLR := this and $FEF6FFFF;
  6.     RCC.CTLR := this and $FFFBFFFF;
  7.     RCC.CFGR0:= this and $FF80FFFF;
  8.     RCC.INTR := $009F0000;
  9.     SetSysClockTo72;
  10. end;

And the original c code:
Code: C  [Select][+][-]
  1. void SystemInit(void)
  2. {
  3.     RCC->CTLR  |= (uint32_t)0x00000001;
  4.     RCC->CFGR0 &= (uint32_t)0xF8FF0000;
  5.     RCC->CTLR  &= (uint32_t)0xFEF6FFFF;
  6.     RCC->CTLR  &= (uint32_t)0xFFFBFFFF;
  7.     RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
  8.     RCC->INTR  = 0x009F0000;
  9.     SetSysClock();
  10. }

(Just in hope that you guys see the beauty in "this" concept  ;))

kupferstecher

  • Hero Member
  • *****
  • Posts: 604
Re: Wishlist - (language evolution)
« Reply #49 on: July 17, 2022, 05:35:19 pm »
Anyway, 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.

Quote
Code: Pascal  [Select][+][-]
  1. Procedure Foo;
  2. unit var
  3.   a: integer;
  4.  
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

  • Hero Member
  • *****
  • Posts: 5458
  • My goal: build my own game engine using Lazarus
Re: Wishlist - (language evolution)
« Reply #50 on: July 17, 2022, 05:40:10 pm »
Code: Pascal  [Select][+][-]
  1. procedure SystemInit;
  2. begin
  3.     RCC.CTLR := this or  $00000001;
  4.     RCC.CFGR0:= this and $F8FF0000;
  5.     RCC.CTLR := this and $FEF6FFFF;
  6.     RCC.CTLR := this and $FFFBFFFF;
  7.     RCC.CFGR0:= this and $FF80FFFF;
  8.     RCC.INTR := $009F0000;
  9.     SetSysClockTo72;
  10. end;

Because for Something := Something + 1; we have inc(Something), I would suggest:

Code: Pascal  [Select][+][-]
  1.   OrVal (RCC.CTLR,  $00000001);
  2.   AndVal(RCC.CFGR0, $F8FF0000);
  3.   AndVal(RCC.CTLR,  $FEF6FFFF);
  4.   AndVal(RCC.CTLR,  $FFFBFFFF);
  5.   AndVal(RCC.CFGR0, $FF80FFFF);

alpine

  • Hero Member
  • *****
  • Posts: 1394
Re: Wishlist - (language evolution)
« Reply #51 on: July 17, 2022, 06:08:38 pm »
*snip*
Here a comparison of a startup code for the clock configuration. (Yes, it's only touched once...)

Code: Pascal  [Select][+][-]
  1. procedure SystemInit;
  2. begin
  3.     RCC.CTLR := RCC.CTLR  or  $00000001;
  4.     RCC.CFGR0:= RCC.CFGR0 and $F8FF0000;
  5.     RCC.CTLR := RCC.CTLR  and $FEF6FFFF;
  6.     RCC.CTLR := RCC.CTLR  and $FFFBFFFF;
  7.     RCC.CFGR0:= RCC.CFGR0 and $FF80FFFF;
  8.     RCC.INTR := $009F0000;
  9.     SetSysClockTo72;
  10. end;

Better:
Code: Pascal  [Select][+][-]
  1. procedure SystemInit;
  2. begin
  3.     RCC.CTLR := this or  $00000001;
  4.     RCC.CFGR0:= this and $F8FF0000;
  5.     RCC.CTLR := this and $FEF6FFFF;
  6.     RCC.CTLR := this and $FFFBFFFF;
  7.     RCC.CFGR0:= this and $FF80FFFF;
  8.     RCC.INTR := $009F0000;
  9.     SetSysClockTo72;
  10. end;

And the original c code:
Code: C  [Select][+][-]
  1. void SystemInit(void)
  2. {
  3.     RCC->CTLR  |= (uint32_t)0x00000001;
  4.     RCC->CFGR0 &= (uint32_t)0xF8FF0000;
  5.     RCC->CTLR  &= (uint32_t)0xFEF6FFFF;
  6.     RCC->CTLR  &= (uint32_t)0xFFFBFFFF;
  7.     RCC->CFGR0 &= (uint32_t)0xFF80FFFF;
  8.     RCC->INTR  = 0x009F0000;
  9.     SetSysClock();
  10. }

(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:
*snip*
Because for Something := Something + 1; we have inc(Something), I would suggest:

Code: Pascal  [Select][+][-]
  1.   OrVal (RCC.CTLR,  $00000001);
  2.   AndVal(RCC.CFGR0, $F8FF0000);
  3.   AndVal(RCC.CTLR,  $FEF6FFFF);
  4.   AndVal(RCC.CTLR,  $FFFBFFFF);
  5.   AndVal(RCC.CFGR0, $FF80FFFF);
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
Re: Wishlist - (language evolution)
« Reply #52 on: July 17, 2022, 06:09:23 pm »
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.

That depends....

The proposal from earlier in this thread
Code: Pascal  [Select][+][-]
  1. procedure Foo;
  2. var
  3.   CallCount: Integer = 0; static;
  4.  

"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][+][-]
  1. var
  2.   cvar: integer;
  3.   a: integer;
ERROR:
Code: Pascal  [Select][+][-]
  1. var
  2.   a: integer;
  3.   cvar: integer;



Of course omit the ";" (like for deprecated), and that changes
Code: Pascal  [Select][+][-]
  1. 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

  • Hero Member
  • *****
  • Posts: 5575
Re: Wishlist - (language evolution)
« Reply #53 on: July 17, 2022, 06:26:43 pm »
And 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.)

And 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" 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6035
  • Compiler Developer
Re: Wishlist - (language evolution)
« Reply #54 on: July 18, 2022, 02:20:40 pm »
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.

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][+][-]
  1. program treadmodify;
  2.  
  3. {$OPTIMIZATION USELOADMODIFYSTORE}
  4.  
  5. type
  6.   TRec = record
  7.     f1: LongInt;
  8.     s1: set of 1..32;
  9.   end;
  10.  
  11. procedure Test;
  12. var
  13.   r: TRec;
  14. begin
  15.   r.f1 := $20;
  16.   r.f1 := r.f1 or $400;
  17.   r.f1 := r.f1 + $800;
  18.   r.s1 := [];
  19.   r.s1 := r.s1 + [4]; // currently not optimized
  20.   Include(r.s1, 4);
  21. end;
  22.  
  23. begin
  24.   Test;
  25. end.

Without optimization on i386-win32:

Code: ASM  [Select][+][-]
  1. .section .text.n_p$treadmodify_$$_test,"ax"
  2.         .balign 16,0x90
  3. .globl  P$TREADMODIFY_$$_TEST
  4. P$TREADMODIFY_$$_TEST:
  5. # [treadmodify.pp]
  6. # [14] begin
  7.         pushl   %ebp
  8.         movl    %esp,%ebp
  9.         leal    -36(%esp),%esp
  10.         pushl   %esi
  11.         pushl   %edi
  12. # Var r located at ebp-36, size=OS_NO
  13. # [15] r.f1 := $20;
  14.         movl    $32,-36(%ebp)
  15. # [16] r.f1 := r.f1 or $400;
  16.         movl    -36(%ebp),%eax
  17.         orl     $1024,%eax
  18.         movl    %eax,-36(%ebp)
  19. # [17] r.f1 := r.f1 + $800;
  20.         movl    -36(%ebp),%eax
  21.         leal    2048(%eax),%eax
  22.         movl    %eax,-36(%ebp)
  23. # [18] r.s1 := [];
  24.         leal    -32(%ebp),%edi
  25.         movl    $_$TREADMODIFY$_Ld1,%esi
  26.         movl    $8,%ecx
  27.         rep
  28.         movsl
  29. # [19] r.s1 := r.s1 + [4]; // currently not optimized
  30.         pushl   $32
  31.         leal    -32(%ebp),%ecx
  32.         movl    $_$TREADMODIFY$_Ld2,%edx
  33.         leal    -32(%ebp),%eax
  34.         call    fpc_varset_add_sets
  35. # [20] Include(r.s1, 4);
  36.         orl     $16,-32(%ebp)
  37. # [21] end;
  38.         popl    %edi
  39.         popl    %esi
  40.         movl    %ebp,%esp
  41.         popl    %ebp
  42.         ret

With optimization on i386-win32:

Code: ASM  [Select][+][-]
  1. .section .text.n_p$treadmodify_$$_test,"ax"
  2.         .balign 16,0x90
  3. .globl  P$TREADMODIFY_$$_TEST
  4. P$TREADMODIFY_$$_TEST:
  5. # [treadmodify.pp]
  6. # [14] begin
  7.         pushl   %ebp
  8.         movl    %esp,%ebp
  9.         leal    -36(%esp),%esp
  10.         pushl   %esi
  11.         pushl   %edi
  12. # Var r located at ebp-36, size=OS_NO
  13. # [15] r.f1 := $20;
  14.         movl    $32,-36(%ebp)
  15. # [16] r.f1 := r.f1 or $400;
  16.         orl     $1024,-36(%ebp)
  17. # [17] r.f1 := r.f1 + $800;
  18.         addl    $2048,-36(%ebp)
  19. # [18] r.s1 := [];
  20.         leal    -32(%ebp),%edi
  21.         movl    $_$TREADMODIFY$_Ld1,%esi
  22.         movl    $8,%ecx
  23.         rep
  24.         movsl
  25. # [19] r.s1 := r.s1 + [4]; // currently not optimized
  26.         pushl   $32
  27.         leal    -32(%ebp),%ecx
  28.         movl    $_$TREADMODIFY$_Ld2,%edx
  29.         leal    -32(%ebp),%eax
  30.         call    fpc_varset_add_sets
  31. # [20] Include(r.s1, 4);
  32.         orl     $16,-32(%ebp)
  33. # [21] end;
  34.         popl    %edi
  35.         popl    %esi
  36.         movl    %ebp,%esp
  37.         popl    %ebp
  38.         ret

FPK and Nikolay might be interested in suggestions for improvements here. :)

Quote
Code: Pascal  [Select][+][-]
  1. Procedure Foo;
  2. unit var
  3.   a: integer;
  4.  
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

  • Hero Member
  • *****
  • Posts: 5575
Re: Wishlist - (language evolution)
« Reply #55 on: July 18, 2022, 02:25:51 pm »
If 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)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8453
Re: Wishlist - (language evolution)
« Reply #56 on: July 18, 2022, 10:06:38 pm »
If 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
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 6035
  • Compiler Developer
Re: Wishlist - (language evolution)
« Reply #57 on: July 19, 2022, 08:48:03 am »
If 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

  • Hero Member
  • *****
  • Posts: 604
Re: Wishlist - (language evolution)
« Reply #58 on: July 19, 2022, 11:19:03 am »
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][+][-]
  1. const
  2.   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.

(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

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Re: Wishlist - (language evolution)
« Reply #59 on: July 19, 2022, 11:28:20 am »
Quote
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.
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.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

 

TinyPortal © 2005-2018