Recent

Author Topic: FPC Unleashed (async/await, parallel for, match, string interpolation & more)  (Read 46547 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12561
  • Debugger - SynEdit - and more
    • wiki
Can't help it, but I have to play the devils advocate here.

Though, let me note (again) at first: This is no pro/contra argument. I couldn't care less what you want to do (not meant to devalue your work / but expressing that I do not use it, hence..).... But, if you do, then I will still give you bits and pieces that maybe are worth to be considered to find out how you want to exactly specify what it is you do... If you find it not of interest, well your choice.


Code: Pascal  [Select][+][-]
  1. type
  2.   TSubRange = 5..9;
  3.   TData = array [TSubRange(8)] of integer;

According to the proposal that would be a single number. But how many entries should that array have?

The type for the index starts at 5 => so would that be the same as
Code: Pascal  [Select][+][-]
  1. type
  2.   TSubRange = 5..9;
  3.   TData = array [TSubRange(5)..TSubRange(7)] of integer;
  4.   // or...
  5.   //TData = array [TSubRange(5)..TSubRange(8)] of integer;

A sub-range could be starting at 1 for natural number, and then the above may be looking less contrived....


Similar, what happens with enum
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyEnum = (e0, e1, e2, e3, e4, e5);
  3.   TData = array [e2] of integer;

The array is defined by a single ordinal value => should that have some meaning...




How should one declare an array with  256 values that has an index of type byte?

The index type may matter, if code completion should declare a variable from an identifier used as index.
« Last Edit: May 27, 2026, 02:13:02 pm by Martin_fr »

Fibonacci

  • Hero Member
  • *****
  • Posts: 1036
  • Behold, I bring salvation - FPC Unleashed
Code: Pascal  [Select][+][-]
  1. var
  2.   Foo: Integer[8];              // 1D, fixed size, 8 elements, implicit indexes 0..7
  3.   Foo: Integer[0 .. 7];         // 1D, static size, 8 elements, explicit indexes
  4. var
  5.   Foo: Integer[8, 8];           // 2D, fixed size, 8x8 elements, implicit indexes 0..7,0..7
  6.   Foo: Integer[8, 1 .. 8];      // 2D, fixed size, 8x8 elements, explicit indexes 0..7,1..8
  7.   Foo: Integer[1 .. 8, 1 .. 8]; // 2D, fixed size, 8x8 elements, explicit indexes 1..8,1..8
  8. var
  9.   Foo: Integer[];               // 1D, dynamic size,                     instead of "Foo: array of Integer"
  10.   Foo: Integer[,];              // 2D, dynamic size for both dimensions, instead of "Foo: array of array of Integer"
  11.   Foo: Integer[8,];             // 2D, dynamic size for 2nd dimension,   instead of "Foo: array [0 .. 7] of array of Integer"
  12.  
  13.   procedure Foo(ABar: const[]); // instead of "ABar: array of const"

Not possible due to ShortString. Swap Integer for String first, then throw your examples.
FPC Unleashed: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

Fibonacci

  • Hero Member
  • *****
  • Posts: 1036
  • Behold, I bring salvation - FPC Unleashed
@Martin_fr: You're over-complicating this. The point is simple: I want a 100-element array - I don't want to write [0..99], and I definitely don't want to declare a range type first just to use it. Just write the number. Ok? Old code stays valid. If you want enum/subrange/type as index, you write it explicitly. The shorthand array[N] is for "I just want N elements" - 99% of array declarations.
FPC Unleashed: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

Khrys

  • Sr. Member
  • ****
  • Posts: 470
Code: Pascal  [Select][+][-]
  1. var
  2.   Foo: Integer[];               // 1D, dynamic size,                     instead of "Foo: array of Integer"
  3.   Foo: Integer[,];              // 2D, dynamic size for both dimensions, instead of "Foo: array of array of Integer"
  4.   Foo: Integer[8,];             // 2D, dynamic size for 2nd dimension,   instead of "Foo: array [0 .. 7] of array of Integer"
  5.  

For "multidimensional" dynamic arrays I'd go for  Foo: Integer[][]  (if at all) not only because the lone comma(s) look out of place, but because multidimensional dynamic arrays aren't a thing in Pascal:  array of (array of Integer)  is a jagged array. Not only is there no guarantee that the array is indeed rectangular, but the elements aren't contiguous in memory, and there are (potentially) a ton of reference counts to keep track of - IOW, jagged arrays suck and their use shouldn't be encouraged by semantically ambiguous syntax.

On the other hand, how's that for a feature suggestion - truly multidimensional dynamic arrays?  :)

flowCRANE

  • Hero Member
  • *****
  • Posts: 987
Not possible due to ShortString. Swap Integer for String first, then throw your examples.

ShortString could be considered an exception to the rule. But we would also have to consider an array of ShortStrings of a specific length. That could indeed be problematic.

For "multidimensional" dynamic arrays I'd go for  Foo: Integer[][]  (if at all) not only because the lone comma(s) look out of place, but because multidimensional dynamic arrays aren't a thing in Pascal:  array of (array of Integer)  is a jagged array.

I know this and this is a place where the truly multidimensional arrays could be introduced. The Integer[,] actually would be a multidimensional array, and the Integer[][] would be a jagged array (i.e. array of array of Integer). So in short, single [] determines all dimensions od the array, so the comma indicates how many dimensions the array has (no comma means one dimension, one comma means 2D, two commas means 3D etc.). So declaring the jagged array would look the same as in C(-like) languages.

Quote
On the other hand, how's that for a feature suggestion - truly multidimensional dynamic arrays?  :)

I would love to see their support. 8)
« Last Edit: May 27, 2026, 04:08:12 pm by flowCRANE »
Lazarus 4.6 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12955
  • FPC developer.
