Saturday, October 30, 2010

Scala Bowling - A better Java or a Research Project?

A short post in the hope that I'll get some input about Scala. I first looked at Scala when it first came about, around 3 years ago now I think. My first impressions were clever, conceptually robust, but schizophrenic. It is as though the language designers decided to shoe horn in every language feature they could think of. It was clear that it was way more powerful then Java, but for me it was too clever, too complex.

Well three years later I'm looking at Scala again. I've recently come back to Java, after spending awhile in C# land, and I'm sorely missing lambdas. A quick perusal of the usual Java forums convinced me of what I had already suspected. Java 7 and closures aren't going to see the light of day anytime soon. What Java needs is a re-write, and you could argue that Scala is it! So I downloaded a Scala plug-in for Eclipse, got "hello world" up and running and started pondering what to do next?

As chance would have it, trusty Ron Jefferies has come to the rescue again with his bowling game. His first attempt at Bowling with Scala is definitely imperative. A sort of Scala for Java programers style. As he anticipated the functional community were quick to come back at him with more functional suggestions, using pattern matching and recursion. Well Scala has all the functional paraphernalia so why not use it? There is a sort of unsaid assumption by the functional crowd that a pure functional solution is somehow intrinsically superior to an imperative one. As I mentioned in my post on Haskell the jury is still out for me. Sure state is evil, and where a functional style is a natural fit to the problem domain, then a pure functional style is a no brainer, but how often is that? My gut feel is that most of the stuff I tend to do (shuffling data between a database and a browser) is imperative in nature, well at least I tend to think of it that way. To me, pure functions are things you use in maths and best suited to mathematical analysis. I get the feeling that Ron also shares my misgivings, and yet again, the expert pure functional solution was found wanting when someone discovered a failing test.

So how should we use Scala? As a pure OO language where we exploit the benefits of immutability as much as we can? Or as a pure functional language were we exclude state entirely Haskell style? It was interesting to see that the expert pure functional solution came about as a direct port from Haskell. looking at the Haskell version and the Scala version, they are almost identical. Based on this evidence you could describe Scala as a pure functional language, that also so happens to support imperative OO programming.

The guys over at Object mentor may beg to differ. Their bowling examples, whilst functional in nature also exhibit an OO quality, yet they still make use of pattern matching. So their Scala style could be considered an OO/Functional hybrid. What is the budding Scala programmer from an imperative background to do? It seems to me that Scala is still a bit of an experiment, with people still working out the best idioms.

The option of using Scala as a better Java is always there of course, and if I get the chance to do so I will, but there will always be this nagging doubt of whether I'm doing it right? And whether a real Scala programmer would approve? I think languages should promote a style. C was very good at this, with everyone adopting the style of Kernnighan and Ritchie. Smalltalk also makes a very strong style statement, exemplified by the code in the Smalltalk-80 image. Scala doesn't seem to have this. It is though it is at least two languages, or perhaps three, all coexisting. A haphazard mix of paradigms, idioms and styles.

I guess I need to read the book by the inventor Odresky to see if he as a Scala style I can comfortably adopt. More important then the discomfort of "am I doing it right?", is the obfuscation of the problem domain that comes IMHO when applying a pure functional style to problems that are more naturally expressed imperatively. Should I always be living in fear of that next failing test that blows a whole in my cleverly contrived pure functional solution? Or should I be able to reason about the correctness of my program with a modicum of confidence by simply reading it?

I'm interested in finding out the thoughts of people who are further down the Scala path. All comments and pointers welcomed.

12 comments:

Grazer said...

Hi Paul,

I'll make two points.

Firstly, in regards to your comment that web applications feel particularly imperative, I reckon this is a bit of an illusion of familiarity. As you say, web applications mostly just take data from a database and present it in HTML, and this is, at its heart, a simple functional transform. The database access is imperative due to history, but the rest of the process is, I think, essentially functional. Of course, the vast majority of existing frameworks for building web applications are not built with this view of the process in mind, so they kind of push us into the imperative way of achieving the goal.

