Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: "number" interpolation

Scala has string interpolation like raw"\n" for raw strings.

Does it have anything like number interpolation e.g. 1px for one pixel? A nice syntax for numeric units would both make code more readable and make it easier to write safer code.

Like strings, numbers have a nice literal syntax and are fundamental.

prefix notation px(1) is not how people write units:

case class px(n: Int)

And I don't think a postfix notation via implicit conversion can work:

case class Pixels(n: Int) {
 def px() = Pixels(n)
 def +(p: Pixels) = p match {case Pixels(m) => Pixels(n+m)}
}
implicit def Int2Pixels(n: Int) = Pixels(n)
  1. it needs a dot or space or parens (i.e. not (1 px) or (1)px or 1.px, which is not how humans write units).

  2. it won't check types i.e. we want to explicitly cast between these numeric type-alias things and numbers themselves (i.e. 1.px + 2 and 1 + 2.px and def inc(p: Pixels) = p + Pixels(1) with inc(0) all don't fail, because of the implicit cast, when they should).

like image 789
sam boosalis Avatar asked Feb 22 '26 09:02

sam boosalis


1 Answers

You can define own string interpolation (more details here):

implicit class UnitHelper(val sc : StringContext) extends AnyVal {
  def u(args: Any*): Pixels = {
    val pxR = """(\d.*)\s*px""".r   
    sc.parts.mkString match {
      case pxR(px) => Pixels(px.toInt)
      case _ => throw new IllegalArgumentException
    }
  }
} 

Usage example:

val x = u"10px" + u"20px" // x = Pixels(30)

Pros:

  • easy to add interpolation for any units: em, px, pt, cm, in

Cons:

  • it is not type safe because string interpolation is runtime feature.
like image 141
Yuriy Avatar answered Feb 25 '26 12:02

Yuriy