Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2025-07

Feature "Multiline strings" added

35 messages · 12 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Michael Van Canneyt

Hello,

I have added (long overdue) multiline string support to the FPC compiler.

It is activated by default in objfpc and delphi modes.

if you wish to use it (or disable it), there is a modeswitch:

{$modeswitch multilinestrings}
or, to disable
{$modeswitch multilinestrings-}

Due to historic reasons, it comes in 2 flavours.

Delphi style:

a multiline string starts with a odd number of quotes (3 at least), followed by a newline, and ends with an equal amount of quotes on a line preceded by only whitespace:

const s = '''
some
multiline
stuff

   ''';

In the resulting string, the first N whitespace characters will be trimmed, where N is the number of whitespace characters before the terminating quotes. The last CR/LF is also stripped. If a line contains less whitespaces than the final line, it is considered an error.

So the above example would be equivalent to

const s = 'some '+sLineBreak+'multiline '+sLinebreak+'stuff';

(the "some " and "multiline " are followed by a space, your mail client may not display that corectly in the source... )

The line-ending in the resulting string is by default the native line ending. this can be influenced by the (delphi-compatible) directive:

{$TEXTBLOCK NATIVE/CR/LF/CRLF}

To include triple quotes in such a string, you can use 5 quotes to delimit the string:

const s = '''''
some
'''multiline '''
stuff

   ''''';

All this is Delphi compatible.

The FPC bugtracker contains since a long time a proposal for multiline strings using a backtick as the quote character:

https://gitlab.com/freepascal.org/fpc/source/-/issues/35827

This has since been implemented in pas2js (our pascal to Javascript transpiler). In the interest of compatibility, that proposal has also been implemented in FPC as well.

In fact, the implementation in the issue has served as the start of the Delphi-compatible implementation.

This means you can also do

const S = `some
multiline
stuff`;

This form of multiline strings can be configured using 2 directives:

{$MULTILINESTRINGTRIMLEFT N}

where N is the number of whitespace characters to strip from the string.

The line ending can be set using

{$MULTILINESTRINGLINEENDING PLATFORM/CR/LF/CRLF/SOURCE}

SOURCE will use the line ending as used in the string definition, other than that the effect is identical to $TEXTBLOCK.

Despite the large amount of tests for this new feature, there may still be bugs, please report them in the bugtracker if you encounter them.

My thanks to user Akira1364 (real name?) for the initial implementation of this feature.

Michael.

Reply by email

Alexey T.
to Michael Van Canneyt

hello,

Let's delete custom very special FPC variant with ticks. leave only Delphi variant, please. in English it is maybe called as 'align implementation with Delphi'.
why? to keep the same source when changing objfpc/delphi mode.

Alexey Torgashin

Reply by email

Michael Van Canneyt
to Alexey T.
Alexey T. wrote 5 lines
hello, Let's delete custom very special FPC variant with ticks. leave only Delphi variant, please. in English it is maybe called as 'align implementation with Delphi'.

It is aligned with Delphi ?

why? to keep the same source when changing objfpc/delphi mode.

As said, pas2js alread has this, and I want to maintain compatibility between FPC and pas2js.

The used mode has no influence on the support for backtick or not. Both variants will work in objfpc mode.

Michael.

Reply by email

Michalis Kamburelis
to Michael Van Canneyt
Michael Van Canneyt wrote 14 lines
> Let's delete custom very special FPC variant with ticks. leave only Delphi > variant, please. in English it is maybe called as 'align implementation with > Delphi'. It is aligned with Delphi ? > why? to keep the same source when changing objfpc/delphi mode. As said, pas2js alread has this, and I want to maintain compatibility between FPC and pas2js. The used mode has no influence on the support for backtick or not. Both variants will work in objfpc mode.

I'd say that (while I understand the reasons it happened) having 2 ways in the language to do the same thing -> makes things more complicated.

Why?

- Some documentations will want to mention 2 ways of doing multi-line strings in FPC,

- Some users will have to understand these 2 ways of doing multi-line strings in FPC -- because they will encounter some code using 1 approach, some using different approach. They will need to also understand the reasons for both approaches ("this one works only in Delphi, this one works only in pas2js").

- A bugs may "creep in" when users (us!) confuse some things. E.g. `{$MULTILINESTRINGLINEENDING ..}` doesn't affect Delphi-style multi-line strings, while `{$TEXTBLOCK ...}` doesn't affect FPC-style multi-line strings. If a code will use a mix of backtick and ''' syntaxes for multi-line strings (which it shouldn't, but over time -> complicated things happen in big production codebases) then it's going to be a mess to understand. Imagine debugging something, only to realize that "ups, {$MULTILINESTRINGLINEENDING...} doesn't apply here, it's Delphi-style...".

- Something that only you can judge: maintaining 2 ways of multi-line strings in FPC likely makes it harder on FPC. You need to document, you need to fix bugs in both, you need to carry them both working through all changes.

To be clear, I fully understand the reasons why it happened, pas2js of course could not predict that Delphi will later invent it's own, incompatible, way of multi-line strings. The way to solve this is probably outside of the scope of this thread, you know I'm working on it :) Basically, better communication through standardization.

That said, the solution to maintain 2 ways forever seems unoptimal. Is maybe proposition below possible?

- Implement in Pas2js also Delphi-compatible multi-line strings.

- Deprecate in FPC and Pas2js the "backtick version". That is, let the compilers just generate a message like "Multi-line strings using backticks are deprecated and will be removed in some future release. We encourage to use instead syntax with 3 apostrophes, docs on XXX" when it encounters such syntax.
- And then it is clear to users what to use in new code. And they can easily upgrade their code, just follow compiler messages.
- And then in 2+ years maybe we can remove the old backtick version. And everything is simpler :)

Again, I know it sucks that FPC/Pas2js effectively have to do additional work (deprecation process etc.) to adjust to Delphi. I'd love to fix this state of things long-term :)

Regards,
Michalis

Reply by email

Hairy Pixels
to Michalis Kamburelis

On Jul 27, 2025 at 11:01:16 AM, Michalis Kamburelis via fpc-pascal <

Show quoted text 8 lines
wrote: I'd say that (while I understand the reasons it happened) having 2 ways in the language to do the same thing -> makes things more complicated. Why?

I originally liked the back ticks but after more consideration I think triple quote is best because it’s commonly understand from other major languages (Python,Swift,C# since 2023) and doesn’t introduce new symbols/tokens into the language.

The backticks are famous from JavaScript but they are used for variable interpolation which FPC doesn’t even have so it’s not even a 1:1 match with JavaScript.

Agreed, more than one way to write strings is not helpful and in fact harmful. It really does annoy me in JS that both options exist and you need to agree on which quote to use and sometimes it gets mixed with different programmers etc.. working on the same codebase.

Anyways, thanks to for getting this merged. It’s been a whopping 6 years since the PR was made and it’s a very welcome feature for embedded code. 👏

Regards,
Ryan Joseph

Reply by email

Michalis Kamburelis
to Hairy Pixels
Anyways, thanks to for getting this merged. It’s been a whopping 6 years since the PR was made and it’s a very welcome feature for embedded code. 👏

Oh, I also want to add "thank you" by the way for multi-line strings!

We have code constructing long shaders in Castle Game Engine. It right now uses a setup where GLSL snippets are converted to include files. I look forward to the day when I can drop compatibility with old FPC/Delphi versions and then drop our Makefile and helper utility and just express it much simpler using multi-line strings.

Regards,
Michalis

Reply by email

Thomas Kurz
to Michalis Kamburelis: I'd say that (while I understand the reasons it happened) having 2 ways in the language…
Show quoted text 9 lines
Deprecate in FPC and Pas2js the "backtick version". That is, let the compilers just generate a message like "Multi-line strings using backticks are deprecated and will be removed in some future release. We encourage to use instead syntax with 3 apostrophes, docs on XXX" when it encounters such syntax. And then it is clear to users what to use in new code. And they can easily upgrade their code, just follow compiler messages. And then in 2+ years maybe we can remove the old backtick version. And everything is simpler :)

+1 for this approach. I also think that only one way to do it may be the best. If pas2js was first, it'd be best to change Delphi, but it's pretty unrealistic. So migrating pas2js to the Delphi way seems to be the cleanest thing.

Regards,
Thomas

Reply by email

David Connolly
to Thomas Kurz

Personally, I prefer the back tick, but they're both excellent additions to the language.

On Sun 27 Jul 2025, 20:15 Thomas Kurz via fpc-pascal, <

Show quoted text 24 lines
wrote: > Deprecate in FPC and Pas2js the "backtick version". That is, let the > compilers just generate a message like "Multi-line strings using > backticks are deprecated and will be removed in some future release. > We encourage to use instead syntax with 3 apostrophes, docs on XXX" > when it encounters such syntax. > And then it is clear to users what to use in new code. And they can > easily upgrade their code, just follow compiler messages. > And then in 2+ years maybe we can remove the old backtick version. > And everything is simpler :) +1 for this approach. I also think that only one way to do it may be the best. If pas2js was first, it'd be best to change Delphi, but it's pretty unrealistic. So migrating pas2js to the Delphi way seems to be the cleanest thing. Regards, Thomas _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Flávio Etrusco
to Michael Van Canneyt: I have added (long overdue) multiline string support to the FPC compiler. It is activated…

Thanks to you both!
Maybe I missed something, but isn't there a way to strip/skip the "line endings"?

Em dom., 27 de jul. de 2025 às 09:29, Michael Van Canneyt via fpc-pascal <

Show quoted text 107 lines
escreveu: Hello, I have added (long overdue) multiline string support to the FPC compiler. It is activated by default in objfpc and delphi modes. if you wish to use it (or disable it), there is a modeswitch: {$modeswitch multilinestrings} or, to disable {$modeswitch multilinestrings-} Due to historic reasons, it comes in 2 flavours. Delphi style: a multiline string starts with a odd number of quotes (3 at least), followed by a newline, and ends with an equal amount of quotes on a line preceded by only whitespace: const s = ''' some multiline stuff '''; In the resulting string, the first N whitespace characters will be trimmed, where N is the number of whitespace characters before the terminating quotes. The last CR/LF is also stripped. If a line contains less whitespaces than the final line, it is considered an error. So the above example would be equivalent to const s = 'some '+sLineBreak+'multiline '+sLinebreak+'stuff'; (the "some " and "multiline " are followed by a space, your mail client may not display that corectly in the source... ) The line-ending in the resulting string is by default the native line ending. this can be influenced by the (delphi-compatible) directive: {$TEXTBLOCK NATIVE/CR/LF/CRLF} To include triple quotes in such a string, you can use 5 quotes to delimit the string: const s = ''''' some '''multiline ''' stuff '''''; All this is Delphi compatible. The FPC bugtracker contains since a long time a proposal for multiline strings using a backtick as the quote character: https://gitlab.com/freepascal.org/fpc/source/-/issues/35827 This has since been implemented in pas2js (our pascal to Javascript transpiler). In the interest of compatibility, that proposal has also been implemented in FPC as well. In fact, the implementation in the issue has served as the start of the Delphi-compatible implementation. This means you can also do const S = `some multiline stuff`; This form of multiline strings can be configured using 2 directives: {$MULTILINESTRINGTRIMLEFT N} where N is the number of whitespace characters to strip from the string. The line ending can be set using {$MULTILINESTRINGLINEENDING PLATFORM/CR/LF/CRLF/SOURCE} SOURCE will use the line ending as used in the string definition, other than that the effect is identical to $TEXTBLOCK. Despite the large amount of tests for this new feature, there may still be bugs, please report them in the bugtracker if you encounter them. My thanks to user Akira1364 (real name?) for the initial implementation of this feature. Michael. _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Michael Van Canneyt
to Michalis Kamburelis: I'd say that (while I understand the reasons it happened) having 2 ways in the language…
Michalis Kamburelis wrote 56 lines
Michael Van Canneyt wrote: >> Let's delete custom very special FPC variant with ticks. leave only Delphi >> variant, please. in English it is maybe called as 'align implementation with >> Delphi'. > > It is aligned with Delphi ? > >> why? to keep the same source when changing objfpc/delphi mode. > > As said, pas2js alread has this, and I want to maintain compatibility between > FPC and pas2js. > > The used mode has no influence on the support for backtick or not. > Both variants will work in objfpc mode. > I'd say that (while I understand the reasons it happened) having 2 ways in the language to do the same thing -> makes things more complicated. Why? - Some documentations will want to mention 2 ways of doing multi-line strings in FPC, - Some users will have to understand these 2 ways of doing multi-line strings in FPC -- because they will encounter some code using 1 approach, some using different approach. They will need to also understand the reasons for both approaches ("this one works only in Delphi, this one works only in pas2js"). - A bugs may "creep in" when users (us!) confuse some things. E.g. `{$MULTILINESTRINGLINEENDING ..}` doesn't affect Delphi-style multi-line strings, while `{$TEXTBLOCK ...}` doesn't affect FPC-style multi-line strings. If a code will use a mix of backtick and ''' syntaxes for multi-line strings (which it shouldn't, but over time -> complicated things happen in big production codebases) then it's going to be a mess to understand. Imagine debugging something, only to realize that "ups, {$MULTILINESTRINGLINEENDING...} doesn't apply here, it's Delphi-style...". - Something that only you can judge: maintaining 2 ways of multi-line strings in FPC likely makes it harder on FPC. You need to document, you need to fix bugs in both, you need to carry them both working through all changes. To be clear, I fully understand the reasons why it happened, pas2js of course could not predict that Delphi will later invent it's own, incompatible, way of multi-line strings. The way to solve this is probably outside of the scope of this thread, you know I'm working on it :) Basically, better communication through standardization. That said, the solution to maintain 2 ways forever seems unoptimal. Is maybe proposition below possible? - Implement in Pas2js also Delphi-compatible multi-line strings.

That's already since long the case.

Personally, I prefer the backtick solution.
The triple quote is slow, it requires postprocessing the string. The backtick solution needs only one pass.

<rant>
I positively HATE it when people start treating whitespace as significant. No YAML or Python for me on that account alone. The triple quote solution (presumably Python inspired) is a totally braindead and retarded solution as far as I am concerned. </rant>

You can guess from that little rant that I myself will certainly not remove or even deprecate the backtick version.

If having one soluton for all is the norm, we need to remove a lot more things from FPC that Delphi did differently than we do. We don't do that either. Compatibility, yes. But that should not prevent us from doing things our own way from time to time.

The solution is simple:
if you don't like the backticks, don't use them.

Michael.

Reply by email

Michalis Kamburelis
to Michael Van Canneyt
Michael Van Canneyt wrote 22 lines
Personally, I prefer the backtick solution. The triple quote is slow, it requires postprocessing the string. The backtick solution needs only one pass. <rant> I positively HATE it when people start treating whitespace as significant. No YAML or Python for me on that account alone. The triple quote solution (presumably Python inspired) is a totally braindead and retarded solution as far as I am concerned. </rant> You can guess from that little rant that I myself will certainly not remove or even deprecate the backtick version. If having one soluton for all is the norm, we need to remove a lot more things from FPC that Delphi did differently than we do. We don't do that either. Compatibility, yes. But that should not prevent us from doing things our own way from time to time. The solution is simple: if you don't like the backticks, don't use them.

I can see how this can get into a heated discussion (hopefully it will not!) :) You have the last word when it comes to FPC decisions, obviously. Still, let me try to present the case for "deprecate backticks" again.

The problem with your solution """if you don't like the backticks, don't use them.""" -> is that it means we have 2 ways to achieve the same thing in the Pascal language, to the end of time, and users *will* get confused about them and we have 2x more work to explain it. Things like indentation, crlf/native/etc., what happens with last line -> they have now 2 different behaviors, and people who work with various Pascal code (Pas2js, FPC, Delphi) will need to grok them both and remember which {$xxx} affects which. This makes things harder -- to document, to teach, and to not confuse ourselves when reading alien code.

For me, solving the above problem ("less confusion by not having 2 syntaxes for same thing") is really more important.

( It is *less* important for me which syntax for multi-line strings "wins", as I can see advantages and disadvantages in both. And it is unfortunate that effectively, since we are in this state, Delphi will not adjust to Pas2js, so the recommendation is to go with Delphi solution. Hopefully in the future we can have a better dialogue about it between FPC and Delphi. But that's a future dream, not something we have now. )

As for advantage / disadvantage of the Delphi solution:

In general: calling a solution "totally braindead and retarded" is not constructive :) I know, your statement was in <rant> parentheses, still it wasn't very constructive for discussing :) Let's discuss exactly the technical pros and cons of this decision, for multi-line strings. The advantage of the Delphi solution, to make whitespace meaningful (*in this case*) is: you can write things like this:

