Proposal
I propose to have a shorthand string interpolation, by using the sharp #
character.
The syntax will change as follows (feel free to correct if I expressed it wrong):
processedStringLiteral
::= alphaid ‘"’ {[‘\’] processedStringPart | ‘\\’ | ‘\"’} ‘"’
| alphaid ‘"""’ {[‘"’] [‘"’] char \ (‘"’ | ‘$’) | escape} {‘"’} ‘"""’
| alphaid ‘#’ {printableChar} (whiteSpace | nl | (‘,’ ‘ ’)) ;
- The new grammar (supposedly) allows any consecutive non-whitespace/newline/comma-followed-by-space characters to be part of the interpolation.
- No arguments are supported for this sharp interpolation (we can allow them, but I don’t think its a good move).
- The mechanism invokes exactly the same
StringContext
class that regular string interpolation uses.
Here are some examples of what will be possible:
val binVal = b#101001100101
val hexVal = h#0304903FFAA
val bigVal = big#345,463,489,989,893,859,438,943,643
val dateVal = date#22.02.2022
val date2Val = date#22/02/2022
val ipVal = ip#192.168.0.1
val phoneVal = phone#+1-800-555-5555
val phoneList = List(phone#+1-800-555-5555, phone#+1-800-777-7777)
As you can see, the fact that we associate the sharp #
token with the word “number” enables us to express values more naturally to match the spoken (english) language.
Remember that this is in term positions and not types, so #
cannot be confused with path dependent type ascription.
Applying methods on sharp interpolation
The sharp interpolation accepts all characters until whitespace, newline, or comma characters.
This is to allow flexible separators like in phone numbers and dates.
Consequently, unlike regular string interpolation, in order to apply methods we must add space or new line:
ip#192.168.1.0.connect //error
ip#192.168.1.0 .connect //OK
ip#192.168.1.0
.connect //OK
h#1234+h#abcd //error
h#1234 + h#abcd //OK
Related Issues
Discussion
- Should we also use
;
as end-of-string for the sharp interpolator? Currently the proposal allows comma (with no following space) to be a separator. Is this OK or confusing? - Theoretically we can allow for interpolation arguments. Should we? I think if someone wants arguments then they should just use the regular string interpolation.
- I think that the experimental Numeric Literals (FromDigits) language feature in Scala 3 is not good enough, and this proposal does a better job of enabling the user full control over the acceptable way of expressing numeric literals. Should they both exist or should we remove
FromDigits
? - Should we add interpolators like
big#345463489989893859438943643
to the standard library? - Anything else?