New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC FS-1001 Discussion] String Interpolation #6
Comments
I presume the approach of using Concat is preferred over generating "%d%O%d%O" because of the difficult in inserting "foo" and "bar.bar" at the right points in the argument list? |
Re "Should embedded expressions be restricted to just identifiers\dotted names or we should allow full set of F# expressions" - I'm fairly strongly inclined to the position that allowing arbitrary expressions will hurt code readability, somewhat needlessly. Restricting to identifiers or a very simple class of expressions seems sensible. |
Re: "Should we provide ways to specify width\precision\alignment similar to what [printf][6] is doing today? If yes - what modification should be made to the proposed syntax?" I don't tend to like language features that lead to a non-localized discontinuity when you want to "do the obvious next thing" in a programming sequence - for example, format a displated number 5.6234 to two decimal places - 5.62. These kinds of discontinuities are a PITA for teachers - do they teach the "simple but ultimately way too limited" version of printing - %(foo), or do they teach the "complete but more complex" way of doing things - %d, %0.2d etc. So my inclination is that we need to handle width/precision/alignment specifiers. Does %0.2(foo) seem reasonable? |
Yes, this is one of reasons. i.e. when embedded expressions in format string are interleaved with format specifiers then
This is an interesting question from the implementation perspective. We already have implementation for the one extreme: allowing arbitrary F# expression - in this case we can just reuse existing parser. Another extreme: allowing just identifiers\dotted expressions - writing parser for this case will be trivial. Any other options will require making customized parser that will recognize only limited subset of expressions. Personally I would not go in this direction and allow anything so it will be responsibility of the consumer to write the readable code.
Yes, I like it. |
Unfortunately the corresponding pull request on codeplex was closed because of release pressure. Can we somehow revive this? String interpolation is a feature that a lot of users would like to see. |
Ok I rebased it on master: dotnet/fsharp#921 |
a question: are we supporting localization correctly? msdn about c# string interpolation It's not only about a better string format, need to support i18n too. C# does that because string interpolation does implicit type conversion to FormattableString var s = $"hello, {name}"
System.IFormattable s = $"Hello, {name}"
System.FormattableString s = $"Hello, {name}" so var product = "Raspberry Pi";
var price = 25.0;
Console.WriteLine(LocalizationHelper.Format(
$"The price of {product} is {price}.";
));
If the preferred way for f# is explitic, i think we need another function like |
(I posted this originally in the wrong thread (the implementation thread).) I assume most people here know the Scala solution to this, but just in case I want to point that one out, as I think it is quite elegant. The key point is that it has a concise syntax and is extensible.
with formatting:
The above examples are taken from: And plain SQL queries: (http://slick.typesafe.com/doc/3.1.1/sql.html#string-interpolation)
and even things like ReactJS-like JSX/TSX xml-based syntax:
(example from http://docs.scala-lang.org/sips/completed/string-interpolation.html) |
scala syntax and extensibility it's really interesting, |
Note that ES6 seems to have the same syntax as Scala, even down to the extensibility. ("tagged template literals") |
I'm with @isaacabraham on using the Since we'll know the type the expression resolves to we can determine which formatting specifications to enable. For most types -
If it resolves to a numeric type
The primitive types can follow the same style of formatting that
Additional Questions -
|
@cloudRoutine sorry for being late in the party, but you say
Would it be conflicting to use |
@smoothdeveloper
And if for some bizarre reason you feel the need to define a bunch of expressions within the scope of the substitution block, with several lambdas and function calls, there'll be parens all over the place. But it'll be nice and easy to see the bounds around it, thanks to those |
@cloudRoutine thanks, it makes more sense with the expanded description, I took scope as something akin to how it is used in C# but not as being different context as you explain. As for what goes in the interpolated strings, you'd be surprised of what can be found in code in the wild even though that feature was only recently added to C# 6, I won't be surprised to find tuples or records, and why not object expression since it can be done :) |
By adding another instead of needing to write helper functions like let makeString (arg:MyDu) =
sprintf "adjsk -- %O" arg the
which may not immediately seem useful, but for partial application it could provide a lot of value. perhaps |
I think we are in a classical "analysis paralysis" :) What about implementing a minimal functionality first, keeping the door open for further improvements?
So we would ended up with this: let s = $"This feature is {x}!" "awesome" Great things about it:
In short, I believe we should implement anything to move forward with this, then, according to feedback, make it great. |
I'm with vasily here... Go with the existing C# syntax. It's clean and it works. Most importantly it will be a natural transition for those of us who have to bounce back and forth between C# and F# all day. I find myself trying to do this all the time in F#, then remembering it's (sadly) not there (yet). If you need custom formatting, just do it inside the {}, after all it's just an expression. This is the feature I miss most from C# when working in F#, so it would be nice to see this feature sooner rather than later. |
I really would like to have this feature soon in F# with the same syntax it's implemented in C# because I also think it works very well! Is there anything we can do to continue the discussion and or to receive an approval? |
@realvictorprm Yes, we need to find a way to progress this. We need to go back to some basics - e.g. I'm now inclined to agree we should go with the C# syntax for this |
Hm as soon as it's approved I would love to try implementing it to get a grasp of how adding features to the compiler works. |
@realvictorprm Adding string interpolation is "approved in principle" (i.e. "planned" in https://fslang.uservoice.com/forums/245727-f-language/suggestions/6002107-steal-nice-println-syntax-from-swift) Next step is either to implement the C# syntax, or edit the RFC to capture that as a proposed design |
So I could just start looking how to start implementing it, right? I've a pretty big interest in this because generator stuff etc. involves big string interpolation. On the C# side the code is very readable thanks to the interpolation feature but with F# readability is lacking here really much. Is there any pointer you can give me where to code should start? E.g the place where strings are being checked? |
@realvictorprm see initial attempt dotnet/fsharp#921 |
And a new case:
|
yeah I'm a bit before this point, I just added all necessary stuff in the parser and lexer. Now after I understand how it works it's a lot easier 😅 |
@realvictorprm Great work! |
I cannot find here what's the final decision on Not defending EF Core team decision but reality is more APIs like that will show up and it would be nice to have smooth inter-op in F#. |
I didn't saw that one @dmitry-a-morozov. I just went through it a small bit and it sounds like a formatting function or whatever. Just something which wraps the operation which would be done instantly. However as always I highly discourage any and I really mean any implicit conversion in F#. Therefore if we want interop with other stuff out there we must acquire it with either 1. a different syntax or 2. we change our mind about interpolated strings in such a way that they are functions which can be executed (which is very unlikely). I'm pretty open for using another prefix for strings to signal that the formatting shouldn't be executed instantly rather instead a function or formatting object should be returned (maybe it's a function string then 😛 ?). This however would be the same as shortcutting the sprintf function @dmitry-a-morozov I think. Maybe something like this (prefix stands for function)? let formatDefinition = f"let {name} = {definition}" |
What is the status of this? |
@iddan There have been a few PRs from the community, but none have been merged. |
What blocks them from being merged? |
We hold a high bar for features getting merged into the compiler, and that means a significant time investment on behalf of us and the person implementing it. We haven't prioritized the feature above other things to do ourselves, so that time investment lies on a community member if they have a strong desire to see the feature in an upcoming version of the language. |
Is there a transparent lifecycle of a proposal? |
There are info about process in the README More info this specific issue status in the RFC doc https://github.com/fsharp/fslang-design/blob/master/RFCs/FS-1001-StringInterpolation.md |
according to dotnet/fsharp#3593, there are currently two work items:
I suggest, if we care enough about this feature, we can at least "crowdsource" some test cases. |
I'm trying to bring it back upon current TODO: TODO: TODO: TODO: |
creating a temp PR here: https://github.com/yatli/visualfsharp/pull/1 edit: compiler's up. feel free to suggest test patterns. I'll work on the TODOs |
I'd suggest decompose FS-1001 into two components, and make them more native to what we already have by using simple transformations of the syntax tree rather than introducing new mechanisms: Part 1: transform In this way string interpolation will work well with the I'll have to think about mixing inline arguments with plain formatting placeholders -- the order is the key, for example: In this way we don’t even need a new ast case. I’ll ping back when I make progress. |
Actually part 1 can be done in the library not the compiler, by making $ an operator that works just like sprintf. |
After some thoughts, i think it’s impossible to have one-level formatting if inline arg and placeholders are mixed. The correct way of handling this is to create a closure that captures the inline argument, and output a new formatter. |
I'm opening a draft PR, and I will begin documenting my design. |
Completely agree with @vasily-kirichenko
If this will work var s = $"hello, {name}" it would cover 85-95% of my problems. For the remaining ones I can write sprintf. I believe I'm not alone and most of the people would be quite happy just having this. |
It's not like I've done that in the past lol. Even if I started it only :D |
After far too long I've added a comment about the design for this RFC here: dotnet/fsharp#6770 (comment) |
Thanks :)!
Don Syme <notifications@github.com> schrieb am Mo., 1. Juli 2019, 15:40:
… After far too long I've added a comment about the design for this RFC
here: dotnet/fsharp#6770 (comment)
<dotnet/fsharp#6770 (comment)>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#6?email_source=notifications&email_token=AGB4Z4HVA67UL2LHI5I4U3DP5ICNHA5CNFSM4ARLNFR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY6E7JI#issuecomment-507269029>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AGB4Z4GYOBBFQ2RN5AZHUZ3P5ICNHANCNFSM4ARLNFRQ>
.
|
I've rewritten the RFC. Closing in favour of new discussion thread #368 |
This issue is used to track discussions of F# RFC FS-1001 - "String interpolation"
The text was updated successfully, but these errors were encountered: