Better number literals

Lots of good suggestions here.

I am completely in favor of allowing _ in numeric literals. If someone wants to open an issue laying down the desired syntax, we can act on this quickly.

Regarding string interpolators: I am not sure why they need to be whitebox macros. The type of a string interpolator such as f could well be (Any*)String. It is then the job of the interpolator to refuse any argument that does not conform to its format string. So f is still a macro, but not a whitebox macro.

Concerning BigDecimal literals themselves, I think only extensible solutions are worth considering. Don’t stop at BigDecimals. Can we have a scheme where we can have arbitrary user-defined types that allow some form of numeric literal? One way to do it is to say that a numeric literal N is of type T if

  • T is the expected type at the point where the literal is defined
  • There is an instance of typeclass Literally[T] defined for T where
trait Literally[A] {
  def fromString(s: String): A
}

So, the following would both work, assuming BigDecimal and BigInt define Literally instances that
convert strings of digits to the type itself.

val x: BigDecimal = 1234567890.9
(123: BigInt)

They would expand to

val x: BigDecimal = BigDecimal.literally.fromString("1234567890.9")
(BigInt.literally.fromString("123"): BigInt)

This assumes that BigDecimal has a companion object like

object BigDecimal {
  implicit def literally: Literally[BigDecimal] = new {
    def fromString(digits: String) = new BigDecimal(digits)
  }
}

We can improve on this solution by making fromString a macro that checks the digits string
for syntactic validity.

One issue is how to define a syntax for general numeric literals N without mentioning the result type. One candidate syntax would be:

  • a digit 0-9
  • followed by a sequence of digits or letters,
  • which can also contain one or more '_'s, if followed by a digit or letter,
  • which can also contain one or more '.'s if followed by a digit.

This would allow for many different ways to write numbers (even IP addresses would be covered!). It does not cover floating point numbers with exponents, but I am not sure these are worth generalizing.

3 Likes