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
\" escape does not work with string interpolation #6476
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6476?orig=1 |
@paulp said: |
Denis Petrov (denis) said (edited on Oct 4, 2012 3:24:35 PM UTC): Without interpolation, single quote literals could represent any string using escapes (triple-quoted cannot represent """) Thus, a code generator (i.e. template engine) cannot use triple quoted in the emitted code, as literals are not known in advance. But as result of this escaping rules, a code generator cannot use string interpolation at all. |
Denis Petrov (denis) said: |
@retronym said: I know it's a little clunky, but your code generator could create: scala> s"${'"'}"
res1: String = " |
Denis Petrov (denis) said: |
Radim Kolar (hsn) said: |
@jrudolph said: I agree to what Denis said: as there is a new escape character |
@retronym said: |
@densh said: q"method.call($"mystring in a quasiquote$")" |
@retronym said (edited on Sep 19, 2013 4:03:44 PM UTC): Update Scala parser: retronym/scala@scala:master...ticket/6476 Update IntelliJ parser: https://github.com/retronym/intellij-scala/compare/topic/SI-6476 Starting a [scala-internals] discussion: https://groups.google.com/d/msg/scala-internals/_DnZGO-4NXc/xNoiOUoCf58J |
Jason Swartz (swartzrock) said: A triple-quoted string interpolation should preserve the backspace. |
@som-snytt said: Clarifying the previous comment: scala> implicit class `literally the string`(val sc: StringContext) {
| def lit(args: Any*): String = {
| sc.checkLengths(args)
| sc.standardInterpolator(identity, args)
| }}
defined class literally$u0020the$u0020string
scala> val a = "42" ; s"""a=\"$a\";"""
a: String = 42
res4: String = a="42";
scala> val a = "42" ; lit"""a=\"$a\";"""
a: String = 42
res5: String = a=\"42\"; Clarifying a previous suggestion to use octal escapes, they are deprecated somewhat: scala> implicit class `strictly ess`(val sc: StringContext) {
| def S(args: Any*): String = {
| sc.checkLengths(args)
| sc.standardInterpolator(StringContext.processEscapes, args)
| }}
defined class strictly$u0020ess
scala> val a = "42" ; s"\042$a\042"
a: String = 42
res0: String = "42"
scala> val a = "42" ; S"\042$a\042"
scala.StringContext$InvalidEscapeException: invalid escape character at index 0 in "\042"
at scala.StringContext$.treatEscapes0(StringContext.scala:208)
at scala.StringContext$.processEscapes(StringContext.scala:189)
at strictly$u0020ess$$anonfun$S$1.apply(<console>:10)
at strictly$u0020ess$$anonfun$S$1.apply(<console>:10)
at scala.StringContext.standardInterpolator(StringContext.scala:121)
at strictly$u0020ess.S(<console>:10)
... 32 elided
scala> :se +deprecation
scala> val a = "42" ; f"\042$a\042"
<console>:11: warning: Octal escape literals are deprecated, use \u0022 instead. And of course as noted previously, that advice is only good for triple-quotes. There's a comment in the code to upgrade the advice to dollar-quote when that is merged someday. |
@som-snytt said (edited on Jul 9, 2014 5:12:18 AM UTC): https://groups.google.com/d/msg/scala-sips/rem6D3XTkPY/08v2X0ZpmgsJ The literal quote is what @retronym would call the least controversial bit. |
@som-snytt said: and I never understood the confusion over this topic. I find the arguments against the interpolator receiving the raw text unconvincing. (That escapes must be processed at one layer as meta-escapes and so on.)
I think the compiler should satisfy that customer. |
Kevin Lee (kevinlee) said: a
b a bug or not? |
@som-snytt said: http://www.scala-lang.org/api/2.11.7/index.html#scala.StringContext@s%28args:Any*%29:String |
Kevin Lee (kevinlee) said: |
Isiah Meadows (impinball) said:
|
@som-snytt said: |
@som-snytt said: |
@SethTisue said: |
@som-snytt said: |
@som-snytt said: |
@som-snytt said: |
Denis Petrov (denis) said: scala> "c:\\user"
res0: String = c:\user
scala> """c:\\user"""
res1: String = c:\\user
scala> """c:\user"""
<console>:1: error: error in unicode escape
"""c:\user"""
^
scala> """c:\u005Cuser"""
res2: String = c:\user
� |
@som-snytt said: scala> f"""c:\\user"""
res3: String = c:\user |
Daniel Gordon (Dgordon) said:
So in my code - no problem, I can use two backslashes (even though that defeats the whole purpose of triple quotes). However, code like this will be in a method that I expose for clients to use. Now if a client decides to use my method, and passes some regex string that contains any escape like Or I'll have to parse the user regex and if there is any backslashes in it, then create a string using two backslashes instead. I've had this come up many times when using Regex in scala. I'm surprised that something like this is sitting on the backlog. |
@som-snytt said: But ultimately, stringly composition is a losing battle. I think there's probably a misunderstanding in Daniel's example? Interpolated text is never interpreted or escaped. There's no danger that the following might interpolate a newline. I didn't count the backslashes. scala> val x = raw"\\\\\\\"
x: String = \\\\\\\
scala> s"${x}n"
res1: String = \\\\\\\n |
Not being able to write That is a matter of opinion or taste. If a default interpolator were supported for ordinary string syntax, then fixing it would not be optional. Recall that the initial judgment was that interpolation wasn't needed because you can write
where the lack of a space between the quote and operator makes its visually parseable. So it's a matter of opinion or taste. I don't think there was a great deal of incentive to make interpolation especially nice. |
For a bug, the spec specifically disallows triple single quote for a char: "The character can be any Unicode character except the single quote delimiter", but accepted it anyway until it was fixed. I don't think appeal to the spec means anything except in so far as the spec converges upon a desired description, and the implementation either follows or leads. |
Fixes scala/bug#6476 SIP-11 specification says ``` interpolatedString ::= alphaid `"` {printableChar \ (`"` | `$`) | escape} `"` ``` My reading of this is that the scanner should support the character sequence `\"`, but pass them as is. The Standard (s) interpolator would take care of the evaluation of `\"` as `"`. This would fix the long standing issue of people trying to write `s"a=\"$a\""` and running into mysterious `';' expected but string literal found.`. This change should be relatively safe since neither `s"\"foo\""` nor `s"foo\"` previously compiled.
I don't see any possibility of changing this in Scala 2, for compatibility reasons. Given the necessity of supporting cross-compilation between Scala 2.13 and 3, it seems to me that the next change opportunity is Scala 3.1. Under the circumstances, I think we should just close the ticket, as this is working-as-designed in Scala 2. For anyone seriously interested in changing this, in whatever Scala version — it isn't enough to just wish — or even to prove! — that a different decision had been made initially. A lot of people wish that. To actually change it now, the full implications, the spec changes, the implementation changes, and the social aspects of getting the change through all need to be worked through. |
Here's my PR - scala/scala#8830. No spec change, and hopefully no change in existing-and-working code. |
@SethTisue we can always make it not compile in a minor version without any serious compatibility implications |
I would be delighted to be forced to admit that I was wrong (about the chances of this moving forward in Scala 2). As I just commented on Eugene's PR,
|
specifically i'm referring to |
Fixes scala/bug#6476 SIP-11 specification says ``` interpolatedString ::= alphaid `"` {printableChar \ (`"` | `$`) | escape} `"` ``` My reading of this is that the scanner should support the character sequence `\"`, but pass them as is. The Standard (s) interpolator would take care of the evaluation of `\"` as `"`. This would fix the long standing issue of people trying to write `s"a=\"$a\""` and running into mysterious `';' expected but string literal found.`. This change should be relatively safe since neither `s"\"foo\""` nor `s"foo\"` previously compiled.
@OlegYch It's surprising for sure, but I think Perhaps one way of looking at it is that s-interpolator emulates standard String literal |
if it's surprising then it should not compile |
Using Scala 2.12 and got this error, this issues explains it nicely. Thanks. |
Fixes scala/bug#6476 SIP-11 specification says ``` interpolatedString ::= alphaid `"` {printableChar \ (`"` | `$`) | escape} `"` ``` My reading of this is that the scanner should support the character sequence `\"`, but pass them as is. The Standard (s) interpolator would take care of the evaluation of `\"` as `"`. This would fix the long standing issue of people trying to write `s"a=\"$a\""` and running into mysterious `';' expected but string literal found.`. This change should be relatively safe since neither `s"\"foo\""` nor `s"foo\"` previously compiled.
Fixes scala/bug#6476 SIP-11 specification says ``` interpolatedString ::= alphaid `"` {printableChar \ (`"` | `$`) | escape} `"` ``` My reading of this is that the scanner should support the character sequence `\"`, but pass them as is. The Standard (s) interpolator would take care of the evaluation of `\"` as `"`. This would fix the long standing issue of people trying to write `s"a=\"$a\""` and running into mysterious `';' expected but string literal found.`. This change should be relatively safe since neither `s"\"foo\""` nor `s"foo\"` previously compiled.
Fixes scala/bug#6476 SIP-11 specification says ``` interpolatedString ::= alphaid `"` {printableChar \ (`"` | `$`) | escape} `"` ``` My reading of this is that the scanner should support the character sequence `\"`, but pass them as is. The Standard (s) interpolator would take care of the evaluation of `\"` as `"`. This would fix the long standing issue of people trying to write `s"a=\"$a\""` and running into mysterious `';' expected but string literal found.`. This change should be relatively safe since neither `s"\"foo\""` nor `s"foo\"` previously compiled.
@SethTisue wrote:
It seems I will be having my own hat for lunch today. |
The text was updated successfully, but these errors were encountered: