So Scala is too complex?

24082010

There is currently lots of talk about Scala being to complex. Instead of more arguing I implemented the same bit of functionality in Scala and in Java and let everyone decide for themselves.

There is some nice example code in the manual to the The Scala 2.8 Collections API which partitions a list of persons into two lists of minors and majors. Below are the fleshed out implementations in Scala and Java.

Related

Actions

Information

111 responses

24082010

steve(21:38:17) :

Thanks for your example!

It’s impressive how the “Scala is too complex crowd” never comes up with some examples to prove their point.

Additionally they love to show some complex Scala code piece around arguing Java is much simpler, conveniently ignoring the fact that the equivalent code in Java would need AOP, DI, XML config and/or expression language to work.

Looking at both Scala and Java at the beginner level, Scala wins hand down, I don’t even know why to argue about that.

(Yes, i’m annoyed about these “Scala is too complex” people … their hit-and-run tactic gets on my nerves. :-/)

Scala concepts are very smart, very powerful, and as such go well beyond what Java can deliver, but this comes at a cost. Showing examples with setters and getters won’t change that (you should have added 16 more fields to show how longer the Java code is…)

Instead, why don’t you show us how to best explain to a junior developer when to best use traits (or not). And expect your team to all agree.

Don’t get me wrong, I really like Scala, but that doesn’t make it a trivial language. Part of the success of Java was its simplicity (remember we are speaking of the C++ days where you had plenty of ways to write buggy code).

Compare (written) English and Chinese. See how much you have to type to express what just a few Chinese characters. Does this make English much more complex and difficult to use/explain/learn than Chinese? Sure, writing substantially longer pieces of code is substantially more boring, and writing substantially more concise pieces of code expressing complex tasks gives substantially more pleasure — but this still does not make Scala any easier to learn than Java. Examples as the one above give a rather biased picture.

There is a huge difference between verbosity/conciseness, and readability, yet both of them get lumped into the “complexity” argument.

Written Chinese is concise, but incredibly complex. More like Perl than Scala. Perl can be incredibly concise, but also completely unreadable. Scala is a lot more readable, but not quite as much as languages like Ruby and Groovy.

Java is very readable, but also excessively verbose. Personally I think Groovy hits a much nicer sweet spot on the readability scale, because you don’t have to declare all your getters and setters explicitly, and you can use much more powerful collection logic.

Rather than comparing Scala to Java, I think a comparison between Scala and Groovy would be much more interesting. Groovy offers many of the same advantages, yet any Java programmer can understand the code.

Right, Scala vs Groovy comparisons would actually get to the heart of whether what Scala’s complexity gets you is worth it. Usually the first thing you read about in Scala comparisons is that it saves you typing through inference and getters/setters. So Scala must be more readible because it’s less boilerplate code to read (they claim). OK, well what about compared to Groovy, Python, and Ruby?

Well these functions are part of Scala. That’s one reason making things less complex: not having to reinvent the wheel all the time. Besides, even when I’d had to implement partition and mkString in Scala they would be pretty much one liners.

This certainly shows that scala is less _verbose_ than Java, and there’s certainly a link between verbosity and complexity, but it’s just not that cut and dried. Have a look at some parser combinator code; it’s certainly concise! Hard to argue it’s simple, though.

In fact yes Scala is less verbose, and that’s why it can be seen as more complexe.
Just because each line is more meaning full than java line.
But take a look at java, it’s really a simple language, with not so much construct in it.
It’s obvious than we can assimilate the difficulty of new construct.

I have looked at Scala and learned Java not so long ago (so you cannot come with the argument that I find Java only better because I have so much experience). The 5 ways you can do the same thing in Scala is very confusing. I find Scala code less readable (maybe also because of the lot of functional parts – I already hated LISP and Scala makes the functional programming not more attractive for me).

If you want to be serious about such a comparison, at least use a project that has a few thousands of lines. You will certainly see that Scala is less verbose but what it gains in brevity, it loses in simplicity.

Anyway, this discussion is a textbook example of selective bias. Everyone who thinks that Scala is not complex is already a fan of the language. People who think that Scala is too complex have usually given it a honest try with no particular agenda and then shied away in front of its complexity.

“The thesis of Functional Java is to prove the practicality of Java for solving software problems. It fails. This is not to say that Functional Java is not practical for solving other problems and indeed it does.”

Or this?

“I have found that those who advocate for the practicality of Java as a programming language for solving software problems invariably have an incredibly poor understanding of programming language theory and poor general problem solving skills. […]”http://blog.tmorris.net/java-and-practicality/

The Java example is missing another ‘feature’ which comes for free in Scala – the possibility of passing Functions (or Lambda expressions in this case) to your partition method (kind of higher ordered methods if you like).

So if you would like to partition the persons by another predicate (say age < 21) you could do so easily just by passing another Lambda expression.

For your Java example to 'simulate' this 'feature' too, you additionally have to define say an Interfacse 'Predicate' which is to be passed to your partition method and may get defined by an anonymous class (i think you know the details … :o) ).
(Well, it's a simple solution, since it doesn't support closing over / Closures in the way Scala does)

So considering this 'feature' of 'Functions as first class values' on top, the Java example even gets more complex …

Your sample is unfair – I just say imports and properties. You could just define the variables in Java also (without getters and setters). And then: You choose a sample where you can leverage some functions of the core libraries.

BTW: I had properties in VB long time ago and I prefer the Java way with getters and setters.
With core libraries I mean the set of classes and methods that comes along with the language without adding 3rd-party libraries or frameworks.

I also think your are mixing verbosity and complexity. Yes, verbosity is not necessarily good. Yes, concise can be simpler. Yes, verbosity can be tedious and error prone. But, even as I love Scala, I am not going to move my team onto it, because ‘it is complex’.

Consider your simple example. A developer will need to know the difference between class and object keywords, as well as the smaller things like the case keyword, the conditional (<=), and perhaps the difference between var and val keywords.

Is each of these language features a good idea, yes. But will having them all be a good idea – I am definitely concerned. The fact that *I* and most of this blog readers get scala does not mean that most developers will be ramp up to it easily.

I personally would like to see numbers as to how much time it takes to get an average developer up to speed with Scala. And perhaps more importantly – since developers spend alot of their time reading code – how effective an average developer is in making sense of Scala code (compared to Java).

The concepts behind the keywords you mention are also there in Java. A developer needs to understand them anyway. Only that in Java you have the burden to pattern around while in Scala you have concise language constructs:

I am not saying that this is a good thing or a bad thing. Infact, before I saw Scala, I always believed that the future of Java was direct support for patterns.

The question at the end of the day, is whether this extra vocabulary makes the language more complex, or perhaps more importantly ‘is it worth it’. I just need to see more before move teams onto Scala.

You need to know less about the language, as the language is simpler. But you need to know much more about what you’re doing, since you often need to implement (correctly and efficiently) stuff that comes for free in Scala — or you need to use thrid-party libraries, which obviously makes the Java side less easy to learn and read.

Not true. With Java, if you know only the language itself, you can’t do anything. At least not without inventing the wheel over and over again. To work with Java, you need to know the foundation classes, popular other class frameworks (Apache Commons, for example), (web) frameworks, AOP frameworks, persistence frameworks, not to mention tons of patterns. And much of that exists merely to work around the limitations of the language. It’s better to use a language that supports all of that out of the box, so you don’t need to learn tons of extras to get anything done.

Yes, that’s exactly my point: in Java you get similar things using ad-hoc techniques. Scala has it all right in the language. Consider debugability and maintainability of your code in the light of bugs and quirks of these techniques. This makes the Java solution *definitely* more complex over all.

If you used e.g. Lombok which auto-generates all the getter/setter/toString plumbing code via annotations and e.g. lambdaj that allows to use closure-like filtering on collections, the Java listing would be just a bit longer than the Scala listing. Which proves how often people asserting Scala being better than Java aren’t completely aware of all the possibilities that Java offers. :-)

You mean that if you use two different third part libraries designed to fulfil the gaps and missing parts of Java (and take the extra time to learn them, besides the language itself), then you can get a solution *close* to the native Scala one? Wow, Java is really cool. :-)

But seriously now. The Java platform is great. That is why Scala is built over it. But Java, as a language, is poor. One have to resort to design patterns and 3rd part libraries all the time not to add real value to one’s code, but just to emulate the missing resources in the language.