"""
procedure Bar;
const
SomeHtmlContent = '''
<b>something</b>
something
something

    ''';

begin
end;
"""

... and there will be no extra whitespace at the beginning of 3 lines in SomeHtmlContent. I don't have any internal knowledge about Embarcadero decision process, but I think that's why they chose this approach. They own examples happen to be similar to mine: https://docwiki.embarcadero.com/RADStudio/Athens/en/String_Types_(Delphi)#Long_and_Multiline_String_Literals .

With backticks, to achieve the same, I need to write:

procedure Bar;
const
  SomeHtmlContent = `<b>something</b>
something
something`;
begin
end;

... which makes the indentation looks worse. 2x "something" is now at the same level as "begin".

The possible mixups of whitespace is somewhat addressed by just requiring all lines to start with same indentation (it's an error if they don't).

So..

1. I don't think Delphi solution is so bad :)

2. Still, frankly I see both solutions (backticks or ''') as acceptable.

3. I still think that having 2 solutions to the same thing is bad for users. This is causing the confusion that I listed in my message. You need to document 2 ways of multi-line strings, users have to understand 2 ways of multi-line strings. We have 2x work to explain this to users.

Choosing to deprecate backticks -> makes things clear for users. OK, we will have to live with 2 ways for some time (backward compatibility is important) but it's clear to everyone knows what to use in new code.

We talk about it now, because probably *now* is the best moment to deprecate backticks, when they are only released in Pas2js (and in FPC since yesterday). If we don't, and FPC allows both versions, then in 5+ years we *will* have codebases using both approaches, so any thoughts about deprecation will be harder.

And I'm not saying that FPC should now adjust to Delphi by removing all FPC-specific features. Let's not generalize :) Of course not, and there are good reasons why some FPC-specific solutions may be better than Delphi solutions (like @ for callbacks). I'd love to go into details, but that's for independent threads :) Here's let's focus on this very specific feature, multi-line strings. Both solutions seems to achieve in the end the same thing.

Regards,
Michalis

Reply by email

Michael Van Canneyt
to Michalis Kamburelis
Michalis Kamburelis wrote 42 lines
Michael Van Canneyt wrote: > Personally, I prefer the backtick solution. > The triple quote is slow, it requires postprocessing the string. > The backtick solution needs only one pass. > > <rant> > I positively HATE it when people start treating whitespace as > significant. No YAML or Python for me on that account alone. > The triple quote solution (presumably Python inspired) > is a totally braindead and retarded solution as far as I am concerned. > </rant> > > You can guess from that little rant that I myself will certainly not > remove or even deprecate the backtick version. > > If having one soluton for all is the norm, we need to remove a lot more > things from FPC that Delphi did differently than we do. We don't do that either. > Compatibility, yes. But that should not prevent us from doing things our own > way from time to time. > > The solution is simple: > if you don't like the backticks, don't use them. > I can see how this can get into a heated discussion (hopefully it will not!) :) You have the last word when it comes to FPC decisions, obviously. Still, let me try to present the case for "deprecate backticks" again. The problem with your solution """if you don't like the backticks, don't use them.""" -> is that it means we have 2 ways to achieve the same thing in the Pascal language, to the end of time, and users *will* get confused about them and we have 2x more work to explain it. Things like indentation, crlf/native/etc., what happens with last line -> they have now 2 different behaviors, and people who work with various Pascal code (Pas2js, FPC, Delphi) will need to grok them both and remember which {$xxx} affects which. This makes things harder -- to document, to teach, and to not confuse ourselves when reading alien code. For me, solving the above problem ("less confusion by not having 2 syntaxes for same thing") is really more important.

If this argument is to carry any weight, then we also need to remove all instances where FPC did things differently from Delphi:

- operators
- nested comments
- duplicate names in objects
- generics. The FPC implementation differs wildly from Delphi.
- anonymous functions explicitly are interfaces.
- We allow nested functions for function references
- use of @

And I am probably forgetting some.

[snip]

... which makes the indentation looks worse. 2x "something" is now at the same level as "begin".

You forget the directive to remove whitespace. It is intended for exactly this purpose.

And I'm not saying that FPC should now adjust to Delphi by removing all FPC-specific features. Let's not generalize

You are not saying it, but your argument implies it. The 'less confusion' argument is invalidated if you apply it randomly to some particular feature and not to others.

That is for me the heart of the matter and a matter of principle:

Either we adjust to Delphi, or we allow ourselves some freedom.

I am perfectly capable to set aside my personal preferences and adjust. But I chose the latter - the freedom to do things differently - in the interest of compatibility with pas2js:

If it was not for pas2js, we would not have extended RTTI, we would not have webassembly and some other things. Pas2js was and is - and I am serious - vital for FPC's advancement in todays world.

Which means compatibility with this vital piece is important too. If pas2js weren't there, I would simply have adapted the existing implementation to handle the ''' approach, despite the horror this construct arouses in me.

But pas2js exists, I believe it is important, and that explains my decision.

Michael.

Reply by email

Michalis Kamburelis
to Michael Van Canneyt
But pas2js exists, I believe it is important, and that explains my decision.

OK. I will have to accept this decision :) Well I see your arguments (Pas2js compatibility + you feel Delphi design is "horror" :) ). Even if I do see a different decision as more optimal.