@Martin_fr: You're over-complicating this. The point is simple: I want a 100-element array

... And it seems you want to start at 0. That are two parameters, not one.
 

VisualLab

  • Hero Member
  • *****
  • Posts: 742
Regarding unions (variant records) and bit fields, I agree. Pascal has limitations in this regard. A solution to this issue would be useful. Although not necessarily by copying C syntax verbatim.

My proposal for a new union syntax is not copied from the C language. It is the result of careful consideration of what a union syntax should look like—one that aligns as closely as possible with Pascal syntax, is simple, concise, readable, unambiguous, and C-ABI-compatible. I believe that my proposal, which was ultimately implemented, meets all of the above requirements.

I had no objections to the addition of Pascal's syntax regarding unions.

Quote
You must be joking. The syntax of C and C++ has also remained unchanged for decades. Is it also clunky and deviates from the norm? If that's your opinion, I completely agree with you. And should the syntax of these languages ​​be improved? If that's what you think, then I agree on that point too. Unfortunately, no one intends to correct it. On the contrary, C and C++ enthusiasts insist it's great (which is a lie).

Among the dozen or so most popular general-purpose programming languages, there isn’t a single one whose array declaration syntax requires specifying indices instead of the number of elements. None of these languages has syntax as verbose as Pascal’s, with the sole exceptions being niche languages such as Ada, Fortran, and VBA. Furthermore, all modern programming languages allow you to declare arrays by specifying the number of elements, with the sole exception of niche languages such as Pascal and Ada.

Because their creators were guided by the syntax of C or its derivatives (C++, Java, etc.). The more complex syntax for declaring arrays in Pascal (and its derivatives) stems from the need to convey additional information. Declaring arrays based on the number of elements doesn't allow for setting indexes other than those in C. Declaring indexes other than the "only right" is useful or necessary in many cases. I use this all the time.

<cut>... rather to shorten overly long syntax and add the ability to specify the number of elements...

No, it's just your subjective opinion that the current Pascal array declaration syntax is too long. Not everyone agrees. Furthermore, the range-based syntax still allows you to easily determine the number of array elements.

...(which is more important in 99.9% of cases).

Whose and what cases? It is not known how many users there are of particular syntaxes and what cases they need. There is no information about anyone conducting any research or surveys on this subject. Users of C and its derivatives use the only syntax available. But perhaps some would like to change the "only correct" array index ranges in certain cases, but can't.

