Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 10, 2017 Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
D has a very nice feature of token strings: string a = q{ looksLikeCode(); }; It is useful in writing mixins and to have syntax highlighting in editors. Although I like it, it is not something I ever felt like missing in other languages. What I do always miss are these two options: 1. Have something like this: string a = |q{ firstLine(); if (cond) { secondLine() } }; mean count the number of whitespace characters at the start of a first new line of string literal and then strip up to that many whitespace characters from the start of each line. 2. If we just put for example "-" instead of "|" in above example have that mean: replace all whitespace with a single space in following string literal. I think it is clear why would these be useful but if you want me I can add a few examples. This would not make any breaking changes to the language and it should be possible to simply implement it wholly in the lexer. So what do think? |
October 11, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor | > string a = |q{
> firstLine();
> if (cond) {
> secondLine()
> }
> };
you could write your own string processing function according to your needs to filter the code string, and use it like
string a = inject(q{...}) //or
string a = inject!(formatOpts)(q{...})
i have done this myself and also included positional argument formatting to my liking, optimized for CT code generation. don't have the code at my hands ATM though. could post it later if you are interested.
/det
|
October 10, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to captaindet | On Tuesday, 10 October 2017 at 21:38:41 UTC, captaindet wrote: >> string a = |q{ >> firstLine(); >> if (cond) { >> secondLine() >> } >> }; > > you could write your own string processing function according to your needs FWIW, that's the solution in Python: https://docs.python.org/release/3.6.3/library/textwrap.html#textwrap.dedent Works even better in D because it can run at compile time. |
October 11, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to sarn | On 10/10/2017 3:16 PM, sarn wrote:
> Works even better in D because it can run at compile time.
Yes, I see no need for a language feature what can be easily and far more flexibly done with a regular function - especially since what |q{ and -q{ do gives no clue from the syntax.
|
October 11, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wednesday, 11 October 2017 at 08:35:51 UTC, Walter Bright wrote:
> On 10/10/2017 3:16 PM, sarn wrote:
>> Works even better in D because it can run at compile time.
>
> Yes, I see no need for a language feature what can be easily and far more flexibly done with a regular function - especially since what |q{ and -q{ do gives no clue from the syntax.
You are right. My mind is just still not used to the power of D templates so I didn't think of this. On the other hand that is why D is still making me say "WOW!" on a regular basis :).
Just to confirm I understand, for example the following would give me compile time stripping of white space:
template stripws(string l) {
enum stripws = l.replaceAll(regex("\s+", "g"), " ");
}
string variable = stripws(q{
whatever and ever;
});
And I would get variable to be equal to " whatever and ever; ". Right?
|
October 11, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor | On Wednesday, 11 October 2017 at 09:56:52 UTC, Igor wrote:
> On Wednesday, 11 October 2017 at 08:35:51 UTC, Walter Bright wrote:
>> On 10/10/2017 3:16 PM, sarn wrote:
>>> Works even better in D because it can run at compile time.
>>
>> Yes, I see no need for a language feature what can be easily and far more flexibly done with a regular function - especially since what |q{ and -q{ do gives no clue from the syntax.
>
> You are right. My mind is just still not used to the power of D templates so I didn't think of this. On the other hand that is why D is still making me say "WOW!" on a regular basis :).
>
> Just to confirm I understand, for example the following would give me compile time stripping of white space:
>
> template stripws(string l) {
> enum stripws = l.replaceAll(regex("\s+", "g"), " ");
> }
>
> string variable = stripws(q{
> whatever and ever;
> });
>
> And I would get variable to be equal to " whatever and ever; ". Right?
Even better, you could write the same code that you would for doing this at runtime and it'll Just Work:
string variable = q{
whatever and ever;
}.replaceAll(regex(`\s+`, "g"), " ");
|
October 12, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2017-10-11 10:35, Walter Bright wrote: > On 10/10/2017 3:16 PM, sarn wrote: >> Works even better in D because it can run at compile time. > > Yes, I see no need for a language feature what can be easily and far more flexibly done with a regular function - especially since what |q{ and -q{ do gives no clue from the syntax. Unfortunately it doesn't work for the other multiline syntax: void main() { auto a = q"FOO int b = 3; FOO"; } The above fails to compile [1]. The trailing FOO cannot be indented. This works: void main() { auto a = q"FOO int b = 3; FOO"; } Which in my opinion doesn't look as good as the first example. It gets worse if "a" is indented even more, because it's nested in a class, in a method, in an if statement and so on. [1] main.d(3,14): Error: unterminated delimited string constant starting at main.d(3,15) -- /Jacob Carlborg |
October 12, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Wednesday, 11 October 2017 at 14:28:32 UTC, Meta wrote: > On Wednesday, 11 October 2017 at 09:56:52 UTC, Igor wrote: >> On Wednesday, 11 October 2017 at 08:35:51 UTC, Walter Bright wrote: >>> On 10/10/2017 3:16 PM, sarn wrote: >>>> Works even better in D because it can run at compile time. >>> >>> Yes, I see no need for a language feature what can be easily and far more flexibly done with a regular function - especially since what |q{ and -q{ do gives no clue from the syntax. >> >> You are right. My mind is just still not used to the power of D templates so I didn't think of this. On the other hand that is why D is still making me say "WOW!" on a regular basis :). >> >> Just to confirm I understand, for example the following would give me compile time stripping of white space: >> >> template stripws(string l) { >> enum stripws = l.replaceAll(regex("\s+", "g"), " "); >> } >> >> string variable = stripws(q{ >> whatever and ever; >> }); >> >> And I would get variable to be equal to " whatever and ever; ". Right? > > Even better, you could write the same code that you would for doing this at runtime and it'll Just Work: > > string variable = q{ > whatever and ever; > }.replaceAll(regex(`\s+`, "g"), " "); I tried this but Disassembly view shows: call std.regex.regex!string.regex and call std.regex.replaceAll!(string, char, std.regex.internal.ir.Regex!char).replaceAll which means that replaceAll with regex is done at runtime, not compile time. Also when I just added enum in front of string variable then I got this: Error: malloc cannot be interpreted at compile time, because it has no available source code |
October 12, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Igor | On Thursday, 12 October 2017 at 08:08:17 UTC, Igor wrote:
> I tried this but Disassembly view shows:
>
> call std.regex.regex!string.regex
> and
> call std.regex.replaceAll!(string, char, std.regex.internal.ir.Regex!char).replaceAll
>
> which means that replaceAll with regex is done at runtime, not compile time. Also when I just added enum in front of string variable then I got this:
>
> Error: malloc cannot be interpreted at compile time, because it has no available source code
Hmm, you're right. I could've sworn that std.regex is CTFE-friendly but it looks like I was wrong. If it used the GC instead of malloc this would probably work.
|
October 13, 2017 Re: Multiline string literal improvements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Thursday, 12 October 2017 at 16:59:46 UTC, Meta wrote: > On Thursday, 12 October 2017 at 08:08:17 UTC, Igor wrote: >> I tried this but Disassembly view shows: >> [snip] > > Hmm, you're right. I could've sworn that std.regex is CTFE-friendly but it looks like I was wrong. If it used the GC instead of malloc this would probably work. Indeed it’s been an ongoing work to make regex match at CTFE. I considered peperring the code paths with __ctfe ? malloc ... : new[] But it a lot of corner cases snd run-time optimized code path is already quite impenetrable. |
Copyright © 1999-2021 by the D Language Foundation