Tuesday, December 16, 2008

Is Scala too hard or are you just stupid?

In case you missed it, Python's BDFL a.k.a. Guido van Rossum filed some major complaints about Scala. After you read that, read a good rebuttal and especially observe the ensuing debate. I especially liked Tony Morris's closing salvo. He brings some validity to the ad homenim response: Maybe you don't like Scala because you are too dumb to understand it. Please allow me to commit the most common fallacy of human thought and attempt to answer this question by only examining my own experience. In other words, if Scala seems too hard to me, then it is too hard. Period. If it seems simple enough to me, then anybody who finds it hard is just stupid.

Since I am going to make a statement of fact based entirely on my own experiences, maybe a little background would be relevant. I started programming 27 years ago when I was 7 years old. I programmed in BASIC, first on an Apple II at school and then on my very own Commodore 64. My first "real programming" was in Pascal when taking Advanced Placement Computer Science in high school. I probably still think in Pascal and translate everything into it first. I also learned FORTRAN and C while in high school.

In college, I learned a lot more C. For awhile I double-majored in math and computer science. Then I took the CS 10, the weed-out course for CS majors. For all of our programs in that class, we started with a predicate calculus definition of the problem, and then we had to logically derive the solution. We had a tool (I think the prof or somebody else in the department wrote) that we transform the problem statement to a computer program. But not just any program, a Lisp program. I hated everything about this, including Lisp. That class successfully weeded me out, and stuck to math.

In college I also learned Perl (for an economics class) and C++ (for a summer math research project.) After college, I programmed mostly in Java, with some C++, Perl, Ruby, and C# sprinkled in along the way. So in summary, I've programmed in a lot of language, but most of them are from the imperative cum OOP tree with C based syntax. I had one major experience with a functional language, and hated it so much that I change my major. So now on to my observations and emotions about Scala.

1.) Type inference sucks, but you (Java developers) gotta love it. I love having a statically typed language. I am definitely in that camp. However, I love not having to declare types very often. How often do you get to have your cake and eat it too? But this is, in my experience, the major source of pain in Scala. You are at the mercy of the cleverness of the compiler. In Java you are often at the mercy of the cleverness of the JVM, but it requires some esoteric Java (the kind that you only see in job interview problems or in books by Josh Bloch and Neal Gafter) to produce code that looks like it should compile, but will not. This is all too common in Scala. Here is an example.


// this compiles
object ItemMetaData extends Item with KeyedMetaMapper[Long, Item]{
override def dbTableName = "items"
// here is the problem line
override def fieldOrder = List(name, description, reserve, expiration)
}


class Item extends KeyedMapper[Long, Item]{
def getSingleton = ItemMetaData
def primaryKeyField = id

object id extends MappedLongIndex(this)
object reserve extends MappedInt(this)
object name extends MappedString(this, 100)
object description extends MappedText(this)
object expiration extends MappedDateTime(this)
}
// but this does not
object ItemMetaData extends Item with KeyedMetaMapper[Long, Item]{
override def dbTableName = "items"
// here is the problem line
override def fieldOrder = name :: description :: reserve :: expiration :: Nil
}


class Item extends KeyedMapper[Long, Item]{
def getSingleton = ItemMetaData
def primaryKeyField = id

object id extends MappedLongIndex(this)
object reserve extends MappedInt(this)
object name extends MappedString(this, 100)
object description extends MappedText(this)
object expiration extends MappedDateTime(this)
}

The two list expressions are equivalent, and yet one compiles and the other does not. Why? Is it a flaw in the compiler? Is it bad syntax? Is it a flaw in the language implementation (i.e. the List code and the :: code) ?

2.) Having no operators means that operators are everywhere! You can make the case that Scala's syntax is simpler than Java, C++, Ruby, or C++ for that matter. Why? Because it has no operators. There is no operator overloading, because there are no operators. The flip side of this is that it is easy to simulate operators and that everybody can do it. This is great for the wanna-be language designers in all of us, but can really suck. Why? It's like you are constantly encountering new operators. It can make Scala's syntax feel infinite is size, even though it is actually quite small and simple.

3.) Golf is built in and is known as _. Scala uses the underscore all over the place to allow for shorthand. Once you have become reasonably competent at Scala, you begin to like this. Until then, you hate it. In other words, it steepens the learning curve. It is a feature for power users, but it is prevalent. Thus you either become a power user, or you quit (insert snide comment about Guido or Cedric here.)

4.) Expressive is as expressive does. A lot of folks have thrown the term "readability" around. There are two aspects of readability. When you read code, do you know what it does? When you read code, do you know how it does it? The more expressive a language is, the easier it is for it to satisfy the first question. However, it may be harder for it to satisfy the second question. One could argue that if a language is better at both of these things than an alternative language, then you would probably rather program in that language. It is certainly easier to tell what idiomatic Scala will do than Java, for example. However, it is often harder to understand how it does it. You can substitute Python for Scala in the above two sentences and it is still true. But could you substitute Python for Java in those sentences? Probably not.

5.) Scala is not for creationists. Ok maybe that's a bad joke by an atheistic evolutionist. What I mean is that object creation can be confusing in Scala. Constructors are not obvious at first. Case classes add confusion, and then you throw in companion objects and you might start screaming "Make it stop!" Oh do I complain too much? Well in most of the other "mainstream" languages you need to learn exactly one thing to figure out object construction. Sure there may be other patterns (factories, singletons, builders, etc.) for augmenting this, but there is only "natural" way instantiate a class. In Scala you see standard stuff like val foo = new Foo("2ez") but also val foo = Foo("wtf"). The latter could be a case class, in which case the former won't compile. Or it could be a companion object, in which case both things compile.

So what is the conclusion? Well for all of my struggles, I have managed to find my way around Scala. So there, it must not be too hard. I am no smarter than any other programmer out there, so if I can learn it, they can too. Plus, my job did not even depend on it. Usually when a programmer has to learn a language, their job depends on it. A motivated programmer can definitely learn Scala is no time!

5 comments:

Ismael Juma said...

Hi,

"In Scala you see standard stuff like val foo = new Foo("2ez") but also val foo = Foo("wtf"). The latter could be a case class, in which case the former won't compile. Or it could be a companion object, in which case both things compile."

I think there is some confusion here.

Case classes don't introduce anything new when it comes to construction. It's simply that a companion object is generated for each case class. Also, both forms work (with or without new). See an example that compiles fine:

case class Bar(i: Int)

class Foo {
val bar = new Bar(5)
val bar2 = Bar(5)
}

Ismael

Robin Barooah said...

I've been learning scala for a while now, and my experience is that it's deeper than most of the languages people regularly use to get stuff done, and so it takes a significant amount of time to learn.

I hadn't tried to use a serious language that took more than a couple of hours to understand for a very long time, and had forgotten what that feels like.

It didn't feel good at first, but now I'm glad I started on it. Because scala is more than the sum of it's parts, as are most serious languages, it's hard to take seriously the criticisms of people who haven't actually written any programs in it.

That's not to say that it doesn't look intimidating. Or that it is immediately obvious. These are valid observations, but I think any programming language you don't know can be like that.

To me the important questions are: is it worth learning? and once you have learned it, is it still unreadable, or does it become clearer?

And so far, my experience has been that it's well worth learning, and it does get clearer as you learn it - and is clearer to me than java.

jherber said...

Scala takes some commitment, but the brevity, power, and access to everything the JVM ecosystem has to offer is worth it, in my opinion. If you understand the rational (research behind it) and how the functional piece is implement, the whole thing "clicks". Try googling for Jorge Ortiz's Scala classware - he does an excellent job of exemplifying how Scala is implemented in Java's constructs.

I think Scala's designer, Martin Odersky, addresses Java's shorcomings (something Java's evolvers are not in the position to do very well) and the larger problem of how we keep making progress in terms of building programs that are easier to proof, understand, componentize, compose, and test.

Another benefit I see after grasping the functional paradigm, is how Scala allow developers to stand on the shoulders of the geniuses in the functional research and implementation community - something not possible in Java.

Mikegr said...

I think it's important to distinct between the characteristics of a single language and the implementation details of a paradigm like functional programming.

Eg. you cannot blame Scala for it's complexity if you have never used another functional language.

Object oriented programming is much harder than just structured programming. Nevertheless a developer must know OOP in 2009 and should know FP.

akmal niazi khan said...

Programming is very interesting and creative thing if you do it with love. Your blog code helps a lot to beginners to learn programming from basic to advance level. I really love this blog because I learn a lot from here and this process is still continuing.
Love from Pro Programmer