I don't really have time to answer the rest of your questions. If you want to know what array declarations look like in other languages, just do some research (I recommend asking Google Gemini, for example, to provide a comprehensive analysis and comparison of language syntax). It’s no secret that Pascal is an exception when it comes to the pointlessly verbose nature of its syntax. However, the fact that Pascal’s current syntax is unambiguous does not mean that a shorter version (similar to those in other languages) would cease to be readable, unambiguous, and easy to understand.

C and C++ also have pointlessly verbose syntax. Yes, but some people don't bother to notice it, but they should. For example, why the hell do I have to type "include" every time for every library file I include? Or write "define" for every pseudo-constant? Or write "header guards"? Or "unsigned int" when declaring a variable type? (And that's why people often use aliases, because they're tired of the verbose syntax.) There's so much more. This "shorter syntax" from C (and its ilk) is often hard to read, confusing, or incomplete. And in many places, it's really, really verbose.

VisualLab

  • Hero Member
  • *****
  • Posts: 742
This syntax is consistent with that of modern Pascal but is not as verbose, resembling the syntax used in all of today’s most popular programming languages. I will provide the examples again:

Code: Pascal  [Select][+][-]
  1. var
  2.   Foo: Integer[8, 1 .. 8];      // 2D, fixed size, 8x8 elements, explicit indexes 0..7,1..8

The idea of mixing 2 ways of declaring: array size (1st dimension) with index range declaration (2nd dimension) is a straight way to mess up. While the syntax isn't verbose, it's certainly error-prone and unreadable.

Code: Pascal  [Select][+][-]
  1. var
  2.   Foo: Integer[];               // 1D, dynamic size,                     instead of "Foo: array of Integer"
  3.   Foo: Integer[,];              // 2D, dynamic size for both dimensions, instead of "Foo: array of array of Integer"
  4.   Foo: Integer[8,];             // 2D, dynamic size for 2nd dimension,   instead of "Foo: array [0 .. 7] of array of Integer"
  5.  
  6.   procedure Foo(ABar: const[]); // instead of "ABar: array of const"

The current declaration of dynamic arrays in Pascal is much more readable and incomparably less error-prone. In particular, it clearly differs from the syntax of static arrays. However, the above proposal, with empty (or partially empty) square brackets, can be confused with code in which someone forgot to specify a size or index. The compiler won't be able to distinguish this, and consequently won't be able to report incomplete (and therefore incorrect) syntax. After compilation, this may result in incorrect program operation and the need for time-consuming error searching. Similarly with the given proposal of passing an array to a procedure - an overly shortened syntax. This is just asking for hard-to-find errors.



The Integer[,] actually would be a multidimensional array, and the Integer[][] would be a jagged array (i.e. array of array of Integer). So in short, single [] determines all dimensions od the array, so the comma indicates how many dimensions the array has (no comma means one dimension, one comma means 2D, two commas means 3D etc.). So declaring the jagged array would look the same as in C(-like) languages.

Another error-prone suggestion. It's illegible. If syntax is to be useful, it must also be easy to grasp. Why do you suggest copying quirks from C? After all, C already exists, has a lot of libraries and quite efficient compilers. So just use it instead of trying to force Pascal to resemble C.

flowCRANE

  • Hero Member
  • *****
  • Posts: 987
Because their creators were guided by the syntax of C or its derivatives (C++, Java, etc.).

So what? New programming languages weren’t designed to be syntactically compatible with C, but rather so that their syntax would be sufficiently good, readable, and understandable. And in the case of arrays, a syntax similar to that of C was used, not because of thoughtless copying of ideas from C, but because it is simply good—for most programmers, though apparently not for Pascal programmers.

Quote
Furthermore, the range-based syntax still allows you to easily determine the number of array elements.

So? Has anyone suggested removing the ability to specify indices? No, no one has suggested that. The proposal is to extend the syntax for declaring arrays so that you can specify the number of elements and use default indexing starting from 0.



However, the above proposal, with empty (or partially empty) square brackets, can be confused with code in which someone forgot to specify a size or index. The compiler won't be able to distinguish this, and consequently won't be able to report incomplete (and therefore incorrect) syntax. After compilation, this may result in incorrect program operation and the need for time-consuming error searching.

Nonsense. If a programmer forgets to specify the size of an array or its indices, that array will be empty (automatically initialized to nil), and the first attempt to access it will cause a runtime error, so there’s nothing to look for. On the other hand, if a programmer has memory issues, no syntax—not even the most verbose one—will help. Arguments like "no, because someone might forget" aren’t valid arguments.

Quote
The current declaration of dynamic arrays in Pascal is much more readable and incomparably less error-prone.

"It is not known how many users there are of particular syntaxes and what cases they need. There is no information about anyone conducting any research or surveys on this subject." So in short — "No, it's just your subjective opinion that the current Pascal array declaration syntax is not too long. Not everyone agrees."

Quote
Another error-prone suggestion. It's illegible.

"Just your subjective opinion, not everyone agrees."

Quote
After all, C already exists, has a lot of libraries and quite efficient compilers. So just use it instead of trying to force Pascal to resemble C.

After all, original Free Pascal already and still exists, has verbose syntax and is less C-like. So use it instead of criticizing the development of a language fork that had features from C and other languages implemented long before I stumbled upon this thread and this project.
« Last Edit: May 27, 2026, 07:22:07 pm by flowCRANE »
Lazarus 4.6 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

flowCRANE

  • Hero Member
  • *****
  • Posts: 987
Initial sketch:

Code: Pascal  [Select][+][-]
  1. string[10];             // existing - ShortString with max 10 chars
  2. array[0..9] of string;  // current - explicit range
  3. array[10] of string;    // new - count form, equivalent to array[0..9]

In fact, ShortString is too cumbersome to simplify array syntax. So the current array keyword must remain, because it’s unlikely that this can be reconciled in a meaningful way, and creating a syntactic exception to the rule just to maintain backward compatibility with ShortString isn’t a very good idea.

The examples you provided above are excellent—simply specifying a number instead of the full range. It should be possible to specify a numeric literal, a constant, and an ordinal data type as in the original Free Pascal (e.g., Byte, Char, Word, TSomeEnum, etc.).
Lazarus 4.6 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

Fibonacci

  • Hero Member
  • *****
  • Posts: 1036
  • Behold, I bring salvation - FPC Unleashed
@Martin_fr: You're over-complicating this. The point is simple: I want a 100-element array

... And it seems you want to start at 0. That are two parameters, not one.

Like 100% of the time I want to start at 0. So writing the additional 0.. and then "my number minus 1" is just unnecessary - that can be skipped. Plus, my mind doesn't have to "think" that 0..99 gives 100 elements, because it'll just say array[100] - clear, simple, readable.
FPC Unleashed: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

flowCRANE

  • Hero Member
  • *****
  • Posts: 987
And that’s one of the reasons why Pascal has such a clunky syntax—in-mind convertion of index ranges into the number of elements, even though it’s the number of elements that’s actually key. Unfortunately, the same problem exists with bit fields—again, instead of specifying the data type and size in bits, the language forces you to specify a range and manually convert those ranges.
Lazarus 4.6 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

440bx

  • Hero Member
  • *****
  • Posts: 6560
even though it’s the number of elements that’s actually key.
Sometimes the number of elements is important but there are probably as many cases where the number of elements is a secondary concern at best.  For instance, in an array of months, the number of elements isn't the focus of interest, it's being able to address each month as in, "for m := January to December do" or a subset of it, e.g, "for m := March to July do".  Honestly, I think that attempting to copy C's overly barren (not to mention mediocre) syntax is often not a good idea.   For better ways, look at Ada and Rust, the way it's done in C and C++ are almost guaranteed to be either downright the wrong way or extremely poor and deficient ways. 

All that said, I think it is occasionally convenient to be able to define an array just by specifying its number of elements but, Pascal's way of using a range is inherently superior because it provides more information to the compiler.  Pascal's Low() and High() functions make the occasions when the actual element count is needed to be a bit on the rare side, though sometimes it is convenient to have.  I'd say a cheaper alternative to defining arrays using just their element count is to add a "countof" compiler function, ultra-cheap to implement because it is compile time only and, as its name states, returns the count whenever that happens to be genuinely needed or useful.

FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

flowCRANE

  • Hero Member
  • *****
  • Posts: 987
Sometimes the number of elements is important but there are probably as many cases where the number of elements is a secondary concern at best.  For instance, in an array of months, the number of elements isn't the focus of interest, it's being able to address each month as in, "for m := January to December do" or a subset of it, e.g, "for m := March to July do".

I understand that, but don't confuse the syntax for declaring an array with the syntax for an iterating loop, because we're not talking about loops here. Besides, since you're using an array indexed by months, you would have declared its size anyway by simply using the name of the enumeration type, rather than a range from the first month's enum to the last month's enum.

Anyway, it doesn’t matter anyway, because—once again—no one has proposed removing the ability to specify an index range. The proposal concerns extending the syntax to allow specifying the number of elements and using default indexing starting from 0.

Quote
All that said, I think it is occasionally convenient to be able to define an array just by specifying its number of elements but, Pascal's way of using a range is inherently superior because it provides more information to the compiler.

And this superiority manifests itself as a constant source of annoyance whenever arrays are used with 0-based indexing. And arrays of this type, which map directly to memory addresses, are a daily occurrence. I myself use non-zero array indexing so rarely that if Free Pascal didn’t support the ability to specify an index range at all, I wouldn’t even have noticed it.

However, because ranges are enforced, I have to use this ridiculous syntax in all the arrays in my engine (and there are quite a lot of them), even though they’re all zero-indexed with fixed sizes. To work around this, I declare macros containing ranges, but that doesn’t solve the problem, because the Lazarus codetools can’t fully handle them correctly, provide suggestions, or jump to their declarations. It’s so annoying.
Lazarus 4.6 with FPC 3.2.2, Windows 11 — all 64-bit

Working solo on a top-down retro-style action/adventure game (pixel art), programming the engine from scratch, using Free Pascal and SDL3.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12561
  • Debugger - SynEdit - and more
    • wiki
@Martin_fr: You're over-complicating this. The point is simple: I want a 100-element array - I don't want to write [0..99], and I definitely don't want to declare a range type first just to use it. Just write the number. Ok? Old code stays valid. If you want enum/subrange/type as index, you write it explicitly. The shorthand array[N] is for "I just want N elements" - 99% of array declarations.

I didn't plan on making this a discussion, and really hadn't thought that I would give any further reply on this....
But that answer at first glance is really scary. And I think and hope there is a misunderstanding on either of our sides...

I do have the idea what you want to be able to do... And I didn't say any of what I listed should be added.

I said:
Quote
But, if you do, then I will still give you bits and pieces that maybe are worth to be considered to find out how you want to exactly specify what it is you do...

I.e. it would be best to deliberately decide what of this should affect the design (and how), and what not. And what might be later of possible interest. And what matters here is the word deliberate. You may well decide to pick exactly what you already had in mind.

Maybe you had already deliberated all of that... Maybe not. For the case that you had not, this was just me pointing it out.

E.g. maybe it really never matters how "n" is code-completed in the below
Code: Pascal  [Select][+][-]
  1. type TFoo array [256] of boolean;
  2. var f: TFoo;
  3. begin
  4.   f[n {complete n via code tool} ] := true;  
Maybe its fine that this will just give integer. Maybe someone suddenly wants that to be byte (but "byte(256)" isn't a thing).

If you deliberately decided that, then you will tell them that whatever it does, it was for good reason (and I don't and didn't judge that in any way).



Giving your coding abilities, I would think that you would agree that even if the result should coincidently be the same, a deliberated choice is still better, than accidentally getting there.

That was my entire point.

And I do not think that this "a deliberate choice" is "over-complicating it" => if indeed as I read (maybe misread?) your reply, you say that this does not matter... Well then that is imho very scary. (with regard to the quality of the result)
 

 

TinyPortal © 2005-2018