Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala's .type and Java's .class literal

I wonder from a language design perspective why Scala has removed Java's class literal (e. g. String.class) and replaced it with classOf[String], but has then added a "type literal" with its Singletons like Singleton.type instead of something like typeOf[Singleton]?

like image 728
soc Avatar asked May 25 '11 00:05

soc


People also ask

What is a class literal?

A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a .

What is classOf in Scala?

A classOf[T] is a value of type Class[T] . In other words, classOf[T]: Class[T] . For example: scala> val strClass = classOf[String] strClass: Class[String] = class java. lang. String scala> :t strClass Class[String]

What is type in Scala?

Scala is a statically typed programming language. This means the compiler determines the type of a variable at compile time. Type declaration is a Scala feature that enables us to declare our own types.


2 Answers

Here is my rationalization:

classOf[T]

classOf is defined in Predef as a function with this signature:

def classOf[T]: Class[T] 

Although it's implemented by the compiler, using the function syntax is possible without having to create any special treatment in terms of syntax. So that's one reason here to consider this option.

The alternative like String.class would imply that each class has a companion object with a field class. So there are two problems:

  1. class is a keyword, so that causes a problem where the syntax would require a special case for it
  2. if you just create class A without a companion object, it's would be odd to be able to refer to A.class, which would be like accessing the class field on the companion A.

A.type:

On why typeOf[A] may be confusing. It looks like a function call, but types don't live in the same world as function results (function results have types, but the type itself only makes sense at compile time). I can ascribe a type to a variable:

scala> val a: A.type = A a: A.type = A$@c21a68 

I can't assign a type like it's returned by a function:

scala> val b = A.type <console>:1: error: identifier expected but 'type' found.    val b = A.type              ^ 

On the other hand types can be member of a object:

scala> object A { type type1 = Int } defined module A  scala> val x: A.type1 = 1 x: A.type1 = 1 

So it is not a big stretch to have A.type refer to the type of object A. Note that .type aren't used beyond referring to types of singleton objects, so it's not really that frequent.

like image 136
huynhjl Avatar answered Oct 08 '22 11:10

huynhjl


Actually, it is quite consistent. Singleton.type is a dependent type of Singleton, while classOf[Class] is a type parameter to a method.

Consider this:

class A {     class B }  val a: A = new A val b: a.B = new a.B 

The point here is that . is used to indicate something that is a member of a value. It may be a val, a var, a def or an object and it may also be a type, a class or a trait.

Since a singleton object is a value, then Singleton.type is perfectly valid.

On the other hand, a class is not an object, so Class.class doesn't make sense. Class doesn't exist (as a value), so it is not possible to get a member of it. On the other hand, it's definition as def classOf[T]: Class[T] is plain Scala code (even if the actual implementation is compiler magic).

like image 45
Daniel C. Sobral Avatar answered Oct 08 '22 11:10

Daniel C. Sobral