Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Alternative string interpolator for Strings only#8654

Closed
tabdulradi wants to merge 1 commit into
scala:2.13.xfrom
tabdulradi:2.13.x
Closed

Alternative string interpolator for Strings only#8654
tabdulradi wants to merge 1 commit into
scala:2.13.xfrom
tabdulradi:2.13.x

Conversation

@tabdulradi
Copy link
Copy Markdown
Contributor

This PR provides an alternative string interpolator that accepts strings only

val s = "World"
ss"Hello $s" 

val i = 42
ss"Hello $i" // Won't compile 

This gives a std lib alternative for those who want who to lint away toString.

@scala-jenkins scala-jenkins added this to the 2.13.2 milestone Jan 22, 2020
@plokhotnyuk
Copy link
Copy Markdown
Contributor

plokhotnyuk commented Jan 22, 2020

@tabdulradi will it pass bincompat checks?

Also, Java's builder for strings does not call toString for primitives, and moreover do it efficiently for integer types (without any instantiations)

@tabdulradi
Copy link
Copy Markdown
Contributor Author

@plokhotnyuk I am not concerned about efficiency. This is to avoid toString related bugs. The same reason Cats has show.

@tabdulradi
Copy link
Copy Markdown
Contributor Author

tabdulradi commented Jan 22, 2020

@plokhotnyuk As far as I know bincompat issue affects adding methods to traits not case classes. Anyway, if there is an issue, hopefully MiMa would catch it.

@plokhotnyuk
Copy link
Copy Markdown
Contributor

plokhotnyuk commented Jan 22, 2020

@tabdulradi Which toString bugs do you mean? Could you please share links here?

@dwijnand
Copy link
Copy Markdown
Member

dwijnand commented Jan 22, 2020

@tabdulradi In the standard library we enforce forwards binary compatibility in addition to backwards (this is for historic reasons, and we are hoping to be able to drop this restriction in a future feature release of Scala 3, ideally the first one: Scala 3.1). As such, we can't introduce an ss method on StringContext...

@tabdulradi
Copy link
Copy Markdown
Contributor Author

@plokhotnyuk Sorry I wasn't clear. I didn't mean a bug in toString itself.
I meant that relying on toString could introduce bugs in your code because there is a default implementation for all objects. For example let's say we decided to change snippet above to introduce a wrapper

case class Name(value: String)
val name = Name("World")
println(s"Hello $world")

The code still compiled, but we are printing the wrong thing. If we had used ss here the compiler would have caught the bug. Cats partially solves the problem using Show. But because there is never one canonical String representation of a case class, I prefer for non logging/debugging use cases to avoid both toString and Show.

@tabdulradi
Copy link
Copy Markdown
Contributor Author

@dwijnand Thanks for your reply. I'll close the PR for now and set a reminder :)

@tabdulradi tabdulradi closed this Jan 22, 2020
@tabdulradi
Copy link
Copy Markdown
Contributor Author

tabdulradi commented Jan 22, 2020

@dwijnand wait, how about doing it via extension methods instead? Would this be Ok in the std lib?

implicit class StrictStringnterpolator(val sc: StringContext) extends AnyVal {
  def ss(args: String*): String = sc.s(args: _*)
}

@dwijnand
Copy link
Copy Markdown
Member

I'm not sure. Generally introducing classes is just as forwards incompatible. However, you can sometimes get away with it for things like annotations and compile-time only constructs. Value classes, I'm not sure about, because they kind of are compile-time only... until they box. Here it's absolutely intended to be just a method enrichment, but is there no (real) risk for them boxing? I say "real" because I'm clearly going to discount a user purposely doing something like putting StrictStringnterpolator instances in a Seq.

@som-snytt
Copy link
Copy Markdown
Contributor

You get an extension method. Sample trickiness.

Also source compatibility.

Another possibility is scalafix lint for args to s"".

I like the name, though. I could also go with S"".

@julienrf
Copy link
Copy Markdown
Contributor

For this kind of additions, I would suggest first to experiment with it as a separate library before considering its inclusion in the standard library.
For the record, Wartremover already forbids invisible toString conversions.

@dwijnand
Copy link
Copy Markdown
Member

Good point. It's best to include this once it's proven itself already "in the field".

@som-snytt
Copy link
Copy Markdown
Contributor

Sorry it took 4 years, but the linked PR contributes -Wtostring-interpolated to warn when the standard interpolators (which are macros) use toString.

@SethTisue SethTisue removed this from the 2.14.0-M1 milestone Aug 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants