Macros vs string interp

304 views
Skip to first unread message

Ken Scambler

unread,
May 7, 2012, 11:09:47 AM5/7/12
to scala-debate
I used to be sceptical of macros in Scala, and pine for string interpolation.  However, the more I read and experiment with macros, the more useless string interpolation looks.  Macros are a perfect fit for the language: simple, elegant, powerful, and orthogonal.  String interpolation appears to fail on these counts.

SIP-11 goes further than a simple s".." syntax to avoid backwards-compat problems, and adds a whole new concept to the language: a "string prefix" concept, which can be extended ad hoc by users.  Originally this had many good use-cases beyond simple interpolation -- statically checked XML, JSON, and quasiquoting for macros. 

The thing is, the discovery of reify() makes all of these advanced use cases completely redundant.  In his Scala days keynote, Martin notes that the scala"..." literal string wasn't very interesting any more, because of macros -- doesn't the same apply to the other examples?  Why have a feature that gives you xml"$foo" when you can already do xml("$foo") or "$foo".xml with macros?  It's a completely unnecessary design choice to foist on a programmer, especially when orthogonality and minimalism are such important principles for the language.

If we only take simple interpolation, a small and unnecessary notational convenience is all of a sudden trying to pay for a whole new concept and syntax pattern.  It does save keystrokes though...

"Hello "+username"
s"Hello $username"

... sometimes.  And even this can be eliminated with macros (if I'm understanding them correctly). Consider:

"Hello $username".interp
"<html><body><h1>$title</h1></body></html>".interp.xml 

Am I missing something?  String interpolation looks complex, non-orthogonal, un-Scalalike and doesn't pay it's bills.





Bart Schuller

unread,
May 7, 2012, 12:23:44 PM5/7/12
to scala-...@googlegroups.com
Hi,

I've just been playing with the combination of the two, which is more powerful than interpolation alone.

What SIP-11 offers is a standard framework for string interpolation. It claims the $foo and ${expr} syntax and gives it a standardized meaning. If we went with only macros then everyone would invent their own interpolation syntax. Sometimes that's necessary, for instance, the dollar sign is used in mongodb queries and in lots of JavaScript, two potential candidates for interpolation treatment.

From an implementation standpoint, the killer is the "${arbitrary("expression here")}" support. The Scala parser knows what that means, a macro solution wouldn't even get a chance to run. I'm also not so sure that the current macros would be able to take arbitrary expressions as a String and parse and compile them.

Regards,

Bart.

Eugene Burmako

unread,
May 7, 2012, 12:29:03 PM5/7/12
to Ken Scambler, scala-debate
We just discussed this with Martin, and here's the summary:

1) s("hello $world!") looks much more heavyweight than s"hello $world!". "hello $world!".s might be okay though.

2) There's the difficulty with IDEs. In current string interpolation scheme, the desugaring is simple enough for an IDE to provide hyperlinking and auto-completion inside interpolated strings. With macros that'd be tough.

3) Interpolated strings don't process slashes as escapes (except for unicode escapes).

So, all in all, language-integrated string interpolation has a slight edge over macros in terms of usability.

Eugene Burmako

unread,
May 7, 2012, 12:30:17 PM5/7/12
to Ken Scambler, scala-debate
Also reify doesn't cover all use cases that are supported by scala"...". For one, it doesn't work with dynamically typed trees.

Eugene Burmako

unread,
May 7, 2012, 12:31:35 PM5/7/12
to Bart Schuller, scala-...@googlegroups.com
Sure macros can do whatever they wish, including parsing text into ASTs. However the point about unification of splicing syntax for the sake of IDE support still stands.

Ittay Dror

unread,
May 7, 2012, 3:39:31 PM5/7/12
to Eugene Burmako, Bart Schuller, scala-...@googlegroups.com



Eugene Burmako wrote:

Sure macros can do whatever they wish, including parsing text into ASTs. However the point about unification of splicing syntax for the sake of IDE support still stands.

I think bart meaning was that "some string"expr"other string" is illegal in scala. but if the parser is aware of string interpolation, then "${some("expr")}" is parsed so the inner quotes are taken to part of the ${} expression.

Ken Scambler

unread,
May 7, 2012, 6:48:48 PM5/7/12
to Bart Schuller, scala-...@googlegroups.com

On 8 May 2012 02:23, Bart Schuller <bart.s...@gmail.com> wrote:

What SIP-11 offers is a standard framework for string interpolation. It claims the $foo and ${expr} syntax and gives it a standardized meaning. If we went with only macros then everyone would invent their own interpolation syntax.

In the imaginary scheme in my head, there would be a "...".s macro in the standard library providing the interpolation niftiness, so there would be no need for anyone to roll their own.

Grzegorz Kossakowski

unread,
May 7, 2012, 6:58:46 PM5/7/12
to Ken Scambler, Bart Schuller, scala-...@googlegroups.com
I would wait until macros stabilize before putting any references to them from std lib.

--
Grzegorz Kossakowski

Ken Scambler

unread,
May 7, 2012, 7:02:19 PM5/7/12
to Grzegorz Kossakowski, scala-...@googlegroups.com
(forgot to CC to scala-debate)

On 8 May 2012 08:58, Grzegorz Kossakowski <grzegorz.k...@gmail.com> wrote:


I would wait until macros stabilize before putting any references to them from std lib.


Fair point -- then why not wait on string interpolation too, given the high level of overlap between the two?

Ken Scambler

unread,
May 7, 2012, 7:39:39 PM5/7/12
to Eugene Burmako, scala-debate
Thanks for your response Eugene, and thanks for your great work on macros!

I don't think the exotic foo"..." syntax has any advantage sugar-wise over "....".foo.   Fair enough for foo("...") though.

Regarding IDEs:
Firstly, if there's no interpolation feature/macro, then there's no problem to solve; it's a war of choice.  Think of all the pain we're having trying to retract features like XML literals, postfix operators, etc that in hindsight haven't lived up to their promise.

Secondly -- and I apologise for my naivety here -- it seems to me the presentation compiler would have to look at string literals, before the first macro-stage, and it still has all the CompilationUnit and Position information.  So I don't understand why Apply(Literal(Constant(_: String)), Ident("s")) in the AST (or whatever it is) is so much less recognisable than the AST for s"...".   Again though, highly naive, so please shoot me down on this point.

Regarding dynamically-typed trees, again I confess ignorance -- do you mean something like:

val type1: String = something()
val type2: String = somethingElse()
scala" val list: Seq[$type1] = List[$type2]()"

Either way, the motivations for the extensible-string-prefix concept and syntax are reduced to:

- Easier highlighting and click-through on IDEs
- Dynamically typed trees
- Verbatim string for backslashes

This is already a much worse cost/benefit tradeoff than was advertised in the SIP.  What would dynamically typed trees be used for?  Do they deserve a new syntax and language concept?  Is it certain that macros won't catch up in the future and make these redundant too?  At the very least the SIP's wording should reflect this.

I think I remember reading that Martin reversed his opposition to string interpolation on the basis of all these powerful flow-on features, that now seem mostly redundant.  I hope you guys are really confident that the remaining bit and pieces are worth it.

Regards,
Ken

Ken Scambler

unread,
May 8, 2012, 5:58:11 AM5/8/12
to martin odersky, scala-debate
On 8 May 2012 17:21, martin odersky <martin....@epfl.ch> wrote:

I was only saying that the need for scala"..." interpolations is less than before we knew about reify. There is a small but very powerful argument for string interpolation as a primitive: In the interpolated string id"..." escape sequences are left uninterpreted, unlike for normal string literals "...". This means the following works as expected

xml"<result> ${ root \ "title" } </result>"

whereas in 

"<result> ${ root \ "title" } </result>".xml

you'd get a lexical error because of the embedded "\". This, of course, would be unacceptable.

Cheers

 - Martin



Thanks Martin, I see -- also the quotes, which Bart and Ittay pointed out.  What about """<result> ${ root \ "title" } </result>""".xml though?   This is already common practice for "".r regexes.

Eugene Burmako

unread,
May 8, 2012, 6:30:10 AM5/8/12
to scala-debate
I also told about triple quotes to Martin yesterday, and he mentioned
that this still doesn't rule out IDE problems.

What IDE problems do I refer to? We'd like to be able to click through
expr in "hello $expr!".s. Currently that'd be very hard to implement.
Hard, but possible. What is a real killer though is getting
autocompletion to work here: "hello $exp[_]" (where [_] points to the
current location of cursor). That'd require a sophisticated macro <->
IDE protocol, which would be a good, but a time-consuming thing to
implement.

And by dynamically typed trees I mean:

val tree = if (random()) expr1 else expr2
scala"$tree.foo"

You cannot achieve anything similar with reify, yet this scenario
appears pretty frequently in macros.

On May 8, 11:58 am, Ken Scambler <ken.scamb...@gmail.com> wrote:

Ittay Dror

unread,
May 8, 2012, 7:01:55 AM5/8/12
to Eugene Burmako, scala-debate



Eugene Burmako wrote:
I also told about triple quotes to Martin yesterday, and he mentioned
that this still doesn't rule out IDE problems.

What IDE problems do I refer to? We'd like to be able to click through
expr in "hello $expr!".s. Currently that'd be very hard to implement.
Hard, but possible. What is a real killer though is getting
autocompletion to work here: "hello $exp[_]" (where [_] points to the
current location of cursor). That'd require a sophisticated macro <->
IDE protocol, which would be a good, but a time-consuming thing to
implement.

Couldn't the IDE have its own implementation for handling the string interpolation? Instead of introducing another mechanism to the scala language, you'd need a bit (not much) logic duplication in the IDE and macro.

And if macros subvert autocompletion, what will be done with all the cool macros that are going to be implemented now? E.g., If I have a macro to create SQL dsl by not requiring string ids, insted inspecting the selected classes fields, would I have autocompletion for these fields?

Johannes Rudolph