For the sake of clarity, I don't really agree with your statement """The 'less confusion' argument is invalidated if you apply it randomly to some particular feature and not to others.""". That is: We do not need to achieve perfect alignment with Delphi in all features, and it's not something I propose, and even if I would push for it some day -- I would say this would have to work both ways (that is, Delphi should also adjust to some decisions from FPC). But that's a discussion for other thread(s). I think that "aligning with Delphi" in this case, multi-line strings (without extrapolating it into any general rule "we resign from FPC-specific language features") has value. We would not follow alignment with Delphi "randomly" -- we would follow alignment when it is easy to achieve (2 syntaxes for multi-line strings achieve the same feature, *and* it it not a feature yet used by FPC developers, only in Pas2js).

Anyhow, that was just for clarity :) I believe I understand your point of view, that's OK.

To be clear, I fully agree that Pas2js, FPC+WebAssembly, are very important. Bringing Pascal to the web browser is a big achievement of FPC/Pas2js developers, and we love it in Castle Game Engine :)

Regards,
Michalis

Reply by email

Sven Barth
to Michael Van Canneyt: If this argument is to carry any weight, then we also need to remove all instances where…

Michael Van Canneyt via fpc-pascal
schrieb am Mo., 28. Juli 2025, 11:21:

Show quoted text 6 lines
If this argument is to carry any weight, then we also need to remove all instances where FPC did things differently from Delphi: [snip] - anonymous functions explicitly are interfaces. [snip]

Anonymous functions *are* provided using interfaces in Delphi. The only difference is that in Delphi an anonymous function is *always* an interface while in FPC it depends on the left hand side as it might be assigned to a function or method pointer if there's nothing captured (except Self in case of method pointers).
Except for this specific point FPC and Delphi behave the same here.

Regards,
Sven

Reply by email

DougC
to Sven Barth

Michael Van Canneyt via fpc-pascal < > schrieb am Mo., 28. Juli 2025, 11:21:

If this argument is to carry any weight, then we also need to remove

all instances where FPC did things differently from Delphi:

False. This argument still carries considerable weight, even if those other instances are not addressed, by attempting to NOT ADD to the list of areas where discrepancies exist. A worthy goal.

Reply by email

Michael Van Canneyt
to Sven Barth: Michael Van Canneyt via fpc-pascal schrieb am Mo., 28. Juli 2025, 11:21: Anonymous…
Sven Barth wrote 12 lines
Michael Van Canneyt via fpc-pascal schrieb am Mo., 28. Juli 2025, 11:21: > If this argument is to carry any weight, then we also need to remove > all instances where FPC did things differently from Delphi: > > [snip] > - anonymous functions explicitly are interfaces. > [snip] Anonymous functions *are* provided using interfaces in Delphi.

I know, but in Delphi it is an implementation detail. In your announcement mail, you said that it is explicit in FPC, namely you can assign an interface with the right signature to a 'reference to procedure'...

That aspect of anonymous functions (or more precisely, "reference to procedure") is what I referred to.

Michael.

Reply by email

Michael Van Canneyt
to DougC: Michael Van Canneyt via fpc-pascal < > schrieb am Mo., 28. Juli 2025, 11:21: If this…
DougC wrote 12 lines
Michael Van Canneyt via fpc-pascal < > schrieb am Mo., 28. Juli 2025, 11:21: If this argument is to carry any weight, then we also need to remove all instances where FPC did things differently from Delphi: False. This argument still carries considerable weight, even if those other instances are not addressed, by attempting to NOT ADD to the list of areas where discrepancies exist. A worthy goal.

'Worthy Goals' are a personal matter. One person may consider 'making lots of money' a worthy goal. Another might find it futile.

In our case, I think that if both parties agree to act on an equal footing, then it could indeed be a worthy goal to minimize differences.

But we've received absolutely zero 'cooperation' from Delphi in this respect. Every feature that arrived first in FPC was done differently in Delphi later.

So you'll understand then that I don't feel inclined to minimize the differences when I am of the opinion that their approach is inferior to ours.

Michael.

Reply by email

Unknown author
to Michalis Kamburelis: I can see how this can get into a heated discussion (hopefully it will not!) :) You have…

Your argument makes no sense.  There's always been multiple ways to do many things in pascal, and it's never caused any more confusion than any other typical language construct.

Take for instance, comments.

{ this is a comment}

works just as well as

(* this is a comment *)

I don't believe I've ever seen you complain about multiple ways to put comments in the code

Would that also cause the same issues as you argue for the multiple line string support?

I'd guess ?

Because some folks use one, and some use the other, functionally they're the same.  Whether one takes more processing than the other isn't something I've bothered to check, but honestly, who cares? Both accomplish the same thing, and folks can use whichever one they like.

I find your arguing about multiline strings to be exactly the same thing.

Who cares?

Use it or don't, it makes no difference to anyone except the programmers that don't like it for whatever obscure reason, but it affects nothing as far as the language is concerned, so why get so worked about it?

I see no confusion here, nor do I agree that it can/will lead to problems you describe, and if it does, then someone can simply use search and replace to solve the problem.

Reply by email

Pierre Muller
to Michalis Kamburelis: I can see how this can get into a heated discussion (hopefully it will not!) :) You have…

Le 28/07/2025 à 10:07, Michalis Kamburelis via fpc-pascal a écrit :

Show quoted text 39 lines
Michael Van Canneyt wrote: > Personally, I prefer the backtick solution. > The triple quote is slow, it requires postprocessing the string. > The backtick solution needs only one pass. > > <rant> > I positively HATE it when people start treating whitespace as > significant. No YAML or Python for me on that account alone. > The triple quote solution (presumably Python inspired) > is a totally braindead and retarded solution as far as I am concerned. > </rant> > > You can guess from that little rant that I myself will certainly not > remove or even deprecate the backtick version. > > If having one soluton for all is the norm, we need to remove a lot more > things from FPC that Delphi did differently than we do. We don't do that either. > Compatibility, yes. But that should not prevent us from doing things our own > way from time to time. > > The solution is simple: > if you don't like the backticks, don't use them. > I can see how this can get into a heated discussion (hopefully it will not!) :) You have the last word when it comes to FPC decisions, obviously. Still, let me try to present the case for "deprecate backticks" again. The problem with your solution """if you don't like the backticks, don't use them.""" -> is that it means we have 2 ways to achieve the same thing in the Pascal language, to the end of time, and users *will* get confused about them and we have 2x more work to explain it. Things like indentation, crlf/native/etc., what happens with last line -> they have now 2 different behaviors, and people who work with various Pascal code (Pas2js, FPC, Delphi) will need to grok them both and remember which {$xxx} affects which. This makes things harder -- to document, to teach, and to not confuse ourselves when reading alien code.

I think that a possible solution would be to allow to restrict the mode switch to allow only triple-quote or only backquote delimiter.

The idea is simply to add:
{$modeswitch multilinestrings triplequote}
and
{$modeswitch multilinestrings backquote}
It is then probably legitimate to also add:
{$modeswitch multilinestrings all}
{$modeswitch multilinestrings none}
Delphi mode can then use
{$modeswitch multilinestrings triplequote}

by default, which means that back-quote will still be refused by the compiler, unless explicit
{$modeswitch multilinestrings backquote}
or
{$modeswitch multilinestrings all}

is used.

pas2js code using back-quote would then need an explicit
{$ifdef FPC}
{$modeswitch multilinestrings backquote}
{$endif FPC}
to get the compiler to accept that syntax...

Michael, would that be OK for the Pas2js part?

In the hope this can be acceptable by all.

Pierre

Reply by email

Michael Van Canneyt
to Pierre Muller
Pierre Muller wrote 79 lines
Le 28/07/2025 à 10:07, Michalis Kamburelis via fpc-pascal a écrit : > Michael Van Canneyt wrote: >> Personally, I prefer the backtick solution. >> The triple quote is slow, it requires postprocessing the string. >> The backtick solution needs only one pass. >> >> <rant> >> I positively HATE it when people start treating whitespace as >> significant. No YAML or Python for me on that account alone. >> The triple quote solution (presumably Python inspired) >> is a totally braindead and retarded solution as far as I am concerned. >> </rant> >> >> You can guess from that little rant that I myself will certainly not >> remove or even deprecate the backtick version. >> >> If having one soluton for all is the norm, we need to remove a lot more >> things from FPC that Delphi did differently than we do. We don't do that either. >> Compatibility, yes. But that should not prevent us from doing things our own >> way from time to time. >> >> The solution is simple: >> if you don't like the backticks, don't use them. >> > > I can see how this can get into a heated discussion (hopefully it will > not!) :) You have the last word when it comes to FPC decisions, > obviously. Still, let me try to present the case for "deprecate > backticks" again. > > The problem with your solution """if you don't like the backticks, > don't use them.""" -> is that it means we have 2 ways to achieve the > same thing in the Pascal language, to the end of time, and users > *will* get confused about them and we have 2x more work to explain it. > Things like indentation, crlf/native/etc., what happens with last line > -> they have now 2 different behaviors, and people who work with > various Pascal code (Pas2js, FPC, Delphi) will need to grok them both > and remember which {$xxx} affects which. This makes things harder -- > to document, to teach, and to not confuse ourselves when reading alien > code. I think that a possible solution would be to allow to restrict the mode switch to allow only triple-quote or only backquote delimiter. The idea is simply to add: {$modeswitch multilinestrings triplequote} and {$modeswitch multilinestrings backquote} It is then probably legitimate to also add: {$modeswitch multilinestrings all} {$modeswitch multilinestrings none} Delphi mode can then use {$modeswitch multilinestrings triplequote} by default, which means that back-quote will still be refused by the compiler, unless explicit {$modeswitch multilinestrings backquote} or {$modeswitch multilinestrings all} is used. pas2js code using back-quote would then need an explicit {$ifdef FPC} {$modeswitch multilinestrings backquote} {$endif FPC} to get the compiler to accept that syntax... Michael, would that be OK for the Pas2js part?

For me this is OK.

Thinking about it: As far as I know, modeswitches do not accept an argument, they are simple booleans ?

Instead we could have a {$MULTILINESTRINGSTYLE NNN} directive and a -Su<type> or -Sl<type> command line switch, with the delphi mode forcing the 'triplequote' style.

Michael.

Reply by email

Hairy Pixels
to Unknown author: Your argument makes no sense.  There's always been multiple ways to do many things in…

On Jul 28, 2025 at 7:26:08 AM, Travis Siegel via fpc-pascal <

Show quoted text 14 lines
wrote: Your argument makes no sense. There's always been multiple ways to do many things in pascal, and it's never caused any more confusion than any other typical language construct. Take for instance, comments. { this is a comment} works just as well as (* this is a comment *)

