5

Sometimes one might want to declare x to be of the same type as y. With vals type inference handles this very well, but this does not work in some other areas, like with function types.

A solution which seems obvious to a programmer with some C++ experience would be a decltype. No such facility seems to be present in current Scala.

An answer to the linked questions tells:

because types are not first class citizens

I have to admit I do not understand this. I do not think types are a first class citizens in C++, but still it can have the decltype. I am not asking about anything like decltype for type parameters in generics or anything like that (I understand generics are not templates and the types are erased in them). Still, I think an operator which would allow me to use a type of an expression in a place where a type is expected - certainly the compiler must be able to evaluate an expression type, otherwise type inference for val definition would not be possible.

A decltype could be used like below - the code is not trying to do anything anything useful, just to illustrate the syntax and basic usage:

case class A(x:Int = 0)

val a = new A(10)
val b = new decltype(a)

def f(c:decltype(a)) : decltype(a.x+a.x)

Is absence of decltype a deliberate decision, or are there some specific reasons why Scala cannot have it? Is there perhaps some solution using compile time reflection which would allow this?

Community
  • 1
  • 1
Suma
  • 33,181
  • 16
  • 123
  • 191
  • How does `b` come into play here? – Michael Zajac Mar 13 '15 at 18:49
  • @m-z b is here just as an example. In this particular case it would be is the same as val b = a, but one can easily imagine similar case where it would not be the same. I will try to update the question. – Suma Mar 13 '15 at 18:58
  • I don't understand the question. Type signatures are compile time, so you must be able to specify the type statically. Then what does that `decltype` thing give you? What's the "disadvantage" of the regular `val b: A = a` and `def f(c: A): A`? – 0__ Mar 13 '15 at 21:55
  • @0__ Statically does not necessarily mean it the programmer is able to provide a type name. `def(c: A): A` is not equivalent, the return type is actually `Int` (type of `a.x+a.x`), In this case it can be overcomed by using the return type inference, but there are cases where it cannot, this approach cannot be used if you are defining abstract methods or function signatures. One prominent example is function types as written in the other question. There is already one precedent in Scala where compiler evaluates type of expression - singleton types. – Suma Mar 14 '15 at 06:48
  • @0__ Also note that `def f(c: A)` does not adapt itself if type of `a` is changed - the parameter type is not inferred, it must be given by the programmer. – Suma Mar 14 '15 at 06:50
  • Is there anything you want to do here that couldn't be done with type aliases and abstract types? http://stackoverflow.com/questions/1154571/scala-abstract-types-vs-generics – itsbruce Mar 16 '15 at 02:37
  • 1
    @0__ The problem is that you might not know type A; you might have val a = someFuncton(whatever) that returns a type that you shouldn't have to know, and you might want to use that type; e.g, as a parameter to some generic class like List or Future. In C++, decltype(x) is the static type of expression x. – Jeff Schwab Mar 21 '15 at 16:42
  • "that returns a type that you shouldn't have to know" - well I think you are misunderstanding Scala. If you call into an API, you should have an idea what type you get. That's part of the whole logic. If you are tired of writing a long type, declare a type alias once. – 0__ Mar 21 '15 at 19:51

1 Answers1

2

My first stab:

class Decl[T] { type Type = T }
object Decl { def apply[T](x: T) = new Decl[T] }

For example, if we have some variable x whose type we don't want to state explicitly:

val d = Decl(x)
type TypeOfX = d.Type
Jeff Schwab
  • 613
  • 6
  • 16
  • This is really nice. It is a pity one cannot write `Decl(x).Type` directly (or at least I did not find a way), but still nice, it does the job. – Suma Mar 21 '15 at 20:00
  • I think this shows the absence of something like `decltype` in Scala is most likely a deliberate decision. – Suma Mar 21 '15 at 20:04