Basically I have a slew of optionals coming in as JSON, because as we all know even the most strict schema has edge case missing values. When trying to turn Option[A] to string with the standard interpolator it looks like:

None,Some("us"),None,Some(14)  

So here's a better way that uses an interpolator for Option[A] which yields code that looks like:

val city = None  
val country = Some("us")  
val language = None  
val decibels = Some(14)

o"$city,$country,$language,$decibels"  

produces:

,us,,14

And here's the magic, mostly stolen from the Scala StringContext source code:

implicit class OptionStringInterpolator(val sc: StringContext) extends AnyVal {  
    import sc.parts

    def o(args: Any*) = optionInterpolator(StringContext.treatEscapes, args)

    private def optionInterpolator(process: String => String, args: Seq[Any]): String = {
      checkLengths(args)
      val pi = parts.iterator
      val ai = args.iterator
      val builder = new StringBuilder(process(pi.next()))
      while (ai.hasNext) {
        val resolved = ai.next() match {
          case Some(s) => s
          case None => ""
          case o => o
        }
        builder append resolved
        builder append process(pi.next())
      }
      builder.toString()
    }

    def checkLengths(args: Seq[Any]): Unit =
      if (parts.length != args.length + 1)
        throw new IllegalArgumentException("wrong number of arguments ("+ args.length 
          +") for interpolated string with "+ parts.length +" parts")
  }