7

Literals in Scala allow to define identifier as this answer describes. Is there a way though to escape a backtick ` within a literal? To do something like:

 val `hello `world` = "hello world"

Update:
One of the use case for this is to use the refined library for some refined types that matches a regex containing a backtick, for instance:

  import eu.timepit.refined._
  import eu.timepit.refined.api.Refined

  type MatchesRegexWithBacktick = String Refined MatchesRegex[W.`(a|`)`.T]
Valy Dia
  • 2,781
  • 2
  • 12
  • 32
  • 1
    Why can't you use any different symbol, for example apostrophe ``val `hello 'world` = "hello world"`` ? – Dmytro Mitin Apr 05 '19 at 19:00
  • The short answer is I am using the [refined](https://github.com/fthomas/refined) library. And I want to defined a certain type that matches a regex and the regex contains backtick... `String Refined MatchesRegex[W.someRegexWithBackTick.T]` (I had to remove the backtick around someRegexWithBackTick as it was breaking the formatting) – Valy Dia Apr 05 '19 at 19:21
  • 1
    The long answer is [there](https://stackoverflow.com/q/55560634/5826349) @DmytroMitin – Valy Dia Apr 07 '19 at 15:32

1 Answers1

7

It can't be done with the Scala compiler as-is, but maybe it would be possible with a compiler plugin that changed the way identifiers were parsed (perhaps if the back-tick's function was somehow replaced with some obscure unicode character).

In the Scala SLS 1.1, there is the lexical syntax for identifiers:

op       ::=  opchar {opchar}
varid    ::=  lower idrest
boundvarid ::=  varid
             | ‘`’ varid ‘`’
plainid  ::=  upper idrest
           |  varid
           |  op
id       ::=  plainid
           |  ‘`’ { charNoBackQuoteOrNewline | UnicodeEscape | charEscapeSeq } ‘`’
idrest   ::=  {letter | digit} [‘_’ op]

The problem is, the only rule that allows any character other than letters, digits, or _ is the one that requires the identifier be quoted with back-ticks:

‘`’ { charNoBackQuoteOrNewline | UnicodeEscape | charEscapeSeq } ‘`’

However, it explicitly doesn't allow back-ticks with charNoBackQuoteOrNewline, and in case you think you can work around it with UnicodeEscape, that doesn't work either:

scala> val `hello \u0060world` = "hello world"
<console>:1: error: unclosed quoted identifier
val `hello \u0060world` = "hello world"
                      ^
Michael Zajac
  • 55,144
  • 7
  • 113
  • 138