Donnerstag, 4. Februar 2010

What is a Scalable Language good for

Scala again. This time, I will not try to debate abouts its interns and wether its better or worse
than something. Rather, my intention is to find out where the usecases of the Scalability are.

Introduction
Scala is, in my eyes, a language which is pretty execellent at leaving nearly all powers in the hands of the programmer to use "his" scala with "his" preffered style. Unlike most dynamic languages (esp. perl), this however does not mean that scala is magic. Far from it! Instead, it just tries to look behind most of the syntax magic provided by those languages to tries to give a static-typed and logical equivaleng for it.
Those features which most languages have but which they do not offer the user at its full powers are: type inference, operator overload, switch-statements, control structures, closures, type parameters, ...

Offering this kind of power to the user seems strange when comparing this to the concept which lead to the restrictions of java in all these areas: Java contains nearly NONE of them, because java tried to do only OOP in a standard way with a standard method syntax. No operators, no closures, no confusion. And I have to say: After the mess into which C++ might have lead, this was a wise choice by Gosling, which I still think was quite clever at the time.

Java's choice of being simple is a real pain to experienced dev's, which tend to "outgrow" the language at some point of time. But since java contains all of the main aspects which are considered to be important for good coding, i.e. classes ;-), it is a language which is good to begin with. In other words: There are always new - and cheap - programmers available. Complex languages like C++ usually do NOT have this kind of comfort. They rather tend to scare the developers away. ;-)

So whats with Scala? Scala is ultracomplex, far more than C++ will ever be. However, it shines at hiding the complexity. A Scala beginner (coming from Java, I suppose) does not need to know any details about: Operator Overloading, Type Conversions and the depths of generics, sometimes even closures!
The interesting part: Even though he does not KNOW them, he will USE these advanced topics rather quickly: Why? Because + on Strings is Operator overloading (+ on Lists is as easy to understand), implicits are everywhere behind the scenes and generics are nothing else then some simple infos which must be given to know which elements this list holds.
Type Inference? Scary word. var a = "string"? Ok. Understand. Looks like a dynamic language.
And so on.

I you have missed my point: The brilliance of scala is that there are dozens of feature which novice programmers can just use, but do not need to understand. They can just treat them like language constructs and might be very happy the day they find out on how to tailor them for their needs. This GREATLY helps to smoothen the long and steady learning curve which would be needed to learn all of the features.
Also, sometimes the design was just very clever. Java still envies C# for properties sometimes. Scala says: Fields are functions out of the box. No property syntax needed. At least no keywords, since we _CAN overload the operators, right?

So... in my eyes, Scala really cut the boundaries between the advantages of java - easy to learn and understand at first glance - while also offering nearly limitless power when needed.

At least in theory. In pratice, the combination of implicits and closures can be a real PAIN to any novice programmer. And the interoperability with java is, unlike some sources state, actually worse than groovy's for beginners. This has three very important reasons:
  • Groovy is a dynamic language. Since java is static, it can call java code in nearly any way and there a no "conventions" and different semantics to consider.
  • Scala has its own collections. While this is good, as Scala is not java and its collections are very different, it really sucks that there are - in 2.7.7 no default conversions between the BASE datatypes enabled. And with "BASE" i mean no conversion for Iterator or at least Iterable. I cannot really understand this, since Iterable is basically a language construct for java and VERY important to support out of the box for scala for-loops. And there should be some easy ways to at least explicitly convert between scala and java in predef. This would greatly help scala beginners which will usually stick with java collections or at least use libraries which use them.
  • Scala's generics suck. Na, not really. But they DO suck when using them with java raw types. And believe it or not, this happens more often than not! In short terms: There are situations which are completely valid in java but just hideous in scala, as scalas generics are VERY strict and concise to prevent type errors. Problems in this corner usually arise when trying to store scala closures in raw java list or something like that. Seems strange but can happen. And will shred your brain to pieces AND consume a lot of time.