You can emulate patter matching with visitor pattern? Sure. But which one is more complex? What you think will be harder for a newbie to learn, the syntax of pattern matching in Scala or to design and code (properly) the visitor pattern? Which one will be easier to debug?

It is not Scala that has complex concepts. It is programming. Scala just try (and succeed IMO) to handle this complexity with the right tools.

Very interesting :)
But I’m wondering if you can write exactly the same Java code of your example in Scala. I guess you can since at the end of the day both support all the same oop imperative features. Right? Is when you use idiomatic features when Scala will probably write much less code than Java requires to do the same.

And BTW: There are many other more pressing problems for software developers than just yet another language!

* Improve debugging facilities in existing IDEs for existing languages (no, I am not yet satisfied).
* Thousands of GUI isses:
– Integrate browser panes in thick clients
– More seamless integration with native OS (applies to all languages running on the JVM)
– More straigforward KISS web frameworks (without the need of a huge stack of Webserver, application server, …)
* GUI builder (Matisse on NetBeans is IMHO one of the very few that works well and Swing offers a lot of widgets)
* Component reusage crossing language-borders
I am a system integrator and when still windows-only developer, I was quite happy with VB5 or 6 and COM/ActiveX libraries + GUI controls offering the option to put a lot UI elements of a lot of other applications into my own application windows. Reusage of GUI components from other architectures is frickle work (if not impossible in many cases). Under Windows there was a defacto standard for a long time (which anyway now changes with .net – now we have already three.

and so on and so forth – I could continue for hours.
Sorry, but it does not interest me, if I could do something in Scala with some lines less. Everything that takes me more than 5 lines for sure finds a way in my personal libraries and then is a one-liner, so who cares.

So what was your point again? Scala is complex because it has a feature you don’t use? I promise you, Java has enough of them, too.

Maybe you should worry a bit more about your own skill level and not that much about “junior developers”.

Closures are certainly necessary and easy to understand.

To say it again: there are many code structures, which you can’t just put into a library without using functions of higher order. Sure, there are workarounds, but they are generally to verbose, which makes it difficult to understand the intention of the code.

There are maybe less than 10 common things people will do to collections (foreach, map, flatMap, exists, forall, …) and closures help people to speak the same language, instead of hand-crafting the different for-loops 500 times.

That’s definitely a problem, but I don’t think it’s one best solved in the language. Languages are multi-decade bets across a wide variety of projects, while the appropriate code structures shift more frequently and by circumstance.

For example, look at Java. The Java community lost a lot of great people to other worlds because the Java assumptions about how best to program were just wrong for their needs. Ruby, for example, has some huge drawbacks compared with Java, but its greater flexibility allowed Rails to grab a lot of mindshare.

The way you solve the problem of programmer choice vs code base coherence at the code structure level is the same way you solve it at many other levels, from code formatting up to system architecture. You draw boundaries within which coherence matters to you, and then you create social mechanisms to negotiate standards and encourage cohesion.

Verbosity differences can be determined with a character count and complexity differences can be determined fairly objectively if you can agree on a metric.

My point is that subjective complexity differences can’t be determined, period. To me, Lisp is simpler than both Java and Scala, but Scala seems less complex than Java because it’s more Lisp-like. To someone else, it could be the other way around.

The trouble with all comparisons like this is that they are comparing a new programming language to an old one. The key point that is always missed is that ANY serious new language that is written at this point will have properties, generated methods like equals/hashCode, and a host of other fixes (null handling, no checked exceptions, …). All of this is simply knowledge gained from years with Java. What needs to be proven is that once that baseline is there does Scala then stay as usable as Java (for everyone, not just fans of the language).

The interesting part of the comparison is therefore the parts beyond the “obvious” fixes. This comparison uses partition as the data point. Certainly, that is a good example. However, many of the method signatures that enable such simple client code are very complex in the library, something I find very concerning.

Complexity in the API signatures is the cost of having type safe higher levels of abstraction. The client code is usually pretty simple, though.
I don’t think the discussion should be about language features but the abstraction and composition enabled by those.

Nobody is denying that Java was a huge step up from C++. C++ had issues, and got increasingly complex trying to wrk around those issues, whereas Java just solved them. Now Java is getting increasingly complex trying to deal with its shortcomings, and Scala (but also Groovy) just fixes them in the core language.

I’m not arguing that CL is better than Scala, far from it. It’s just that Lisp code seems less complex *to me*, and I’ll probably always be able to write Lisp counterexamples that convince *me* that Lisp is simpler. It’s a good thing to remember that this subjective simplicity is, well, subjective.

I can say right of the bat that Scala, is just nicer to read and understand than any other functionnal languages. Also it’s easier to learn from java/c#/linq.

It seams to take the best of Python while still being typed like F#.. (intellisense is bliss for anybody who has to learn 1000 of UI framework because the market doesn’t stay in place for long.

of course clojure is interesting and i’m sure i could live with it but the thousands of parantheses make it kinda sad to read in a similar way that F# |> pipe caracters are not very fun to read hehe and type.. (i use a shortcut to add the pipe in one stroke hihi but still i personally like object.method(1,2) way of calling methods like in C#,Scala,Java..

I noted that in scala I could remap my keyboard to enter keywords like “=>” and “<=" and special caracters like "[" or "(" without using key combination with single stroke. Even "def" could be mapped to a key

That's awesome in my opinion. This means you can really stream line code and less special caracters is easier to read and type in my opinion.

Also using space caracters to much like F# and clojure etc.. i don't really like

It's all about the feel of the code and it's very easy to see that Scala has the best feel. Is it supported by a good framework (that i will have to see) )

I also like the fact that's method parameters are typed for readability. I understand that it's faster to type when the type is not there but it's totally unreadable from the reader standpoint. HE has to infer the i/o types from the method that he didn't even read yet.. and what about fast reading of polymorphism where parameter types is needed to really understand the overloading..

Anyway… I actually wanted to go the F# way from C# but now Scala is my fail safe… If it can be supported to the max by the community I hope… I actually think Google with android and is dorak VM (JVM) will take Scala to be the best language for their SDK. Right now it's java but it will not take long for google CEO to see that they have a way to take the programming market just by pushing Scala on android. It would need a lot of Scala / android docs and it would win me away from C# .net for real now that microsoft are pushing Html5/js a little to much for me.

It's funny that scala is not that much appreciated in the java world. hehe
In 10 hours of early love, i can already see 1000000 reasons why it's better in all aspect..

It's not for nothing that in .net they decided to upgrade the languages constructs… so now it's c# 5 and always taking ideas for F# hehehe on the way…

it's still totally verbose but it gives you a lot of way to deal with common programming solutions that need to be implemented like async (c#5), query/list manipulation (linq), dynamic, lambda), parallel (PLINQ, TPL) etc…..

anyway let me know what you think about all those programming languages.. I'm starting to see that it's important to learn the best new multiparadigm languages like F# and scala, Clojure etc..

As a long time Java developer, when considering my next programming language, I cannot ignore the verbosity of Java in terms of both its syntax and the end solution (in terms of bolt-ons e.g. AOP etc.) If I remaining with Java it becomes very compelling to look “over the fence” at the newer, ever more popular dynamic langs and their jvm equivalents. They have ever growing communities and offer some attractive features even just taking brevity into account! So, leaving Scala out of this for the moment, I think lots of seasoned Java devs, like me, have been watching with interest the newer flavors gaining ground. After all I chose Java and JEE for the right reasons over a decade ago and tried to leave emotion out of it. So trying not to fall for the “Commitment and Consistency” blinkers and trying to be unemotional about it I think that there are very appealing alternative options available in terms of productivity.

So, taking this openness to best, available tech solutions into account, if I find the brevity of some of these dynamic langs appealing why would I NOT then logically consider Scala, which offers a lot of the cool syntax brevity and sugar of these other langs but also offers all the Strong Typing, OOP and FP that I might want to stick with?

I think this is a no brainer! To remain rigid to Java as a lang with your hands over your ears seems a bit paternal. The lan space is improving all the time and there are very attractive alternatives coming on stream that make you as a dev resource even more productive. That you cannot deny. So why not improve with the times and chose what seems to offer the most AT THIS POINT IN TIME.

The newbie developer argument is ridiculous! Junior dev resources ALWAYS come on stream with vastly different degrees of ability and always will. As always it is up to companies to find those that are capable of dealing with the technologies that each company has in it’s war chest. Scala is no more difficult for the same junior dev than learning OOP concpets or JEE. These are hard concepts to really grasp when you have no background in programming. I remember trying to teach senior C++ devs in my old company about JEE and then IOC/DI and they were all sitting with blank faces just staring at me. The people with aptitudes for it will get it in the end. But don’t start off by telling them that this or that is incredibly complex even before they start learning it!

Exactly. Most of the things these “Scala is too complex”-people get angry about are obvious fixes to the language. They live in their perfect Java world and get angry if you take the Java-isms away from them.

Those people should read “Java Puzzlers” and then go through Scala and check if the described corner cases also apply to Scala (hint: 90% do not).

Scala frees you from some unnecessary complexity but it certainly adds a whole lot of its own. Deconstructors for pattern matching, the generic type system, mixing implicits with the above, the non regularity of its chained syntax (flatMap) compared to simpler languages such as Fantom, etc… The list goes on and on.

Seriously, just read the Scala mailing list for a few days, there is at least one snippet of code posted there every day that will make you think that we weren’t in too bad a shape with C++.

A fair amount of the Java complexity is unnecessary. Your domain objects don’t need equals and hashCode, in this case. Additionally, idiomatic Java wouldn’t implement mkString or partition. Instead, in idiomatic Java those loops would be coded by hand, repeatedly, every time needed, because abstracting over them is a large amount of work for a small amount of payoff.

The verbosity of Java is bad enough that it doesn’t need embellishing.

And What, James? My point was in response to a previous post. If considering use of Scala for future projects (as opposed to say Groovy as was mentioned by previous commenter) I think it’s valuable to know that one of the major contributors to that lang is on record as saying they would in retrospect choose Scala now and if Scala had been available at the time they’d have not felt any need to create Groovy. I think this adds to the discussion, no?

First of all get rid of all the string building stuff (you ARE using default scala functionality for strings), and tighten up your code. No need to equals or hash – as there is no explicit comparisons:

Sure this works. However my point was to provide Java code which is semantically as close as possible to the Scala code. That’s why there are equals, hashCode et. all. Also removing type annotations as you did makes a big difference. My compiler catches type errors, you need to write unit tests for those. More over your (and my) Java implementation of partition is ad-hoc: it only works for Persons, only on their age and only for the hard coded pivot of 18. Making this as generic as in Scala would probably require another dozen or so lines of code.

I have something to add, which may echo previous comments (sorry if I read through the comments too quickly). There /is/ a complaint against Scala that a lot of Java users have. But clearly “complex” is misrepresenting that complaint. That argument is clearly not working (Odersky’s response post has reduced the discussion to a semantic debate about the meaning of “complexity”).

I think the complaint is better phrased as “Scala is large.” It really doesn’t take that long to understand a language like Java, and this was especially true of Java prior to 1.5. It’s not that Java doesn’t offer opportunity for deep knowledge, but this understanding can often be classified as “low-level” or “corner case.” For core features, Java can be a relatively short study.

Add to this the fact that there’s been an explosion of popularity of dynamic languages. Without static type-checking, these languages often have less to learn as well (some in degrees to others). For instance, I learned Python’s core features from the on-line Python tutorial on python.org. Of course, it’s not complete, but it’s broad enough.

And this is where I think the real complaint with Scala is. There are a /lot/ of different types of functionality; so much so that “core” Scala is hard to define. And to this point, I think there should be almost no disagreement. I wish Scala designers had obsessed over some features a little less. For instance, the rules for understanding the difference between private[this] and protected[this] are tedious, and in all honesty, I think the pay-off for such fine-grained hiding is weak.

Which gets to what I think is the natural response: stop trying to learn Scala completely in one pass; start with the Java-like stuff and build your learning out from there. Venkat Subramaniam’s Scala book seems to have this as it’s thesis.

But this response is unsatisfactory by what I see as two camps — the hesitant and the snooty.

One one side, users are really accustomed to picking up languages quickly. They are scared from all the horrible implementations a naive understanding of a language can lead to. Fortunately, there’s some comfort here with Scala. Naive Scala is actually everything you have in Java. . . plus a bit more. The “Java++” moniker for Scala is not much of a fallacy since Scala’s features really do subsume Java’s.

There are, though, some snooty people that are opposed to Scala as just a Java++. It seems to frustrate them to see all of this great work poured into Scala’s type theory just languish. For instance, if we stay away from implicits, then we’re basically saying “I don’t care about type classes; inheritance seems better” and that can lead to a design tension. But these snooty people aren’t in any huddled majority. They’re just scattered about.

The real problem in my eyes is that Oracle really needs to be backing this work — not EPFL. Java’s success is not from technical merits alone. If technical merits sufficed, Scala would really be in a strong running to replace Java and we wouldn’t have sad April Fools posts on InfoQ titled “The End of an Era: Scala Community Arrives, Java Deprecated.” The research really needs more ties to corporate backing. But even that’s not a guarantee of success. For instance, F# has good support from Microsoft, but I’m not sure adoption is much more than that of Scala.

Fortunately, I don’t have a horse in this race. I’m happy to learn Scala, just to learn.

Another thought; the example I posted is equivalent semantically to the scala code – a list of structurally equatable product types being partitioned. Yet, they are not conceptually the same – tuples vs. classes – which leads me to my point.

I am no fan of Java and my JVM language of choice is Scala but to be fair your comparison is over pedantic, better to compare concepts to concepts. No Java programmer would do the hashing for example. Better is to write the idiomatically identical code and then compare and contrast the shortcomings of both e.g. pivot is hardcoded in Java.

I am an adherent to the lambda school and Category theory initiate but I simply think this example is just not fair and is overly biased. It will only serve to push away those you were trying to reach into.

I’m sure you realise that this will not sway the “complex” crowd. What you are witnessing is a cognitive effect, not a cogent argument. “Complex” is used as a euphemism for “I don’t understand” and supplies an excuse to maintain the position — it’s a self-deceiving tool of the anti-intellectual.

You may argue the need to harden up a little bit, accept that one does not understand, then expend the effort to come to understand. This is likely to be met with haste.

I think the example can be best described as certain problems can be succinctly handled in Scala w.r.t Java without too much boiler plate code. Without going through any Scala doc and just by going through the sample i could clearly tell what the program’s output would be and am sure anyone would be able to do so too.

However would Scala be able to handle any problem in such an elegant way, if so the language constructs even if it’s not user friendly can definitely be handled in a better way rather than writing too much code and introducing complexities.

Found the compiling step to be quite laborious, took quite a long time, any idea if it can be improved?

Excuse me for offtopic, but here the question arises:
Why such language as Scala (*listing all the best scala features) still have no stable IDE? Is it so complex to write convenient plugin for say Eclipse in Scala?

I been trying to move some projects from Java to Scala. I always fail. Not because the complexity or the new features, but because the IDE never works. Even if I am willing to take the complexness of the new semantic, I am not willing to code a big project using just a regular editor. I think that Scala could have a lot more fans if pay more attention to the simpler features (like the IDE). I agree with Aleksey

How is your Scala example better than Somelauw’s Java example.
You deliberately made your Java example to be too long to prove your point which is now pointless. This is a cheap way to sell a language.

Actually it’s the other way round: to make my Java version equivalent to the Scala version it would get even longer as it is already. The Java code is for example missing proper equality and parametrizable partitioning.

a ref class can only inherit from a ref class or interface class – C++/CLI…

A c++/cli class can’t inherit from a traditional c++ class, if you do, you will get an error like: a ref class can only inherit from a ref class or interface class To proceed, you can create the native c++ as a member variable, and forward the ca…

It never ceases to amaze me how passionately programmers will defend one language over another. I never truely saw the point in that. I was fortunate to have learned CS where the changing of programming styles every few weeks was the norm. We did not get the chance to learn the languages as much as the styles (imperative, functional, oo). While most students struggled and failed with functional languages, I felt that it just came naturally to me. I avoided imperative languages forever and adopted oo languages after realizing that functional languages were not going to be adopted by the guys doing the hiring. I am thrilled that functional programming is being rediscovered. It saddens me that so many programmers rely on finding answers on the internet and cut and paste has replaced much of that knowledge that once made us proud to call ourselves programmers. Lisp was my first language. There is not that much that is new in these new languages and I do not believe that functional programming will be adopted by the average joe programmer. But I do know the thing that separates good programmers from average ones is their attitude towards complexity and their attention to things like readability, maintainability, testability and how to decompose complexity so that it is expressed in a simple way. I think we should perhaps be asking how do we teach the next generation those programming styles that handle concurrency and distributed programming best. And how do we do that as simply as possible?