Uh oh!
There was an error while loading. Please reload this page.
[RFC FS-1001 POC] String Interpolation [WIP] - #6770
Conversation
Status
ScratchpadLine 2641 in 8397008 Looks like this is the master entry for "r-values"?
|
forki
commented
May 20, 2019
yatli
commented
May 20, 2019
Anything I should do at the moment? |
cartermp
commented
May 20, 2019
yatli
commented
May 21, 2019
I've signed the CLA. Working on |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
realvictorprm
commented
Jun 17, 2019
cool stuff :) |
cartermp
commented
Jun 17, 2019
Tagging @dsyme for design review |
yatli
commented
Jun 20, 2019
@realvictorprm@forki I'm wondering if we could team up on this? |
realvictorprm
commented
Jun 20, 2019
@yatli convinced, are you on the F# Slack? |
yatli
commented
Jun 20, 2019
@realvictorprm yeah, I've just joined |
forki
commented
Jun 20, 2019
via email
Well, that was long time ago ;-)
Any concrete questions or things you want me to do?
Yatao Li <notifications@github.com> schrieb am Do., 20. Juni 2019, 13:18: …@realvictorprm <https://github.com/realvictorprm> yeah, I've just joined
FSF FSSF :D
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#6770?email_source=notifications&email_token=AAAOANBEPBMCJSA4U5ENGCTP3NRRDA5CNFSM4HNZ2MP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYFDSZY#issuecomment-503986535>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAOANHF5LWWHP5PJT4LJYLP3NRRDANCNFSM4HNZ2MPQ>
.
|
yatli
commented
Jun 20, 2019
@forki no worry, one question for now: |
cartermp
commented
Jul 2, 2019
There are a lot of design discussions going on here. Can we capture some of this in an RFC? I think I generally agree with the direction and @dsyme suggestions here. But there are some sub-points that would need a separate design discussion. For example, for verbatim interoplated strings, what about both Additionally we'd have to adjust tooling to account for understanding when we're in an interoplated context (and complete the |
@cartermp yes I agree. There are details that are not covered in FS-1001, some of these points are already well-aligned, and some needs further convergence. I'm listing some of the well aligned points here (may have missed something):
The thing that still doesn't come to its fixed-point in my head is, whether the interpolated form should be a The former incorporates well with the printf family, while the latter is more of the "embracing the C# way" style. I prefer the former because, it implies that we plant our support for Some complexities in extending the printf family: |
dsyme
commented
Jul 3, 2019
@cartermp I will rewrite FS-1001 today |
@dsyme shall we split out the proposal to extend |
dsyme
commented
Jul 3, 2019
It would be great to get it all in together, as a complete package, but I think it depends on whether you feel it fits into the implementation and testing reasonably. |
yatli
commented
Jul 3, 2019
I'd love to do it altogether -- just want to make sure that this is indeed the plan :) |
dsyme
commented
Jul 3, 2019
Could we make it that both interpolated and non-interpolated strings are considered compatible with all of these, depending on the known type from type checking?
I think it would just really surprise people if non-interoplated strings could ever have interpolation fills when used as printf-style format strings. Also not backwards compatible is it, if the format for interpolation is
Yes, I agree with this
My thinking was that
So you could have
yes
I think pretty much no one uses BTW you can find me on F# Software Foundation Slack and we can chat there if you like |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
dsyme
commented
Jul 31, 2019
@yatli Have you been able to make more progress here? Is there anything we can help with? |
yatli
commented
Jul 31, 2019
@dsyme thanks for getting back :) |
yatli
commented
Jul 31, 2019
it'll be great if we can do some coding together :) |
dsyme
commented
Jul 31, 2019
Can you msg me on FSSF Slack? Maybe late August |
naughtyGitCat
commented
Jan 11, 2020
Now is 2020, Is there any new progress on string interpolation? It's quite a practical feature😀 |
varon
commented
Mar 7, 2020
dsyme
commented
Apr 7, 2020
Hi @yatli, I'm thinking of taking another look at this. Would you like to still work on it with me for the next iteration? |
dsyme
commented
Apr 7, 2020
(I'm starting with prototyping the lexer and parser changes) |
yatli
commented
Apr 8, 2020
via email
@yatli I'm going to close this PR and start a new one coming from a feature branch |
dsyme
commented
Apr 8, 2020
Replaced by #8907 |
yatli
commented
Apr 8, 2020
sounds great! |
dsyme
commented
Apr 8, 2020
Continued at #8907 |
Planning
This is the beginning of my take on FS-1001 (fsharp/fslang-design#6, fsharp/fslang-design#368) -- I have just started to code it, but I'd like to know what you think.
In this thread, I will interchangeably call the original formatting specifiers "deferred specifier", and inline interpolations "immediate specifier".
New Tokens and Types
We'll have to introduce new tokens & non-terminals in the parser to accommodate the interpolated string information. Given a string:
We want to tokenize the string into:
When we parse the token stream:
In the parser, we can deduce with the following rules:
Tokenizer Challenges
If we let the hierarchy of nested interpolation slip from the lexer to the parser, we will have to construct ad-hoc parser and start over again. This is not desirable. However, to get a clean token stream considering all the syntax/semantics is a bit challenging. Here's how it's done in Roslyn
https://github.com/dotnet/roslyn/blob/14e0068d9d529ade86c0ed1544477a221809d0e0/src/Compilers/CSharp/Portable/Parser/Lexer_StringLiteral.cs#L222
So basically they hoist a non-regular, mini parser that counts braces.
There are two approaches for us:
}is encountered, either yieldRBRACE, or resume the string lexer to yield eitherSIP_MIDorSIP_RIGHT.Option 2 is perhaps more maintainable, because it does not drift away from the "real lexer".
Implementing FS-1001
Suppose we have the token stream properly parsed, and we have
STRING_INTEROPnodes in the untyped AST. The string formatters are generated at a much later stage, in src/fsharp/CheckFormatStrings.fs, which is only called by the type checkerfsharp/src/fsharp/TypeChecker.fs
Line 6851 in 8397008
There are two situations here.
The interpolated string does not have a "deferred" specifier.Case 1
No deferred specifier means that we don't have to worry about string formatters. Simply move away from the path stringOrKeywordString -> rawConstant -> constant -...-> later picked up by the type checker, and translate our node as appropriate.After translation, we should get something like:edit: for the completeness of the feature we have to go for case 2.
Case 2
The harder case. We will have to make a closure to capture the interpolated expressions, and return a string formatter for the "deferred" parts.
fsharp/src/fsharp/FSharp.Core/printf.fs
Line 1519 in 8397008
The runtime support is here.
If we capture the immediate values in the format, we can translate the format string to indicate the index of the captured values -- for example,
%{s:1}means to extract fromformat.Captures.[1]Currently, in the front end (printf), I'm putting the captures in the
Formatobjects, and I assume it will be populated by the backend-generated code.FormatSpecifiernow optionally holds the index of the capture target.The capture arrays are then forwarded to the ctor of PrintfEnv's.
The builder now handles "Begin-with-capture" arguments on the builder stack. (wip)
The
Printf.Specializationclass is updated with captured value builders. To prevent combinatorial explosion, we restrict that a capture must be the first argument in the argument pack.In the main builder, each time an immediate spec is encountered, the pack should be "flushed".
New builders in the families
FinalCaptureX,FinalFastCaptureX, ... ,ChainedCaptureX, ... ,LittleAChainedCaptureX, ... are added.Note that a format specifier can be both immediate capture and special, so we have to extend the main builder for the special form to consider captures.
Your input is much appreciated!