the blog for developers

Native Type Support In Scala? Wish for 2.8

I wish Scala would have native support for types. Currently in Scala you need to write classOf[Person] for the Java Person.class expression.

It would be nice to have something easier than the noisy classOf e.g. when using Google Guice. Because using Guice with Scala looks ugly. I know I could do DI without Guice/Spring in Scala, but for varios reasons I don’t want to follow Jonas approach for now.

I think Groovy can just use Person for referencing types, but something like #Person would be ok too.

About the author

stephan Stephan Schmidt has been working with internet technologies for the last 20 years. He was head of development, consultant and CTO and is a speaker, author and blog writer. He specializes in organizing and optimizing software development helping companies by increasing productivity with lean software development and agile methodologies. Want to know more? All views are only his own. You can find him on Google +

You can leave a Reply here. Of course, you should follow me on twitter here.

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

Leave a reply.

Comments

That *is* native support. You’re just asking for extra syntax, which is fair, but different to asking for native support.

stephan

@Ricky: From my point of view, classOf[] looks like library support not native support. Perhaps we have a different perception here.

And being a different syntax has – for me – nothing to do if the solution is native in the language or looks like a library feature.

[edit] (I guess you’re right it’s native, but it feels like a library feature compared with .class or using Person directly, which feels like a language feature, even instanceof feels more like a language feature than classOf[] to me.)

classOf is certainly in the library, though it has a ‘magic’ implementation in the compiler, i.e., it compiles down to the same thing as Java’s .class.

I refer you to Guy Steele’s talk “Growing a Language” to explain why there should be no difference between library- and language-provided features. Bear with it (the talk), I know it’s odd at first.

http://video.google.com/videoplay?docid=-8860158196198824415

stephan

I know the talk, who doesn’t?

Then I’m surprised that you want to differentiate between library- and language-provided features.

stephan

@Ricky: No, as I’ve said, I don’t want to. It’s the feel of it:

“@Ricky: From my point of view, classOf[] looks like library support not native support.”

“I refer you to Guy Steele’s talk “Growing a Language” to explain why there should be no difference between library- and language-provided features.”

I refer to objects by their name e.g. “person”, I want to refer to classes by their name, e.g. “Person”.

As I’ve said, perhaps it’s only my perception, but Person.class looks like an language feature and classOf[Person] looks like an library feature (feeling != implementation). Citing Guy Steel there shouldn’t be a difference?

I’ll take a look at the video again though I have the feeling it won’t clear this issue up.

stephan

Assume one moment referencing objects would be a library feature and you would need to write

var objectOf[person] = objectOf[department] headOf

instead of

var person = department headOf

The first one doesn’t look “native”

Stephan, Scala uses square brackets for what are best thought of as static functions over static types.

It’s the same notation used in parametric polymorphism (aka generics). E.g. you can write

def id[X](x : X) = x
val stringId = id[String] _

Which says take the polymorphic identity function and create an a function object specialized on String.

val people = List[Person]()

Which says take the List class, find a List constructor and specialized it on Person and then call the constructor.

And finally, you can write

classOf[Person]

Which instantiates the nullary classOf[X] function, which conceptually instantiates a specific classOf for Person and then calls that function.

Thus classOf[List[Person]] is a perfectly natural thing to write in the language. Special syntax so that you can write List[Person].class would feel unnatural and would not make design sense. I find this (and many) aspects of Scala’s design aesthetic much cleaner than Java’s.

As for your silly “objectOf” example, the symmetrical example would be that in Java you would always have to write

Person person = department.object.headOf.object

You have no problem writing Person.class in Java now because you’re used to it. When I first encountered it I was confused because it was treating the type as if it were a metaobject with a class method. But that wasn’t the case. I couldn’t do things like Person.newInstance(), I had to write Person.class.newInstance(). Scala’s notation makes it clear that classOf[Person] isn’t a method on a metaobject, but a function on a static type. What it returns is a metaobject on which you are free to call methods like newInstance.

stephan

“classOf[Person]”

Shouldn’t this then be called Class[Person]?

“As for your silly “objectOf” example, the symmetrical example would be that in Java you would always have to write”

There would be more to be said in an answer to your comment concerning Person.class, because it seems to me you haven read the post, especially the Groovy part. But this is where this discussion stops, people using “silly” in a discussion are usually not interested in the discussion but interested in being right. And this leads from a community of doing the best to a fanatical we’re right. Thanks for your comment, perhaps it might help other people.

pk11

hi stephan,

I might be wrong but I think it’s probably possible to create a simple implicit conversion for Object.class->ClassOf[Object] to get java-like class literals