Yeah that’s not great either. Language tools are going to need to support a new ` token too or syntax styling will breaks. It’s just more work so what’s the point?

On the other hand, why can’t ‘’ simply be used for all string lengths? Can’t think of a practical reason off the top of my head right now.

Regards,
Ryan Joseph

Reply by email

Unknown author
to Unknown author: Your argument makes no sense.  There's always been multiple ways to do many things in…
Travis Siegel wrote 15 lines
Your argument makes no sense.  There's always been multiple ways to do many things in pascal, and it's never caused any more confusion than any other typical language construct. Take for instance, comments. { this is a comment} works just as well as (* this is a comment *) I don't believe I've ever seen you complain about multiple ways to put comments in the code

The two ways to do comments are, IMO, almost essential. The way I was taught to write Pascal, about 45 years ago now, was to use braces for comments - but then if you needed to comment out a whole chunk of code, including multiple comments, you used (* and *) to do it.

Yes, I'm aware that you could accomplish the same thing with compiler directives these days, but I'm far too set in my ways by now, and too old to want to change!

Brian.

Reply by email

Hairy Pixels
to Michael Van Canneyt: That's already since long the case. Personally, I prefer the backtick solution. The…

On Jul 28, 2025 at 1:04:49 AM, Michael Van Canneyt via fpc-pascal <

Show quoted text 13 lines
wrote: Personally, I prefer the backtick solution. The triple quote is slow, it requires postprocessing the string. The backtick solution needs only one pass. <rant> I positively HATE it when people start treating whitespace as significant. No YAML or Python for me on that account alone. The triple quote solution (presumably Python inspired) is a totally braindead and retarded solution as far as I am concerned. </rant>

Maybe I missed something, aren’t both the string types identical in how they function? I don’t understand how there could be multiple passes.

The ‘’’ was probably chosen because it doesn’t introduce a new token and old syntax styles will continue to work without modification. `` is a string and ` opens the “inner string” so everything still works naturally like before in existing editors.

Even doing that may be baggage from decades of ingrained thinking about strings being single lines. If anyone has any non-dogmatic reasons why ‘’ can’t allow multiple lines I’d like to hear them because I’m curious myself.

Regards,
Ryan Joseph

Reply by email

Hairy Pixels
to Unknown author: The two ways to do comments are, IMO, almost essential. The way I was taught to write…

On Jul 28, 2025 at 8:24:38 AM, Brian via fpc-pascal <

Show quoted text 7 lines
wrote: The two ways to do comments are, IMO, almost essential. The way I was taught to write Pascal, about 45 years ago now, was to use braces for comments - but then if you needed to comment out a whole chunk of code, including multiple comments, you used (* and *) to do it.

I think this is historical baggage from {} not being able to nest within each other. There’s no technical reason why {} can’t nest but instead of changing that a new comment was introduced. Seems redundant to me now looking back.

Regards,
Ryan Joseph

Reply by email

DougC
to Hairy Pixels

Actually, in Pascal (* and *) came before { }. But this is quite off topic for this thread, so let's leave it.

Doug C.

---- On Mon, 28 Jul 2025 10:41:31 -0400 Hairy Pixels via fpc-pascal wrote ---

On Jul 28, 2025 at 8:24:38 AM, Brian via fpc-pascal < > wrote:

The two ways to do comments are, IMO, almost essential. The way I was taught to write Pascal, about 45 years ago now, was to use braces for comments - but then if you needed to comment out a whole chunk of code, including multiple comments, you used (* and *) to do it.

I think this is historical baggage from {} not being able to nest within each other. There’s no technical reason why {} can’t nest but instead of changing that a new comment was introduced. Seems redundant to me now looking back.

Regards,

    Ryan Joseph

Reply by email

Michael Van Canneyt
to Hairy Pixels: On Jul 28, 2025 at 1:04:49 AM, Michael Van Canneyt via fpc-pascal < Maybe I missed…
Hairy Pixels wrote 17 lines
On Jul 28, 2025 at 1:04:49 AM, Michael Van Canneyt via fpc-pascal < > wrote: > Personally, I prefer the backtick solution. > The triple quote is slow, it requires postprocessing the string. > The backtick solution needs only one pass. > > <rant> > I positively HATE it when people start treating whitespace as > significant. No YAML or Python for me on that account alone. > The triple quote solution (presumably Python inspired) > is a totally braindead and retarded solution as far as I am concerned. > </rant> > Maybe I missed something, aren’t both the string types identical in how they function? I don’t understand how there could be multiple passes.

Because the amount of whitespace to remove at the start of every line is determined by the amount of spaces before the closing triple quotes.

Ergo, you can only strip the whitespaces at the start of every line after the whole string was parsed and you have determined the number of whitespace characters to remove from every line... -> 2 passes.

Michael.

Reply by email

Hairy Pixels
to Michael Van Canneyt
Michael Van Canneyt wrote 8 lines
Because the amount of whitespace to remove at the start of every line is determined by the amount of spaces before the closing triple quotes. Ergo, you can only strip the whitespaces at the start of every line after the whole string was parsed and you have determined the number of whitespace characters to remove from every line... -> 2 passes.

oh I re-read the first email and see its implemented differently.

I’ve been using multi lines strings in Swift for my day job for a few years now and got used to the “”” style which include indentation too and I’ve had no complaints. Since whitespace is important to multiline strings having the compiler enforce indentation rules makes sense to me.

Personally I’ll be using the ‘’’ variant so I don’t need to change syntax definitions in Sublime Text + VSCode and how many others that I may come across.

Regards,
Ryan Joseph

Reply by email

Michalis Kamburelis
to Unknown author: Your argument makes no sense.  There's always been multiple ways to do many things in…
Your argument makes no sense. There's always been multiple ways to do many things in pascal, and it's never caused any more confusion than any other typical language construct.

I don't think the comparison to "multiple ways to write a comment" is proper here. Because various ways to write comments, { } and (* *) and //, have all their use-cases. In particular, you can write

(*
{ Some comment about Foo. }
procedure Foo;
begin
end;
*)

to comment entire Foo, with all its comments. This is useful. We all probably used this feature from time to time.

This is different than 2 ways to write multi-line strings, which really achieve the same, I feel.