unread,
May 8, 2012, 7:17:35 AM5/8/12
to Eugene Burmako, scala-debate
On Tue, May 8, 2012 at 12:30 PM, Eugene Burmako <eugene....@epfl.ch> wrote:
> I also told about triple quotes to Martin yesterday, and he mentioned
> that this still doesn't rule out IDE problems.
>
> What IDE problems do I refer to? We'd like to be able to click through
> expr in "hello $expr!".s. Currently that'd be very hard to implement.

Why is it? I would expect it to be easy once you get the positions in
the generated trees right. (I know nothing about Scala IDE, however,
I've got it working in the scala-enhanced-strings documentation [1]
with sxr back then without to much pain)

--
Johannes

[1] http://jrudolph.github.com/scala-enhanced-strings/Syntax.scala.html#9483

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Eugene Burmako

unread,
May 8, 2012, 7:48:44 AM5/8/12
to Ittay Dror, scala-debate
But interpolation syntax is meant to be extensible (strings, regexes, xml...). Requiring IDE to reimplement all that logic would be impossible.

As to macros and completion. Everything is okay as long as your macro works on well-typed Scala code. However, if you go for additional magic (e.g. treating parts of your strings as Scala code, treating method names as class declarations or whatever), you're out of luck.

Eugene Burmako

unread,
May 8, 2012, 7:51:19 AM5/8/12
to Johannes Rudolph, scala-debate
Don't quote me on that, since I know close to nothing about the IDE, but apparently there's a problem with associating macro expansions with their original macro applications.

Johannes Rudolph

unread,
May 8, 2012, 7:54:17 AM5/8/12
to Eugene Burmako, scala-debate
On Tue, May 8, 2012 at 1:51 PM, Eugene Burmako <eugene....@epfl.ch> wrote:
> Don't quote me on that, since I know close to nothing about the IDE, but
> apparently there's a problem with associating macro expansions with their
> original macro applications.

That makes more sense, because after the macro has run the macro
application should have disappeared, right? That doesn't have to mean
that IDE support for generated trees has to be hard as well IMO.

--
Johannes

Bart Schuller

unread,
May 8, 2012, 7:54:41 AM5/8/12
to scala-...@googlegroups.com

On Tuesday, May 8, 2012 11:58:11 AM UTC+2, Ken Scambler wrote:

Thanks Martin, I see -- also the quotes, which Bart and Ittay pointed out.  What about """<result> ${ root \ "title" } </result>""".xml though?   This is already common practice for "".r regexes.


I like the fact that in the current XML literals, the full Scala language is available when I switch to expression context, including any kind of quoting I like. It's not uncommon for an XML literal to span tens of lines and perhaps switch between expression and XML context 2 or 3 times.

I'd hate it if only the outer quotes could be the triple ones and having to resort to quoting everywhere else.

For a parser it makes a big difference to have the interpolation indicator at the front instead of at the back. Only then can it take into account the switch to Scala expression context.

My example (not using macros yet) currently parses the following:


xml"""<foo a="overridden" $attributes b="literal wins">
blie <b attr=$attributeValue/> bla $nodes
${
val inner = xml"""<bar/>"""
xml"""<baz>$inner</baz>"""
}
</foo>"""


I don't see how that is ever going to work with the interpolation indicator at the end. It certainly doesn't parse as a normal string when I remove just the first 3 letters.

Eugene Burmako

unread,
May 8, 2012, 8:01:42 AM5/8/12
to Johannes Rudolph, scala-debate, Iulian Dragoș
We'd better ask Iulian about that.

André van Delft

unread,
May 8, 2012, 7:33:23 PM5/8/12
to scala-debate
I don't like s"hello $world!" because the s is too close to the double
quote character; it just does not look right, in my eyes. But I would
like to have the s as a starter.

For this reason I would propose the syntax s."hello $world!" .

In general, I think

a.b

could be syntactic sugar for

a(b)

when b is a literal (string, character, symbol, number, boolean) or
null.

Any objections?

On 7 mei, 18:29, Eugene Burmako <eugene.burm...@epfl.ch> wrote:
> We just discussed this with Martin, and here's the summary:
>
> 1) s("hello $world!") looks much more heavyweight than s"hello $world!".
> "hello $world!".s might be okay though.
>
> 2) There's the difficulty with IDEs. In current string interpolation
> scheme, the desugaring is simple enough for an IDE to provide hyperlinking
> and auto-completion inside interpolated strings. With macros that'd be
> tough.
>
> 3) Interpolated strings don't process slashes as escapes (except for
> unicode escapes).
>
> So, all in all, language-integrated string interpolation has a slight edge
> over macros in terms of usability.
>

Daniel Sobral

unread,
May 8, 2012, 8:32:48 PM5/8/12
to André van Delft, scala-debate
Well, I like the current scheme and I dislike the proposed scheme.
--
Daniel C. Sobral

I travel to the future all the time.

André van Delft

unread,
May 9, 2012, 2:53:21 AM5/9/12
to scala-debate
Something I really dislike about s"hello $world!":

This syntax glues two elements (s and a string) without the option of
adding whitespace. I think this would be the only place in Scala where
that would happen.