(btw we use pico container with scala where we mix java and scala components and this setup is working just fine.)

stephan

@pk11: I’ve read my post again, because I thought I did make a mistake, but I can’t find a statement where I want Person.class in Scala. So perhaps I’m missunderstanding both you and James. Could you help?

Perhaps you could give a code example of your Pico use to make it clearer for me.

In the post I wished for referencing classes the same way I reference objects, by name. Such as Groovy does it.

class MyModule implements Module {
    void configure(Binder binder) {
        binder.bind(Service)
            .to(ServiceImpl)
            .in(Scopes.SINGLETON)
    }
}

http://glaforge.free.fr/weblog/index.php?itemid=208

If you want to be nasty, you can leverage companion objects + implicit conversion for this:

trait MetaClass {
def toClass = {
val name = getClass.getName
if (name.endsWith(“$”) {
val cname = name.substring(0, name.length – 1)
Class.forName(cname)
} else {
throw new RuntimeException(“No companion class!”)
}
}
}

object MetaClass {
implicit def metaToClass[A](m: MetaClass): Class[A] = m.toClass
}

// example
trait Service { … }

object Service extends MetaObject

import MetaClass._
binder.bind(Service)

It’s ugly and unsafe and rather antithetical to the language design, but you can do it.

James pretty much correctly summed up the reasons why classOf[Person] is better than Person.class and *much* better than Person: Person is a *type*, it is not a meta-object. If you can refer to types as objects, then you have one really weird language. Depending on what you can do with that type once you’ve got it, such a feature may even make your type system unsound.

I agree that classOf[Person] is ugly, but from a theoretical and consistency standpoint, it is infinitely superior to Java’s Person.class. Its only three characters extra, I would try to get used to it if I were you.

stephan

Nice hack.

“If you can refer to types as objects, then you have one really weird language.”

I didn’t want to refer to types as objects, but like objects.

“I agree that classOf[Person] is ugly, but from a theoretical and consistency standpoint, it is infinitely superior to Java’s Person.class.”

I’m really not sure why everybody refers to “Person.class”. Is this a Java vs. Scala thing? Is every post that mentions Scala and Java a Scala vs. Java thing? It wasn’t intended as such. I wanted just to reference classes in the same way I reference objects, by name.

James iterated over implementation issues of classOf[] vs. .class, not about accessing objects and classes.

I’m not sure why this is not possible?

@Stephan: I’ve read my post again, because I thought I did make a mistake, but I can’t find a statement where I want Person.class in Scala.

post line 1, sentence 2: Currently in Scala you need to write classOf[Person] for the Java Person.class expression.

Perhaps I misunderstood, but I thought you didn’t like scala’s type function notations compared with Java’s methodish notation.

To explain my post..

class : a construct used by the compiler to specify the detailed representation of runtime objects belonging to a family of types. List is a class (or maybe trait, I don’t remember) in Scala.

metaobject : a runtime representation of a type or class depending on the system. In Java, List.class is a metaobject (not a class). classOf[List[_]] is more or less the equivalent in Scala. Note that Scala’s type system was built around parametric polymorphism from the beginning, so you can’t just have classOf[List] where as Java was not so you can’t have List[Person].class. Metaobjects in Java and Scala all have type Class[X] for some X and are instantiations of class Class. This abuse of the word “class” is a large source of confusion. Also, Scala will soon have “Manifest”, an alternative form of metaobject.

static type (or just type) : a construct used by the semantic checking phase to verify consistency. In Scala List[Person] is a type and so is List[_], but List is not and neither is classOf[List[_]].

runtime type : information about an object used for runtime checks of validity of certain operations and for dynamic dispatch. Due to parametric type erasure, the runtime type system in Java is primitive when compared to its static type system.

Having said all of that, I do now see that your point was more about Groovy and how it can automatically use a metaobject when you put a type in a value location. Just a misunderstanding on my part, I focused to narrowly on the first two sentences. Anyway, Scala could have done what you say, but there’s a bit of ambiguity

scala> case class Foo
defined class Foo

scala> val f = Foo

According to the current Scala spec this is already valid and what it does is make f refer to the Foo constructor as a first class function.

As for my “silly” comment, I didn’t mean you were silly, I meant that your example was clearly targeted as being a silly syntactic construct. Apologies.

> I didn’t want to refer to types as objects, but like objects.

I don’t understand the distinction. If I were formalizing a language with referable types, it would look exactly the same as a language where types can be referenced *like* objects in certain circumstances.

Perhaps this is too strong of an emphasis on the theoretical side of the debate. From a practical standpoint, I would love to have Groovy’s and Ruby’s syntax for classes. The problem is that would be one very inconsistent wart in the Scala syntax. One of the things I love about Scala (and I think everyone does) is the fact that the language design is remarkably consistent. There are a few wrinkles, but on balance, it’s better designed than any other language I’ve seen. The reason for this is they avoid things like “special magic convenient syntax for the edge case”. Scala either uses implicit conversions for the special magic, or it avoids the issue altogether.

> I’m really not sure why everybody
> refers to “Person.class”. Is this
> a Java vs. Scala thing? Is every
> post that mentions Scala and Java
> a Scala vs. Java thing? It wasn’t
> intended as such. I wanted just to
> reference classes in the same way
> I reference objects, by name.

I don’t know about everyone else, but I’m just using Person.class as a convenient example of the “kind” of syntax you are looking for. Obviously, Person is more concise, but it suffers from the same problems as Person.class while introducing ambiguity into our explanations.

> I’m not sure why this is not possible?

It *is* possible, but that doesn’t mean that it is a desirable language feature. The one seriously debilitating issue is this syntax introduces ambiguity in the grammar (between class literals and singleton objects). You obviously foresaw this, suggesting #Person as an alternative. Practically speaking, there is nothing preventing Scala from having syntax of this form. What James and I are trying to say is that we don’t think that it would be a good idea for the language as a whole.

One correction to my post

case class Foo
val f = Foo

Actually makes f refer to the companion object, not a first class function. My bad.

pk11

>I’m really not sure why everybody refers to >“Person.class”. Is this a Java vs. Scala thing? >Is every post that mentions Scala and Java a >Scala vs. Java thing? It wasn’t intended as such.

sorry, i also misunderstood your issue! when you gave a scala guice example and called it noisy i immediately compared the scala version with the ‘native’ java version. that’s why i was talking about java’s class literal.

> Actually makes f refer to the
> companion object, not a first
> class function. My bad.

Well, you were half-right. :-)

