4

I am learning Scala macros and thinking of this as an exercise.

Is it possible to use Scala macros to write down something like this (maybe not exactly this concrete syntax, but something without boilerplate)

enum DayOfWeek = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday

And have it macro-expand to something like this?

class DayOfWeek private (val ord: Int) extends AnyVal {

  def next: DayOfWeek = ord match {
    case 0 => Tuesday
    case 1 => Wednesday
    case 2 => Thursday
    case 3 => Friday
    case 4 => Saturday
    case 5 => Sunday
    case _ => throw Error("Sunday does not have next")
  }

  override def toString: String = ord match {
    case 0 => "Monday"
    case 1 => "Tuesday"
    case 2 => "Wednesday"
    case 3 => "Thursday"
    case 4 => "Friday"
    case 5 => "Saturday"
    case _ => "Sunday"
  }
}

object DayOfWeek {
  def count = 7

  val Monday    = new DayOfWeek(0)
  val Tuesday   = new DayOfWeek(1)
  val Wednesday = new DayOfWeek(2)
  val Thursday  = new DayOfWeek(3)
  val Friday    = new DayOfWeek(4)
  val Saturday  = new DayOfWeek(5)
  val Sunday    = new DayOfWeek(6)
}

And maybe not neccessarily using consecutive integers to represent enumerations. For example, with some flag, we can have enums with no more than 32 or 64 alternatives be represented as bits, and have an efficient unboxed implementation of its set (as Int or Long).

Another compelling reason for having something like this is we can also customize different aspects for slightly different flavors of enum, for example, above, we could have provided some parameter to enum so that next cycles around instead of erroring on Sunday.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
Phil
  • 5,595
  • 5
  • 35
  • 55
  • 1
    Not directly related, but lots of interesting things here http://stackoverflow.com/questions/1898932/case-objects-vs-enumerations-in-scala and here http://stackoverflow.com/questions/1321745/how-to-model-type-safe-enum-types – Felipe May 06 '15 at 19:05

2 Answers2

3

This has already been attempted (by Alois Cochard and Simon Ochsenreither) in a way that would be compatible with Java enums, but IIRC the Scala compiler would not emit some required flag into bytecode, and the project got stuck. The latest version I'm aware of is here.

I'm not sure whether it's of use for your idea. You'll need to work on the syntax, since I'm not sure that will even parse, and you probably need some advanced flavor of macros (scala meta, for instance) to pull it off.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
1

So from Rex Kerr's answer, I figured out I needed to look at StaticAnnotation, then made a simplistic implementation here. For my personal usage, I don't see the need to maintain nice interoperability with Java, but there I go.

(Allow me to be shameless and accept my own answer ^^)

Community
  • 1
  • 1
Phil
  • 5,595
  • 5
  • 35
  • 55