Shorter syntax for custom specializations


#1

I’m in the process of introducing specialization through my whole hobby project ( https://github.com/tarsa/SortAlgoBox ). In the new (still unreleased) code I have plenty of repetitions of following patterns:

def someMethod[@specialized(Byte, Short, Int, Long) Item](buffer: Buffer[Item])
sealed trait SomeTrait[@specialized(Byte, Short, Int, Long) Item]

How to make the annotation shorter? I would prefer something like:

def method[@sabSpecialized Item](buffer: Buffer[Item])

And a side question:
In scala.Specializable there are following constants:

  final val Primitives  = new Group((Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit))
  final val Everything  = new Group((Byte, Short, Int, Long, Char, Float, Double, Boolean, Unit, AnyRef))

What’s the difference between them? AFAIU every specialized method or type should work with AnyRefs anyway, so why should anyone put them in SpecializedGroup?


#2

I’ve made some experiments but results are disappointing. First I’ve created following code:

import scala.Specializable.Group

class sabSpec extends specialized(sabSpec.Group)

object sabSpec {
  final val Group = new Group((Int, Long))
}

After that I’ve used above code to specialize methods in:

object CustomSpecialization {
  def main(args: Array[String]): Unit = {
    implicit val intAddMonoid: Monoid[Int] = new Monoid[Int] {
      override def neutral: Int = 0
      override def op(a: Int, b: Int): Int = a + b
    }
    println(method1(5, 3))
    println(method2(5, 3))
    println(method3(5, 3))
  }

  abstract class Monoid[@specialized(Int, Long) T] {
    def neutral: T
    def op(a: T, b: T): T
  }

  object Monoid {
    def apply[T: Monoid]: Monoid[T] = implicitly
  }

  def method1[@specialized(Int, Long) T: Monoid](x: T, y: T): T =
    if (x == Monoid[T].neutral) Monoid[T].op(y, y) else x

  def method2[@specialized(sabSpec.Group) T: Monoid](x: T, y: T): T =
    if (x == Monoid[T].neutral) Monoid[T].op(y, y) else x

  def method3[@sabSpec T: Monoid](x: T, y: T): T =
    if (x == Monoid[T].neutral) Monoid[T].op(y, y) else x
}

method1 and method2 are specialized properly, ie for Ints and Longs only. method3 however is specialized for all types. It’s like that for the compiler:

  def method3[@sabSpec T: Monoid](x: T, y: T): T =

is the same thing as:

  def method3[@specialized T: Monoid](x: T, y: T): T =

ie compiler ignores the types I’ve put in the sabSpec definition.

Is that a bug?

PS:
Experiments done on Scala 2.12.4