Moreover, in case of multi-line comments, the additional confusion (which I still think is possible) is because there are {$xxx} compiler directives changing their behavior, and some of them apply only to backtick-style, some only to ''' style, and from their naming ($MULTILINESTRINGLINEENDING / $TEXTBLOCK) it's not clear which applies to which. We will have to remember that $MULTILINESTRINGLINEENDING is for backticks-style, and $TEXTBLOCK is for '''-style.

That is why I say that it's not optimal to have 2 ways to do the same thing. The language is more obvious to read and write if we don't need to deal with 2 ways to achieve the same.

On the same ground, we would all protest if someone tried to introduce alternative way to write "assignment operator", just because some people would like to write "A := B", while others "A <- B". It's not that ":=" or "<-" is better, it's that "one version of doing it should be enough".

( But I do recognize that my comparison above is also flawed. Because comparisons are usually somewhat simplifying the reality. E.g. what if Pas2js had an alternative assignment operator, for some good reason? Anyhow, this is going to off-topic. My focus and my point in this thread was on the multi-line strings case. And I guess this is already decided, we'll have both, I can certainly live with this :), I'll just have to explain to people who I teach about these 2 ways. )

Regards,
Michalis

Reply by email

Martin Frb
to Michalis Kamburelis
Michalis Kamburelis wrote 7 lines
Moreover, in case of multi-line comments, the additional confusion (which I still think is possible) is because there are {$xxx} compiler directives changing their behavior, and some of them apply only to backtick-style, some only to ''' style, and from their naming ($MULTILINESTRINGLINEENDING / $TEXTBLOCK) it's not clear which applies to which. We will have to remember that $MULTILINESTRINGLINEENDING is for backticks-style, and $TEXTBLOCK is for '''-style.

Maybe they should be named different... I guess the tripple quote directives match up with Delphi?
(Otherwise MultiQuoteString ?)

But the backtick, could have BacktickString or BackQuoteString in the name?

Show quoted text 5 lines
On the same ground, we would all protest if someone tried to introduce alternative way to write "assignment operator", just because some people would like to write "A := B", while others "A <- B". It's not that ":=" or "<-" is better, it's that "one version of doing it should be enough".
Or have array element index done different?
   type TFooArray = array (.0..9.) of Byte;
     SomeFooArray(.3.) := 1;

Oh wait, that compiles. ;)

Reply by email

Sven Barth
to Pierre Muller: Le 28/07/2025 à 10:07, Michalis Kamburelis via fpc-pascal a écrit : I think that a…

Pierre Muller via fpc-pascal schrieb am
Mo., 28. Juli 2025, 15:27:

Show quoted text 54 lines
Le 28/07/2025 à 10:07, Michalis Kamburelis via fpc-pascal a écrit : > Michael Van Canneyt wrote: >> Personally, I prefer the backtick solution. >> The triple quote is slow, it requires postprocessing the string. >> The backtick solution needs only one pass. >> >> <rant> >> I positively HATE it when people start treating whitespace as >> significant. No YAML or Python for me on that account alone. >> The triple quote solution (presumably Python inspired) >> is a totally braindead and retarded solution as far as I am concerned. >> </rant> >> >> You can guess from that little rant that I myself will certainly not >> remove or even deprecate the backtick version. >> >> If having one soluton for all is the norm, we need to remove a lot more >> things from FPC that Delphi did differently than we do. We don't do that either. >> Compatibility, yes. But that should not prevent us from doing things our own >> way from time to time. >> >> The solution is simple: >> if you don't like the backticks, don't use them. >> > > I can see how this can get into a heated discussion (hopefully it will > not!) :) You have the last word when it comes to FPC decisions, > obviously. Still, let me try to present the case for "deprecate > backticks" again. > > The problem with your solution """if you don't like the backticks, > don't use them.""" -> is that it means we have 2 ways to achieve the > same thing in the Pascal language, to the end of time, and users > *will* get confused about them and we have 2x more work to explain it. > Things like indentation, crlf/native/etc., what happens with last line > -> they have now 2 different behaviors, and people who work with > various Pascal code (Pas2js, FPC, Delphi) will need to grok them both > and remember which {$xxx} affects which. This makes things harder -- > to document, to teach, and to not confuse ourselves when reading alien > code. I think that a possible solution would be to allow to restrict the mode switch to allow only triple-quote or only backquote delimiter. The idea is simply to add: {$modeswitch multilinestrings triplequote} and {$modeswitch multilinestrings backquote}

We will *not* extend the modeswitch directive for something like that.

Regards,
Sven

Reply by email

Sven Barth
to Unknown author: Your argument makes no sense.  There's always been multiple ways to do many things in…

Travis Siegel via fpc-pascal schrieb am
Mo., 28. Juli 2025, 15:42:

Show quoted text 12 lines
Take for instance, comments. { this is a comment} works just as well as (* this is a comment *) I don't believe I've ever seen you complain about multiple ways to put comments in the code

That is a bad example, because the second syntax is a digraph of the first, just like you can use "(." for "[" and ".)" for "]". In the ISO modes you can even close a "{" comment with "*)" and vice versa, because they are aliases.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Hairy Pixels
Hairy Pixels wrote 11 lines
On Jul 28, 2025 at 10:13:20 AM, Martin Frb via fpc-pascal < > wrote: > Or have array element index done different? > type TFooArray = array (.0..9.) of Byte; > SomeFooArray(.3.) := 1; > > Oh wait, that compiles. ;) > never saw that before! so ugly too. Why does it compile?

Sven already said it:

Because (. .) is a valid alternative for [ ]

The first syntax is a "digraph" of the second syntax, dates back to the times when not all characters were available on keyboards.

Goes to show that Pascal is an old language. But still going strong ;-)

Michael.

Reply by email