Secondly, in response to your concerns around "whether I'm doing it right", I would simply say: Does your application do what you intend it to do, was it easy to code, and will it be easy to maintain? If you can answer 'Yes' to all three of these, then you ARE doing it right; and if you can't, then you're not. I encourage you to not worry so much about whether your code conforms to other people's ideas of what is good and proper. Measure it against your own previous experience with other technologies and against whether you're achieving your goals with less resistance. We can argue about style until the cows come home. No one can argue with demonstrable progress.

Cheers,

Graham.

Matt Hicks said...

Having read, "Programming in Scala" I would say that the general sentiment of the book is that you should lean toward functional when possible, but you always have an Object-Oriented paradigm to fall-back on. I've been programming in a Scala almost exclusively for about a year now and having programmed almost exclusively in Java for twelve years before that it has been an interesting road. It takes a lot for someone with such a hard-headed mentality toward OO to accept the ideas of functional, but I think it's starting to sink in and I find myself first asking if there is a good functional way to solve the problems and usually there is. However, in many cases when I go the OO route it has more to do with my own lack of knowledge I think.

Personally I think it's a ridiculous notion to use Scala's vast capabilities as a reason not to use it because you can solve any problem in a multitude of ways.

Paul Beckford said...

Hi guys,

Thanks for your comments. Everything you say (both Graham and Matt) makes sense. I'll persevere with it and I will buy the book.

Thanks for taking the time.

Paul.

Paul Beckford said...

Hi All,

Its just dawned on me. The JVM has extremely limited support for runtime introspection and hence meta-programming. Like the CLR Java class files are a bag of offsets with most of the semantics compiled out.

Given this state of affairs, it is alot easier to implement a static functional language on these platforms then a dynamic OO language.

So Scala is really a functional language with OO extensions, much like OCaml. To gain full metaprogramming support means building a dynamic VM on top of the JVM which obviously will lead to a reduction in performance. I guess this is the route taken by Groovy.

So if you are looking for OO purity and full Meta-programming, Smalltalk style on the JVM, then Groovy is the language of choice. If you are looking for closures and functional extensions C# style then Scala.

You pays your money, and take your choice :)

Paul.

Grazer said...

It's true. Groovy is interpreted at runtime. (According to Wikipedia, a script is compiled to bytecode at runtime before it is executed, though I don't know how the situation works with metaprogramming.) Scala, on the other hand, is compiled to bytecode at build time, so if performance is a key concern in your application, this may weigh in favour of Scala. Depends how much you need metaprogramming, of course. The third option is to use all three languages in different parts of your application as you see fit. There's no rule saying you have to pick one and go with it!

PhiLho said...