case class Foo

def build(f: ()=>Foo) = f()

build(Foo)

Companion objects for case classes extend their corresponding function types. So your statement would have been accurate if you had said that “f refers to a first class function which delegates to Foo’s constructor.” Comes to about the same thing.

stephan

@Daniel: I’ve meant this more abstract. In a programming language there are things I need to access. Those are for example objects, fields, methods, functions and classes. Objects are usually accessed with names references, fields in Java are accessed by objectreference.fieldname etc. One needs ways to access these things to write software. classOf[] is just one way to access classes, .class is another way to access those, <Person> is another one (all with slightly different meanings, but all accessing the class). In assembler people accessed those things with register pointers.

“One of the things I love about Scala (and I think everyone does) is the fact that the language design is remarkably consistent. There are a few wrinkles, but on balance, it’s better designed than any other language I’ve seen. The reason for this is they avoid things like “special magic convenient syntax for the edge case.”

Would it then not be better to access a class with Person as I access an object with person (and this is not about Meta-Classes). What I can do with this class reference is another thing (call methods or not etc.) I consider this much easier and consistent.

“The one seriously debilitating issue is this syntax introduces ambiguity in the grammar (between class literals and singleton objects).”

A valid concern, but I’m sure this could be solved.

@James:

“post line 1, sentence 2: Currently in Scala you need to write classOf[Person] for the Java Person.class expression. ”

Oh, sorry, I’ve just wanted to give people an impression what classOf[] does, not compare it to Person.class (I used .class because most readers will know what this does).

I’ll digest the rest of your lengthy post after dinner ;-)

List<Person> has nothing to do with the Person class it’s about the Person type. To see why, remember that you can have List[List[Person]] too, but there’s no List[Person] class. Type != class.

The closest you can come to accessing a class at runtime in Java or Scala is Person.class or classOf[Person] respectively. But even that does not actually give you access to the class but to a metaobject. This is true even in Groovy – it’s just that Groovy supports dynamic metaprogramming such that having access to a metaobject is more-or-less like having access to the class. Groovy also apparently gives you a handle to a metaobject whenever you use a class name in value position.

The confusing part in the whole discussion that in the right context, the static type, the class, and even the metaobject can each legitimately be called “Person” even though they are three different things from three different worlds. Then, in Scala, we have the companion object – which perhaps could be the same as the metaobject, but probably not without breaking Java compatibility. While we’re at it, there’s also a Person runtime type which a fourth concept which is accessible via isInstanceOf, asInstanceOf, and dynamic dispatch. (as an aside, that’s where you see the limitation of the runtime type systems in Java and Scala as compared to the static type system – the runtime type system might see something called simply List where the static type system has a type called List[Person]).

It’s also somewhat confusing that in Java runtime type and class are pretty parallel, but still should not be considered the same. For instance null clearly has a runtime type and just as clearly has no associated class or metaobject (as an aside, it also has a static type which is a subtype of all reference types, even though that type isn’t explicitly denotable in Java).

Importantly, in languages with duck typing, runtime type is a much more sophisticated concept than Java allows – essentially the runtime types can be structural. Groovy supports both structure and nominative runtime types. Scala has an optional structural static type system and effectively has an optional structural dynamic type system accessible via casting, but it’s significantly harder to use than Groovy/Ruby/etc.

In other languages there’s even less of a relationship between class and runtime type – some “OO” languages like JavaScript don’t even have classes but still have runtime types.

Sorry about all the rambling, long winded talk.

stephan

“Sorry about all the rambling, long winded talk.”

Ah, no, thanks for the long explanation.

As I’m more of a practical person, is

bind(Person)

using the Type, the Class or the Meta-Object?

> As I’m more of a practical person, is
>
> bind(Person)
>
> using the Type, the Class or
> the Meta-Object?

Depends on how you look at it (hence, James’s point). It certainly would not be the type, but it could be either the class (or more correctly, the *meta-class*) or the meta-object.

> Would it then not be better to
> access a class with Person as I
> access an object with person
> (and this is not about Meta-
> Classes). What I can do with
> this class reference is another
> thing (call methods or not etc.)
> I consider this much easier and
> consistent.

So, if we were to use this syntax, what would this mean?

Person.getMethods()

Just for kicks, let’s make it even worse in the declaration:

class Person { … }

object Person {
def getMethods() = …
}

So does Person.getMethods() refer to classOf[Person].getMethods()? Or is it a call to the getMethods() method in the Person singleton?

class MyModule extends Module {
def configure(binder: Binder) {
binder.bind[Service]
.to[ServiceImpl]
.in[Scopes.SINGLETON]
}
}

This is possible since Manifest hit Scala, though obviously you’d have to wrap the Binder API to achieve it.

@Ricky

Neat idea. I think you’ll have to change “in[Scopes.SINGLETON]” to “in[Scopes#SINGLETON]“, but besides that I think it could be done. This is a lot nicer than my companion object hack.

The one thing I would caution is that Manifest probably shouldn’t be relied upon too heavily. I don’t remember the specifics, but there are some circumstances where generic types cannot be fully reified on the JVM (even using Manifest).

Leave a Reply

What people wrote somewhere else:

Additional comments powered by BackType

Guide to CodeMonkeyism

Over the last 4 years I wrote many articles on this blog. To make it easier for you to find the relevant ones, I've organized them into topics.

Top 10

6 reasons why my VC funded startup did fail

Go Ahead: Next Generation Java Programming Style

Java Interview questions: Write a String Reverser

The dark side of NoSQL

7 Bad Signs not to Work for a Software Company or Startup

Is Java dead?

Scala vs. Clojure

Never, never, never use String in Java

No future for functional programming in 2008 – Scala, F# and Nu

Clojure vs Scala, Part 2

Java Developer

Is Java Dead?

Go Ahead: Next Generation Java Programming Style

Be careful with magical code

All variables in Java must be final

Never, never, never use String in Java

Bending Java: More readable code with methods that do nothing?

NoSQL Guy

NoSQL: The Dawn of Polyglot Persistence

The dark side of NoSQL

Essential storage tradeoff: Simple Reads vs. Simple Writes

Sharding destroys the goals of your relational database

The unholy legacy of databases

Startup/CTO

Development Dream Teams

6 reasons why my VC funded startup did fail

American vs. European style of Software Development

12 Things to Reduce Your Lead Time and Time to Market

The high cost of overhead when working in parallel

Essential storage tradeoff: Simple Reads vs. Simple Writes

Job Seeker

Another Good (Java) Interview Question

7 Bad Signs not to Work for a Software Company or Startup

Java Interview questions: Write a String Reverser (and use Recursion!)

Java Interview questions: Multiple Inheritance

As a Manager: What I value in developers

Top 10 Tips (+1) to Get a Pay Raise

Agilist

What Developers Need to Know About Agile

5 Practices Better to Change in Your Scrum Implementation

Scrum is not about engineering practices

ScrumMaster and ZenMaster: The joke of certification

What is Trans-Scrum?