As for me, these two main points are actually the only real problems I faced when learning it. I guess some people will also add closures. Might seem strange, but I am thinking not of people which come to scala but those which probably HAVE to (from Java) since their ProjectManagement wants them to use it. And thats leads back to our main question:

When are Scala capabilities actually good for project? Where are the advantages:
  • Scala can be tailored to need. This can cause problems (confusing overloads and imports) but also greatly simplify the readability of code. General, this is an advantage for 2 reasons:
  1. Framework Developers (at least open-sourcerers) tend to spend a great deal of time trying to make their API pleasureable and easy to use for programmers. Since scala offers more tools, apis can be learned quicker than in java, i presume. Consider Near-DSL like APIs like "specs".
  2. The danger of the abuse of the language can usually be reduced by a good project manager. Business applications and the like do not really need to hop on the trend of functional languages to create 1-line transactions which are perfect but Write-Only. (this was was not fair...)
  3. Of course, if the project manager is an idiot or does not re-read its programmers code and check for conventions, this will lead right into hell. But a bad pm is always a highway to hell, even without java. No real difference.
  • The power of the language will IMHO help developers to make progress in the art of programming much quicker than simpler languages. In Java, the cap when there is nothing new to learn is reached rather quickly. Since learning nothing is boring and there are real essentials still missing in java, this might have lead to the trend of some frameworks to include their own non-java DSLs. And countless xml-accents, of course. Happy learning. ;-)
  • Scala feels like a dynamic language, but it still offers the performance of a static language. Much more important is however that it also offers minimal type annotations. Dynamic lang fans might consider this overhead, but it might actually just reduce documentation overhead: A good scala source with meaningful names does not need documentation hints telling which params are expected for a function. Dynamic languages usually WILL.
  • Some features of dyn-languages are impossible for scala, of course. Others can be emulated via implicit conversions. For most users, i guess the only real relevant missing feature might be the legendary useful art of duck-typing. Its sad, but inner classes and interfaces have always been there to fight this problem.

Scala-Revisited

Currently, I am evaluating Scala again and compare it to other popular jvm languages, like Groovy, or even Java. My Question is: Is there a room for such a complicated, yet extremely powerful language like scala?

Obviously, i am inclined to scream: "Yes, goddammit! Give it to me! My toy". Hm.. Maybe I am exaggerating a bit lately, as most people do when comparing competition products. I REALLY like scala.

However, when being an experienced programmer, it is easy to be emotional about the personal "favorite" language, but there are usual very good reasons why My fav is not everybody's else fav. There are dozens of good languages out there which no one really use, and one seriously has to ask: why? One example: Eiffel.

I guess one of the main aspects behind this is the momentum which the larger programming communities create (like Java), but that one is easy: If you give a good platform which everybody uses, you will soon have libraries which make the language more popular for everybody and so on and so on... Luckily, the jvm platform, like .NET, defeats this problem: Scala can use Java-Classes without any problems.

But.. That is not the problem of scala. Lately, I am reflecting more and more about the "complexity" of the language and what it means for the average programmer (like me). Speaking along the lines of Odersky, Java is a cathedral. It hides some features from the user which had been known for abuse and complexity which "burdens" the programmers. Scala, on the other hand, is a bazaar: It offers nearly everything a programmer could think of as a language construct (even implicits). Effectively, it makes the task of choosing the right tool for the job harder, as they are much more tools to choose from (operator overloading, closures, implicits). Also, one has to be wary that not all programmers in the team might want to use everything the bazaar offers.

The java's cathedral advantage is that the complexity is lower, the bazaars advantage is the flexibility - with the additional weight of deciding which goods from the bazaar are fine and help, and which will prove to be a burden which is better left out.

What about groovy? Well, groovy I see as Java's "sidekick" - It resembles its original pretty much but is tailored for the situations where java's cathedral's vision are not approiate to solve a problem elegantly. (And in time..) Its a kind of "special force" or "inquistion" for situations where features are important.

So... my next logical step will be to compare java/groovy vs scala. Not based on features but on the intention to find out which targets they are trying to achieve, and how.