I agree with the comments above.
I am a beginner in Scala too, and I appreciate the flexibility, I don't see it as an obstacle.
I like that I can make imperative coding if I want, eg. in small Scala shell scripts or in simple Kojo drawings.
I appreciate that I can do pure OO programming if I want: hey, I can even iterate on the collections if I want to keep a Java feeling (but I won't...).
And indeed, I can use functional coding where it makes sense, precisely when manipulating collections: they offer tools to ease their usage in this way, and the fact I can write: "apply this function on each member of my collection satisfying a given condition" in a short (more concise than the previous English sentence!) way is nice.

There is no "good", "endorsed" way, there are ways better fitting to your way of thinking, which can evolve with time.
I appreciate to be able to sprinkle my coding with some functional goodies (because they are concise while remaining readable if we are careful) while not being forced to do all the coding this way.

Some people might see this as a bastardized way of coding, but well, bastards, hybrids and mixed-race are often seen as more robust and nicer than "pure" breeds... And well, Scala is still pure in its design, very orthogonal and well thought.

Paul Beckford said...

Hi Graham,

I just wanted to know what I've got with Scala before investing a whole bunch of time. There are a lot of programmers out there that know the minutia of a language, without ever standing back and understanding the overarching concepts, strengths and limitations.

Your are right I could use all three, but then I would loose uniformity. There would be places in my code where I would be putting a square peg in a round whole, and I couldn't assume that I could treat everything the same, because it wouldn't be.

A more sensible approach is to have some type of layered architecture with system primitives built using say Scala and higher level stuff in say Groovy. Smalltalk and Ruby programmers have been using this trick with C to overcome performance problems for years.

Ultimately however you would like uniformity all the way down. If you want true message sends then Scala doesn't offer this. This impacts a number of things such as the object model, metaprogramming, actors etc. all of which can be implemented in a uniform way with true message sends. If you don't want to incur a performance hit (and the V8 VM for Javascript shows what's possible) then you need to move away from the JVM. You can even have functional programming thrown in (a function can be an object too):

See Newspeak:

http://bracha.org/Site/Newspeak.html

On the JVM, Scala is a great compromise, but it is a compromise (from an OO perspective). I wouldn't describe it as a pure OO language because it isn't based on messages. I would call it a functional language with OO extensions, and a great 'on-ramp' for imperative programmers trying to come to grips with functional ideas (like me :)).

James said...

Could you elaborate on 'Scala isn't message based' ?

I would say that Scala is message based in an OO sense, but it simply checks the validity of those messages at compile time instead of run time.

Of course, arbitrary message support (Dynamic) is coming though pervasive use of it would be quite non-idiomatic.

Paul Beckford said...

Hi James,

I mentioned metaprogramming. Really what I meant was introspection and reflection. With C++ you can do metaprogramming using templates. Pretty limiting and it all happens at compile time. With Smalltalk you can do metaprogramming with reflection and introspection. A lot more powerful because it all happens at runtime. To reflect on things at runtime is powerful. You get this when you can send messages to things that you don't know what they are (you don't know their implementation, you just know they support the reflective messages you are sending).

This ability opens up a whole area of metaprogramming that languages like Groovy exploit and which aren't open to Scala. Incidently this has nothing to do with compile time type safety. You can achieve both message sends and static type checking in the same language. Strongtalk is an example of this. It's just difficult to do and not well supported by the JVM.

Paul Beckford said...

Hey James,

"Of course, arbitrary message support (Dynamic) is coming though pervasive use of it would be quite non-idiomatic."

That's interesting. I wonder how they are going to do that? You say not idiomatic, well not for now, but dynamic programming is contagious :)

This is my concern with Scala, concept overload and not knowing the sweet spot.

I'm guessing, but they seem to be taking a similar path to the work of Eric Meyer with C#. Static OO languages are an historical accident. We are now left with their VMs as ubiquitous :)

My concern is a lot of this stuff feels like making the most of what we've got (the CLR and the JVM) rather then going back to first principles and deciding what it is we need.


Gilad Bracha who wrote the JVM spec has a language called Newspeak inspired by Smalltalk, Self, Beta with the goal of conceptual purity:

http://gbracha.blogspot.com/

At his level much of this stuff goes over my head. But I am a believer in simplicity and conceptual purity. Sometimes when you take the wrong fork in the road you need to go backwards before you can go forward again. As Alan Kay would say: "Back to the Future". Well its working for the Ruby guys.

Just an opinion :)

Paul.

javin paul said...

Very interesting article, I was bored with reading other side of article and this one is quite refreshing to me though with similar information.

javin
Difference between ClassNotFoundException vs NoClassDefFoundError

Paul Beckford said...

My concern is a lot of this stuff feels like making the most of what we've got (the CLR and the JVM) rather then going back to first principles and deciding what it is we need.

Interesting re-reading this over 10 years later. I've become very fond of Scala, and it has wetted my appetite for Haskell again.

Haskell takes the approach I describe. it goes back to first principles and tries to answer, what it is we need if we truly believe that state is evil, and pure functions are the way to go? I've even dabbled with Category theory as a consequence.

It turns out that the best Scala style is using it as an Haskell for the JVM. Scalaz and Cats have addd Type classes as libraries, along with the IOMonad, and I believe that Scala 3.0 will add Type classes natively.

Also the idea of Scala as an "on ramp for Pure FP has panned out to be exactly that. With people moving from the Play Framework with its dependency on Futures, to AkkaHttp and the Actor Model to Http4S with IOMonad like implementations for Scala (Monix, Cats-effects, etc).

Scala in practice has moved further away from Java and has become Haskell for the JVM.