Besides, my proposal builds on the precedent

a.this

Ken Scambler

unread,
May 9, 2012, 4:52:32 AM5/9/12
to André van Delft, scala-debate

In an overwhelming number of language, including Scala, a.b means "b belongs to a", or "b is subordinate to a".  A.this follows this convention.  S."foo" does not, and actively subverts the user's expectations. 

This isn't an improvement on the SIP.

Ittay Dror

unread,
May 9, 2012, 6:09:46 AM5/9/12
to Ken Scambler, André van Delft, scala-debate

I fully agree,

But since this is the debate mailing list, and I find the s"" notation aesthetically unappealing, I wanted to suggest something else:

${"hello $world} or, if curly braces aren't good, then $"hello $world"

the use of $  is just reusing the same symbol used inside the string interpolation. the use of {} implies a scope of operating on the strings. maybe in the future stuff like ${"foo", "$bar"} will be possible or:

${

   val something = readName()

   "hello $something"

Eugene Burmako

unread,
May 9, 2012, 6:11:44 AM5/9/12
to Ittay Dror, Ken Scambler, André van Delft, scala-debate
What do we do with other interpolators?

Ittay Dror

unread,
May 9, 2012, 6:55:10 AM5/9/12
to Eugene Burmako, Ken Scambler, André van Delft, scala-debate

otherinterpolator{"a string"}

(where the compiler knows that therinterpolator is an interpolator and so doesn't treat it as a normal value)

Daniel Sobral

unread,
May 9, 2012, 8:32:26 AM5/9/12
to André van Delft, scala-debate
On Wed, May 9, 2012 at 3:53 AM, André van Delft
<andre.v...@gmail.com> wrote:
> Something I really dislike about s"hello $world!":
>
> This syntax glues two elements (s and a string) without the option of
> adding whitespace. I think this would be the only place in Scala where
> that would happen.

Originally it allowed spaces, but it turns out the chance for typos is
much greater that way.

Alex Cruise

unread,
May 9, 2012, 1:10:57 PM5/9/12
to André van Delft, scala-debate
On Tue, May 8, 2012 at 11:53 PM, André van Delft <andre.v...@gmail.com> wrote:
Something I really dislike about s"hello $world!":

This syntax glues two elements (s and a string) without the option of
adding whitespace. I think this would be the only place in Scala where
that would happen.

On the face of it, I'm ambivalent about the aesthetics of the s"$foo" syntax.  But I wish this juxtaposition "operator" could be generalized somehow, in keeping with the Scala Way. :)

-0xe1a

Daniel Sobral

unread,
May 9, 2012, 6:14:24 PM5/9/12
to Alex Cruise, André van Delft, scala-debate
But it is!

Nikita Volkov

unread,
May 10, 2012, 6:28:00 AM5/10/12
to scala-...@googlegroups.com
I fully support all the arguments against string interpolation in prefixed form, which introduces a whole new concept in the language, the concept that mostly doubles the already existing functionality. IMO that's exactly a case of overcomplicating a language without a real reason to.

AFAIK the only real new feature the string interpolation of any kind brings to the table is the ability to refer to the members of the scope from string. That's it. All the other functionality is easily achievable with already existing language features (`"<number>$number</number>".xml` is a good example). 

So in my opinion all the debate here is caused by us missing the obvious fact: all these issues are just consequences of disinclination to drop the backwards compatibility by making the standard unprefixed strings interpolated. In other words if decision was made to drop the backward compatibility in terms of how the `$` character should be treated in strings there would be no need for any prefixes and thus there would be none of the issues described in this thread. 

Besides all, string interpolation is implemented in a number of languages (Groovy, Kotlin, Python, Ruby, CoffeeScript, PHP, Perl), it has a very similar form in all of them and none of them have prefixes nor custom interpolators. So Scala will be swimming against the current here by breaking the well-established conventions.

Summarizing that I strongly vote for making the standard strings interpolated and against prefixes and custom string interpolation of any kind.

Trond Olsen

unread,
May 10, 2012, 8:13:59 AM5/10/12
to scala-...@googlegroups.com
I'm not a big fan of SIP-18 but this is a good candiate for it.

Ken Scambler

unread,
May 10, 2012, 9:21:08 AM5/10/12
to Eugene Burmako, Ittay Dror, André van Delft, scala-debate
On 9 May 2012 20:11, Eugene Burmako <eugene....@epfl.ch> wrote:
What do we do with other interpolators?


Macros and triple-quotes have already paid for the rest, apart from the dynamically typed trees. 

Daniel Sobral

unread,
May 10, 2012, 11:27:01 AM5/10/12
to Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 7:28 AM, Nikita Volkov
<nikita....@gmail.com> wrote:
> I fully support all the arguments against string interpolation in prefixed
> form, which introduces a whole new concept in the language, the concept that
> mostly doubles the already existing functionality. IMO that's exactly a case
> of overcomplicating a language without a real reason to.

It adds one feature, but it hardly can be said to "double" anything.
id"xxx" is rewritten just like for-comprehensions are rewritten. The
upside is that it opens up the possibility of dropping XML literal
support completely, since it can do both interpolation and pattern
matching.

>
> AFAIK the only real new feature the string interpolation of any kind brings
> to the table is the ability to refer to the members of the scope from
> string. That's it. All the other functionality is easily achievable with
> already existing language features (`"<number>$number</number>".xml` is a
> good example).

I'm not sure what you mean by easily achievable, but let's consider
one example that uses interpolations capabilities fully:

re"\b${ keywords map re"\Q${_}\E" mkString "|"}\b"

How would that be translated otherwise?

> Besides all, string interpolation is implemented in a number of languages
> (Groovy, Kotlin, Python, Ruby, CoffeeScript, PHP, Perl), it has a very
> similar form in all of them and none of them have prefixes nor custom
> interpolators. So Scala will be swimming against the current here by
> breaking the well-established conventions.

Well, it just so happens that interpolation *DOESN'T* have a common
form. Some languages use $, other use #, others use %, etc -- I looked
into it during the SIP discussions (which, by the way, is when people
should have spoken up -- and many did), and it turns there really
isn't any standard form.

On the other hand, none of these languages can use interpolation to
extend literals. That is a Scala differential -- that things do not
"belong" to the language, but are available for use by libraries, and
that is one thing the interpolation syntax enables. Before this
proposal was brought up -- and it is this flexibility that made the
proposal particularly popular -- the idea was to prefix quotes with a
backslash. Having interpolation on normal strings, of course, is out
of question.

> Summarizing that I strongly vote for making the standard strings
> interpolated and against prefixes and custom string interpolation of any
> kind.

I strongly vote against that. As I said (even before reading this
paragraph), that is out of question. String interpolation by itself
doesn't add enough benefit to break source code compatibility with
almost everything every written in Scala.

Daniel Sobral

unread,
May 10, 2012, 11:36:21 AM5/10/12
to Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 7:28 AM, Nikita Volkov
<nikita....@gmail.com> wrote:
>
> Besides all, string interpolation is implemented in a number of languages
> (Groovy, Kotlin, Python, Ruby, CoffeeScript, PHP, Perl), it has a very
> similar form in all of them and none of them have prefixes nor custom
> interpolators. So Scala will be swimming against the current here by
> breaking the well-established conventions.

Ah, yes, one thing I forgot. That is not true: Perl has prefixed strings.

Mirko Stocker

unread,
May 10, 2012, 11:52:53 AM5/10/12
to Daniel Sobral, Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 5:36 PM, Daniel Sobral <dcso...@gmail.com> wrote:
> Ah, yes, one thing I forgot. That is not true: Perl has prefixed strings.

And by the way, C++11 also has user-defined literals:

http://www2.research.att.com/~bs/C++0xFAQ.html#UD-literals

Cheers,

Mirko

--
Mirko Stocker | m...@misto.ch
Work: http://ifs.hsr.ch | http://infoq.com
Personal: http://misto.ch | http://twitter.com/m_st

Daniel Sobral

unread,
May 10, 2012, 12:20:52 PM5/10/12
to Mirko Stocker, Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 1:15 PM, Daniel Sobral <dcso...@gmail.com> wrote:
> On Thu, May 10, 2012 at 12:52 PM, Mirko Stocker <m...@misto.ch> wrote:
>> On Thu, May 10, 2012 at 5:36 PM, Daniel Sobral <dcso...@gmail.com> wrote:
>>> Ah, yes, one thing I forgot. That is not true: Perl has prefixed strings.
>>
>> And by the way, C++11 also has user-defined literals:
>>
>>  http://www2.research.att.com/~bs/C++0xFAQ.html#UD-literals
>
> But postfixed, not prefixed. I find the idea interesting, particularly
> given how it applies over numeric literals. Making NNNkm turn into
> IntContext(NNN).km would come in handy indeed! The problem is that it
> would be harder on the parser, but I think it is worth serious
> consideration.

Nevermind. I forgot that postfix syntax would conflict with existing
legal Scala code. In fact, I saw this a few times already:

val pat = "xyzzy"r


>
>>
>> Cheers,
>>
>> Mirko
>>
>> --
>> Mirko Stocker | m...@misto.ch
>> Work: http://ifs.hsr.ch | http://infoq.com
>> Personal: http://misto.ch | http://twitter.com/m_st
>
>
>

Erik Osheim

unread,
May 10, 2012, 12:46:54 PM5/10/12
to Daniel Sobral, Mirko Stocker, Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 01:15:41PM -0300, Daniel Sobral wrote:
> But postfixed, not prefixed. I find the idea interesting, particularly
> given how it applies over numeric literals. Making NNNkm turn into
> IntContext(NNN).km would come in handy indeed! The problem is that it
> would be harder on the parser, but I think it is worth serious
> consideration.

The thing I'm hoping for are ways of using these kinds of features to
simulate new literal syntax, i.e. to enable the following
transformations at compile-time:

b"200" -> 200.toByte
r"13/17" -> Rational(13, 17)
n"2358329532523552352" -> new java.math.BigInteger(1, bytes)

Most of these transformations are currently possible at runtime using
StringContext and implicits, but I would rather process the strings at
compile-time than run-time. My sense is that this kind of thing isn't
supported yet but I'd love to be proven wrong.

Of course, in some cases it would be nicer to be able to use a literal
syntax like 200b or 23325235325253n but that seems like a whole
different can of worms.

-- Erik

Daniel Sobral

unread,
May 10, 2012, 12:15:41 PM5/10/12
to Mirko Stocker, Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 12:52 PM, Mirko Stocker <m...@misto.ch> wrote:
> On Thu, May 10, 2012 at 5:36 PM, Daniel Sobral <dcso...@gmail.com> wrote:
>> Ah, yes, one thing I forgot. That is not true: Perl has prefixed strings.
>
> And by the way, C++11 also has user-defined literals:
>
>  http://www2.research.att.com/~bs/C++0xFAQ.html#UD-literals

But postfixed, not prefixed. I find the idea interesting, particularly
given how it applies over numeric literals. Making NNNkm turn into
IntContext(NNN).km would come in handy indeed! The problem is that it
would be harder on the parser, but I think it is worth serious
consideration.

>
> Cheers,
>
> Mirko
>
> --
> Mirko Stocker | m...@misto.ch
> Work: http://ifs.hsr.ch | http://infoq.com
> Personal: http://misto.ch | http://twitter.com/m_st



Stefan Zeiger

unread,
May 10, 2012, 1:29:52 PM5/10/12
to scala-...@googlegroups.com
On 2012-05-10 18:46, Erik Osheim wrote:
> The thing I'm hoping for are ways of using these kinds of features to
> simulate new literal syntax, i.e. to enable the following
> transformations at compile-time:
>
> b"200" -> 200.toByte
> r"13/17" -> Rational(13, 17)
> n"2358329532523552352" -> new java.math.BigInteger(1, bytes)
>
> Most of these transformations are currently possible at runtime using
> StringContext and implicits, but I would rather process the strings at
> compile-time than run-time. My sense is that this kind of thing isn't
> supported yet but I'd love to be proven wrong.

Definition:

class StringConv(val s: StringContext) /*extends AnyVal*/ {
def b(): Byte = macro StringConv.bImpl
}
object StringConv {
def bImpl(c: Context)(): c.Expr[Byte] = {
import c.mirror._
val Apply(_, List(Apply(_, List(Literal(Constant(str:
String)))))) = c.prefix.tree
Expr[Byte](Literal(Constant(str.toByte)))
}
}
implicit def stringContextToStringConv(s: StringContext) = new
StringConv(s)

Usage:

class MacrosTest {
...
val myByte = b"100"
}

Proof:

public com.novocode.macrostuff.test.MacrosTest();
Code:
0: aload_0
1: invokespecial #66 // Method
java/lang/Object."<init>":()V
4: aload_0
5: bipush 100
7: putfield #36 // Field myByte:B
10: return
}

Macros in value classes do not work at the moment but it doesn't matter.
The macro expansion takes care of removing the implicit conversion anyway.

-sz

Erik Osheim

unread,
May 10, 2012, 1:40:23 PM5/10/12
to Stefan Zeiger, scala-...@googlegroups.com
On Thu, May 10, 2012 at 07:29:52PM +0200, Stefan Zeiger wrote:
> public com.novocode.macrostuff.test.MacrosTest();
> Code:
> 0: aload_0
> 1: invokespecial #66 // Method
> java/lang/Object."<init>":()V
> 4: aload_0
> 5: bipush 100
> 7: putfield #36 // Field myByte:B
> 10: return
> }

Thanks Stefan!

It must be time for me to start working on a 2.10 branch of
Spire--there are so many exciting things coming up!

-- Erik

Simon Ochsenreither

unread,
May 10, 2012, 3:39:36 PM5/10/12
to scala-...@googlegroups.com, Mirko Stocker, Nikita Volkov

But postfixed, not prefixed. I find the idea interesting, particularly
given how it applies over numeric literals. Making NNNkm turn into
IntContext(NNN).km would come in handy indeed! The problem is that it
would be harder on the parser, but I think it is worth serious
consideration.

Yes I agree. I hope there is a way to use the existing possibilities like "foo"id, but I'm not sure it is worthwhile.
Another option would be to make "foo"id equivalent to id"foo" and just say: "First look at implicits for String, then look for implicits for StringContext".

Thinking about that ... it sounds pretty reasonable imho.

Simon Ochsenreither

unread,
May 10, 2012, 3:57:13 PM5/10/12
to scala-...@googlegroups.com, Mirko Stocker, Nikita Volkov
Additionally, I think there should be a way to show the IDE/compiler how things should be syntax highlighted.

Egon Nijns

unread,
May 10, 2012, 4:16:39 PM5/10/12
to Nikita Volkov, scala-...@googlegroups.com

+1 for breaking source compatibility once to be more consistent (also with other languages, which is nice for newcomers)

Op 10 mei 2012 12:28 schreef "Nikita Volkov" <nikita....@gmail.com> het volgende:

Daniel Sobral

unread,
May 10, 2012, 6:01:15 PM5/10/12
to Egon Nijns, Nikita Volkov, scala-...@googlegroups.com
On Thu, May 10, 2012 at 5:16 PM, Egon Nijns <egon....@gmail.com> wrote:
> +1 for breaking source compatibility once to be more consistent (also with
> other languages, which is nice for newcomers)

Scala is consistent with Java. That's where most newcomers come from.
So... will Python and Ruby change their string interpolation to be
compatible between them? If not, why should Scala bother with being
compatible with *one* of them?

Andrés Testi

unread,
May 11, 2012, 9:45:45 AM5/11/12
to scala-...@googlegroups.com, Mirko Stocker, Nikita Volkov
Why not allow prefix on symbols too? For example:

bin'00100010101 // Generates a binary Int
// translated to
SymbolContext('00100010101).bin

This could be extended to other bases:

oct'037 // Octal
hex'A12 // Hexadecimal
dec'132123 // Decimal

- Regards

Andrés Testi

unread,
May 11, 2012, 9:56:12 AM5/11/12
to scala-...@googlegroups.com, Mirko Stocker, Nikita Volkov
Of course, this improvement could deprecate the ugly and inconsistent inheritance from Java to express octals and hexadecimals ("0037", "0xA12", etc.)

- Andrés

Paul Phillips

unread,
May 11, 2012, 10:17:50 AM5/11/12
to Andrés Testi, scala-...@googlegroups.com, Mirko Stocker, Nikita Volkov


On Fri, May 11, 2012 at 6:56 AM, Andrés Testi <andres....@gmail.com> wrote:
Of course, this improvement could deprecate the ugly and inconsistent inheritance from Java to express octals and hexadecimals ("0037", "0xA12", etc.)

Why wait on some of them:

scala> 012
<console>:1: warning: Treating numbers with a leading zero as octal is deprecated.
       012
       ^

0x as a prefix is a lot less ambiguous and a lot more useful.  I doubt that's going anywhere.

Nikita Volkov

unread,
May 11, 2012, 10:52:43 AM5/11/12
to Daniel Sobral, scala-...@googlegroups.com
@Daniel Sobral

I see nothing extraordinary in your example (if I get it correctly):
re"\b${ keywords map re"\Q${_}\E" mkString "|"}\b" 
turns into
"\b${ keywords map "\Q${_}\E" mkString "|"}\b".r  
which as you see is shorter and should perfom much faster, because all it does is composes a string and then turns it into a regex. In your example it first composes a regex for every keyword, then joins them as a string and composes the final regex. IMO it's way too many redundant steps, which in more complex examples would require redundant libraries with all the risks of implementing not the best algorithms, and inevitably involving redundant computing cycles. All that for what benefit? I see none.

I don't agree that string interpolation doesn't have a common form between the other languages. The only difference between them is the choice of the special character (S, #, %, as you mentioned) - yet they all share a core principle that string interpolation behaves just like a primitive template, eye-easy, concise and simple. 

To think about it, the main reason for string interpolation was to make the code like `"I am " + name + "!"` easier to write and read, and I just don't believe that turning strings into a way of writing some other languages inside Scala has anything left to do with that reason. IMO it's an example of straying way too far and losing the original cause.

Also I just don't understand why dropping the backwards compatibility is being put out of question. The language version incrementation suggests its backwards incompatibility, and I think it's much better to do it for the cause of making the language more consistent than having to do the same to correct the questionable design decisions in future.

I'm sorry I wasn't on the list when the main discussions on the SIP took place, but please keep in mind that it's never too late to make a correct decision. I tried to make my arguments as constructive as possible and I hope they didn't offend anyone.

2012/5/10 Daniel Sobral <dcso...@gmail.com>

Daniel Sobral

unread,
May 11, 2012, 4:38:33 PM5/11/12
to Nikita Volkov, scala-...@googlegroups.com
On Fri, May 11, 2012 at 11:52 AM, Nikita Volkov
<nikita....@gmail.com> wrote:
> @Daniel Sobral
>
> I see nothing extraordinary in your example (if I get it correctly):
> re"\b${ keywords map re"\Q${_}\E" mkString "|"}\b"
> turns into
> "\b${ keywords map "\Q${_}\E" mkString "|"}\b".r

No, that would cause an error first on \b, which is an illegal escape
code, and then on \Q, as the string would have ended at that point.

> which as you see is shorter and should perfom much faster, because all it

Much faster and incorrectly -- if it worked --, since it does not
verify the inside regex.

However, I'm not asking you to optimize the code: I choose a simple
example because it's short, easy to discuss and to rewrite, not
because it make sense. If I put in a page of XML literal with nested
elements, it would be more difficult to understand, longer to read and
harder to translate (because of typing alone, if for no other reason).

Stupid code is stupid for a reason: it's simple to reason about. That
you cannot even translate correctly such simple code is a strong
argument against your proposal.

> I don't agree that string interpolation doesn't have a common form between
> the other languages. The only difference between them is the choice of the
> special character (S, #, %, as you mentioned) - yet they all share a core
> principle that string interpolation behaves just like a primitive template,
> eye-easy, concise and simple.

Well, I don't agree that interpolation is a common feature implemented
similarly, nor that Scala is departing in a horrible manner from other
languages.

First, none of the 5 most popular languages on this month's Tiobe
index support variable interpolation, and only PHP among the 5 most
popular from langpop does.

Next, variable interpolation is done in many different manners. It's
not only the character changing -- you have things like escaping % by
doubling it on Java's printf, or a score of different modifiers that
can be used on shell scripting, or even how does one write a
non-interpolating string and what is allowed inside it or not (such as
escape characters).

Using an identifier to change meaning of the string is not uncommon
either. Perl has it prefixed (see below), and now C++ has it
postfixed.

dcs@shadowfax:~$ perl -e 'print qr"a b c", "\n", qw"a b c", "\n"';
(?-xism:a b c)
abc

> To think about it, the main reason for string interpolation was to make the
> code like `"I am " + name + "!"` easier to write and read, and I just don't
> believe that turning strings into a way of writing some other languages
> inside Scala has anything left to do with that reason. IMO it's an example
> of straying way too far and losing the original cause.

I disagree. I bet a hundred dollars (I mean it) that the most common
use case for interpolation is to write some sort of computer-language
output: CSV, XML, HTML, SQL, etc. IntelliJ even offers syntax
highlighting for external languages on String, so common this is. And
Scala's interpolation means one will be able to do things like
validating syntax and protecting against SQL injection on a SQL string
template, for example.

> Also I just don't understand why dropping the backwards compatibility is
> being put out of question. The language version incrementation suggests its
> backwards incompatibility, and I think it's much better to do it for the
> cause of making the language more consistent than having to do the same to
> correct the questionable design decisions in future.

It's not "just" dropping compatibility. It's a drop in compatibility
that will require change in huge amounts of code. And FOR NOTHING.
String interpolation doesn't gain us ANYTHING: it just saves some
typing and makes strings prettier -- people can both avoid using "+"
and "format", and then the benefits from both options. Only those
benefits are purely aesthetic.

It does make strings easier to read, which makes it easier to catch
errors in the String -- but Scala interpolation, as proposed, let's
the *compiler* catch those errors for a large amount of those strings
(beyond letting people do it).

And even if we were to accept such break in existing code, there's the
question of what do we do when we *don't* interpolate strings.
Languages designed with interpolation upfront usually have an
alternative, the most popular being (because of shell) using
single-quotes instead of double-quotes. Unfortunately, that option is
not available: it's already used for characters *and* for symbols. If
we allowed it, either we would break the C-inherited (40 years)
tradition of using single-quotes for characters, or we would have 'a'
and 'aa' generate different types! If we do not allow it, we still
have to propose some way to do so, or be left with the extremely
inconvenience of ALWAYS having to escape $ anywhere you write it!

> I'm sorry I wasn't on the list when the main discussions on the SIP took
> place, but please keep in mind that it's never too late to make a correct
> decision. I tried to make my arguments as constructive as possible and I
> hope they didn't offend anyone.

The discussions are public if you join the google group. And your
proposal is somewhat lacking: you did not specify it precisely, did
not say what to do to avoid interpolation, did not address what to do
about existing code, did not discuss the strengths and weaknesses of
the proposal and, to be honest, hardly gave any arguments to support
it. What I understood from your e-mail was this:

* Scala's prefixed strings are ugly. (perhaps, but I think it's just
lack of familiarity)
* No one does it. (not true)
* Everyone does string interpolation. (not true)
* Everyone does string interpolation the same way. (not true)
* It makes the language more complex. (true, but only if/until Scala
rips out XML support using it)
* Therefore Scala should do it too.

That's borderline trolling, imho.

Simon Ochsenreither

unread,
May 11, 2012, 7:57:51 PM5/11/12
to scala-...@googlegroups.com
Octals are already depreciated.

Stefan Zeiger

unread,
May 12, 2012, 9:57:31 AM5/12/12
to scala-...@googlegroups.com
On 2012-05-11 16:52, Nikita Volkov wrote:

To think about it, the main reason for string interpolation was to make the code like `"I am " + name + "!"` easier to write and read, and I just don't believe that turning strings into a way of writing some other languages inside Scala has anything left to do with that reason. IMO it's an example of straying way too far and losing the original cause.

There are very interesting uses for string interpolation which are not quite the standard example but still very close to it. Consider the classical security hole in gazillions of PHP applications:

    s"select id from users where name = '$name' and password = '$password'"

It's just a small step towards a completely safe version which uses bind variables:

    // actual code you could run in SLICK master
    sql"select id from users where name = $name and password = $password"

I'm sure we'll see many other uses cases in the future now that Scala is offering a way of implementing them. (For one use case I have in mind, I could use an even more generic mechanism that would allow splicing of types instead of terms into string :-)

-sz
Reply all
Reply to author
Forward
0 new messages