Rectangle 27 0

What is the difference between a class and a type in Scala (and Java)?

A Scala style class, on the other hand, is just the specification for a set of objects. That specification includes some type information and includes a lot of implementation and representation details such as method bodies and private fields, etc. In Scala a class also specifies some module boundaries.

A static type is a property of a portion of a program that can be statically proven (static means "without running it"). In a statically typed language, every expression has a type whether you write it or not. For instance, in the Cish "int x = a * b + c - d", a,b,c,and d have types, a * b has a type, a * b + c has a type and a * b + c -d has a type. But we've only annotated x with a type. In other languages, such as Scala, C#, Haskell, SML, and F#, even that wouldn't be necessary.

As I get to understand from your above explanation, a question has just crossed my mind. Will I be wrong if I assume, that due to the checking of type during run-time, the dynamically-typed languages(like Python) are slower compared to the statically-typed languages(Scala, Java); because dynamically typed languages have to perform extensive type-checking and that too at run-time?

Exactly what properties are provable depends on the type checker.

Finally, as other's have mentioned, there are types like int which don't have a class as an implementation detail, types like Null and Any which are a bit special but COULD have classes and don't, and types like Nothing which doesn't even have any values let alone a class.

Many languages have types but don't have classes and many languages have classes but don't have (static) types.

Now, dynamic types. Dynamic types are properties of objects that the runtime automatically checks before performing certain operations. In dynamically typed class-based OO languages there's a strong correlation between types and classes. The same thing happens on JVM languages such as Scala and Java which have operations that can only be checked dynamically such as reflection and casting. In those languages, "type erasure" more or less means that the dynamic type of most objects is the same as their class. More or less. That's not true of, e.g., arrays which aren't typically erased so that the runtime can tell the difference between Array[Int] and Array[String]. But remember my broad definition "dynamic types are properties of objects that the runtime automatically checks." When you use reflection it is possible to send any message to any object. If the object supports that message then everything works out. Thus it makes sense to talk of all objects that can quack like a duck as a dynamic type, even though it's not a class. That's the essence of what the Python and Ruby communities call "duck typing." Also, by my broad definition even "zeroness" is a dynamic type in the sense that, in most languages, the runtime automatically checks numbers to make sure you don't divide by zero. There are a very, very few languages that can prove that statically by making zero (or not-zero) a static type.

Scala offers structural types. {def foo : Bar} means any object that provably has a foo method that returns a Bar, regardless of class. It's a type, but not a class.

There are several observable differences between types and classes. List[String] is a type but not a class. In Scala List is class but normally not a type (it's actually a higher kinded type). In C# List isn't a type of any sort and in Java it's a "raw type".

Types can be abstracted using type parameters. When you write def foo[T](x : T) = ..., then inside the body of foo T is a type. But T is not a class.

Types can be virtual in Scala (i.e. "abstract type members"), but classes can't be virtual with Scala today (although there's a boilerplate heavy way to encode virtual classes

When you say "type" I'm going to assume you mean static type mostly. But I'll talk about dynamic types shortly.

Rectangle 27 0

What is the difference between a class and a type in Scala (and Java)?

(Int) => String // both the type and class are Function1[Int,String]
"hello world" // class and type are String
7 // both the class and type are Int in Scala
  // in Java there's no class and the type is Integer.TYPE

println("hello world") // the return type is Unit, of class Unit
                       // Java has void as a type, but no corresponding class

error("oops") // the type and class are both "Nothing"
type A // 'A' is an undetermined abstract type
       // to be made concrete in a subclass

class Seq[T] { ... } // T is a type, but not a class

"higher-kinded" rightly implies that Seq has a "kind", which is * => *, this notation states that Seq will take a single type and yield a single type (this is similar to curried notation for describing functions). By way of comparison, the kind of Map is * => * => * because it takes two type parameters.

'Java has void as a type, but no corresponding class'. Java has a type that represents void: java.lang.Void. It can be used similarly to the 'boxing types' Integer, Double, etc. It's used a fair bit in the reflection and concurrent APIs and can be used at will in class declarations and bodies.

@James - Even that distinction sometimes isn't enough, when you start looking at compiler internal representations it gets even more convoluted. Especially when you start considering erasure.

Broadly speaking, a class is something that can be instantiated. singleton objects (scala) traits (Scala) and interfaces (Scala) are also commonly considered to be classes. This makes sense, as singletons are still instantiated (via compiler-generated code) and an interface can be instantiated as part of a subclass.

Just one upvote, seriously? Was the reply that useless?

Okay, I'll bite... James has a good answer, so I'm going to try a different tact and give a more down-to-earth viewpoint.

Seq is interesting as it's a class, but not a type. More accurately, it's a "type constructor"; something that will construct a valid type when supplied with the necessary type parameter. Another term for type constructors is "higher kinded types", I personally don't like this term, as "type constructor" encourages me to think in terms of supplying types like any other form of argument - a mental model that has served me well for Scala.

The difference between "type constructor" and "higher kinded type" is a matter of how it can be used. In Java List can't be used as a type (ignoring raw types, which suck) but List can be used as a type constructor. In Scala it can be used either way.

There are also abstract types and type parameters. For example:

Which brings us to the second point. classes are the primary unit of design in most object-oriented languages (though not the prototype-based ones like javascript). Polymorphism and subclassing are both defined in terms of classes. classes also provide a namespace and visibility controls.

You also get some interesting differences between Scala and Java:

and the really fun types that aren't classes at all. For example, this.type always refers to the unique type of this. It's unique to a single instance and isn't even compatible with other instances of the same class.

types are a very different beast, every possible value that the system can express will have one or more types, and these can sometimes be equated to classes, for example:

Rectangle 27 0

What is the difference between a class and a type in Scala (and Java)?

A type can be useful by itself, without any instances. One example for this is called "phantom type". Here is an example for Java:

Basically everything can serve as phantom type, it's just a kind of "tag" for the type system.

Can an abstract base class not also serve as a phantom type?

I hope this shows that types and classes are something different, and that types can be useful by itself.

In that example we have public static class Initializer<HA, HB>, where HA and HB take some types (represented by the abstract classes TRUE and FALSE), without ever beeing instantiated.