SIP: Curried varargs

I think that having to keep track of the state between applyName and applyNext calls will be a pain point for authors.

Quick sanity check: how often would named var-args actually be useful?

1 Like

Actually It would be useful for me quite often. I would prefer in many cases :

(name="test", qty=10)
//instead of 
(name -> "test", qty->10)

IMHO Dynamic will be more painfully for me.I just have suggested less painful case. There are many alternatives.

I think it is not rare case, so dynamic is not best solution

1 Like

Given that overloading a method on just the name of the parameter is not supported, this doesn’t seem like a very promising encoding.

The last SIP meeting ended up being private-only, but we did discuss this SIP. We will discuss again in public on November 27th, but here is nevertheless the gist of the feedback from the SIP committee.

There seem to be two main aspects for the motivation of the proposal: type safety and performance.

For type safety, we’re basically not very convinced that the use cases cannot be implemented using appropriate usage of implicit evidences and/or union types and/or HLists.

For performance, we believe that it should be possible to implement a forced expansion using macros, perhaps even just with inline in Scala 3.

Therefore, the feedback of the committee is that we think you should try and implement this using existing tools in the language.

In spite of the implementation, so does the committee think this feature should be a part of the standard library, or a 3rd party library?

A third-party library. Anything that can be outside of the stdlib should prove its value as a third-party library before it can apply for inclusion in the stdlib.

This is rather disappointing, as it severely curtails the ability of those of us who are in favor of these proposals to rebut these concerns.

While the next meeting will be public, the situation has become asymmetric. We’ll be working against a formed position (whatever you may claim to the contrary, the SIP is made up of humans, and that’s how the human brain works), rather than participating in the formation of that opinion.


A reason why this proposal might not be suitable in a 3rd party library is that it could be a dependency of other core features, including HList, collection initializers, string interpolations.

1 Like

The string interpolators of the stdlib are already intrinsified by the compiler, and HLists (aka tuples in Scala 3) already eliminate all the overhead based on inline and IIRC match types. So both are already as efficient as possible.

In order for tuples to stand in for varargs, there needs to be some form of auto-tupling (ideally, opt-in at the definition site), else you need to write double parentheses at the call site. I brought this use case up on the auto-tupling removal thread (Let's drop auto-tupling). Unfortunately, unless something has changed, the frontrunner solution for opting in was removed as “not pulling its own weight” (, which I feel like might have been due to confusion between present usefulness and potential future usefulness.


I think you might have misunderstood my reply. I was specifically answering the parent comment, and only answering the parent comment. In particular I am not arguing that tuples are a replacement for this SIP. I was arguing that this SIP wouldn’t be used to implement tuples.

Ah, I can totally see how the comment I actually replied to was only claiming that. I simply clicked “reply” on the latest post from you, when I really meant to reply to your earlier statement:

1 Like

It would still be nice to have efficient collection initializers.

One thing that annoys me is that there still doesn’t seem to be a nice way of efficiently constructing a singleton Iterator or Set in Scala. I have to write Iterator(x) or Set(x) and pay for allocating an array and its wrapper every time… or use Set.empty + x for the latter, which is more verbose.


Unfortunately, there’s a difference between “can be implemented” and “can be implemented by someone with extensive background in Shapeless or macros”. One of the really nice things about this proposal is it lowers considerably the difficulty of writing something like show"".

Can I interest you in Iterator.single(x)?

Right, I had missed this one, thanks. But there are plenty of collections that do not have a single constructor. The biggest offenders are Sets and Maps.


Wouldn’t a shapeless solution to the same problem also be much slower to compile?


Yes, and it would be considerably harder to debug.

Just a challenge to put out there: implement Cats’ show interpolator using just implicit evidences, union types, or HLists.

Because I’ve tried doing it, and the restrictions of the string interpolator API mean that you’re pretty much stuck with implicit conversions. In Dotty this means enabling implicit conversions on a project wide basis (or adding it to the import tax), and is very close to a dealbreaker. If there’s a reasonable way to do this, it implies a rather large gap in the current Dotty documentation, because I couldn’t find anything hinting this was possible, short of resorting to implicit conversions.

However, as show"This is $a, and this is $b!" (currently desugars to approximately this: new StringContext("This is", ", and this is", "!").show(WrappedArray(a, b))) would desugar to this:

new StringContext("This is", ", and this is", "!").show.applyBegin.applyNext(a).applyNext(b).applyEnd

The implementation would now be possible without enabling implicit conversions or resorting to a compiler plugin:

class ShowInterpolaterState(parts: List[String], builder: StringBuilder)
  def applyBegin: ShowInterpolaterState = this
  def applyNext[A: Show](a: A): ShowInterpolatorState = 
    parts match
      case p :: rest => new StringInterpolatorState(rest, builder.append(p).append(
      case Nil => builder.append(; this
  def applyEnd: String = 

def (sc: StringContext) json: 
  def show: ShowInterpolaterState = 
    new ShowInterpolatorState(, new StringBuilder)

I just watched part of 2019 November SIP Meeting at @odersky mentioned that there will be a combination explosion problem when overloading applyNext methods. It’s true, just like any complex API that relies on method overloading. On the other hand, applyNext with type classes (like @morgen-peschke’s example) can easily solve the combination explosion problem but is hard to inline.

Fortunately, this proposal gives the library author the freedom to choose either method overloading or type class. Therefore, a sophisticated library author can take the advantage from both approaches and avoid the pitfall of each approach. For example, in html.scala, I use applyNext with type classes to avoid combination explosion problem, and also provide only a few additional overloading inlined applyNext methods to optimize the most frequent use cases.