Hacker News new | past | comments | ask | show | jobs | submit login
Why Java folks should look forward to Scala (dhananjaynene.com)
88 points by fogus on May 31, 2011 | hide | past | favorite | 33 comments



Java programmers who are looking for "a better Java" would probably be happier with C# than they would be with Scala, although C# doesn't run on the JVM. The "Manifest" mechanism undoes some but not all of the damage done by type erasure in the JVM, so to some extent building a more richly typed language on the JVM is like driving a car with a broken window.

My first Scala program rolled off my fingers and worked the first time. My second one ran headlong into a number of difficulties; people pointed out that the newest version of Scala added some things (not in the book I had) that would make things easier and they were right... sorta.

Now I've been doing fit-and-finish work on a mixed Scala-Java system written by people with PhD's in computer science and personally I think they'd have been better off writing the whole thing in Java.


I can definitely relate to that. I was in a discussion a while ago with 2 friends, and I was "the Java guy". After that chat, I decided to go back to C# and give it a second chance, despite my Microsoft allergy ;)

It is clearly a better designed language, which of course "borrowed" a lot (90%?) from Java - and then improved it.


More to the point, Microsoft is continuously improving C#

I was at a conference back in 1997 where we came up with a wish list of features we'd like in Java for high performance computing. We all knew it was useless to ask this from Sun, but we did anyway.

The first version of C# had everything we asked for in it, and even early versions of C# had a 'delegate' mechanism that was, more or less, method pointers.

C# 3.0 introduced support for functional programming; it's certainly not like CaML, but there's a reasonably fluent syntax for real closures -- with a little work in adding syntactic sugar it's not bad.

LINQ is amazing and people have barely scratched the surface of what's possible like it. There's a system for manipulating "Expression Trees" that lets you do LISP-style metaprogramming.

C# 4.0 added covariant and contravariant inheritance for generics and, unlike JVM-based languages, it works the way it is supposed to without any lame workarounds.

Comparing C# to Java as a ~language~ is like comparing modern italian to ancient latin. Changes happen in Java at a glacial rate after a tortuous process that ensures that when JDK 7 hits the streets it's going to be four years obsolete.

That said, the Java platform has an incredible ecosystem around it; using maven gives me the feeling I'm in Manhattan and can plug into an infinite library of amazing stuff.

The .NET ecosystem, on the other hand, feels like being a crossroads town in the middle of Iowa. Occasionally you get something good like NUnit, but open source offerings are anemic or absent, and commercial libraries often come across like ads in the SkyMall catalog. (Often you can implement the 5% of the library you need yourself in the time you'd spent talking to salespeople)


comparing modern italian to ancient latin.

Offtopic but interesting tangent: that's comparing declined languages ( with nominative, accusative, dative etc cases) to languages that use prepositions and other particles instead. Kind of like comparing static type languages vs. clojure and erlang.


Latin has prepositions as well, although I see your point. I've made the same case before that Latin is a statically typed human language whereas most of English grammar depends on "runtime" information.


I knew I felt some unease with Scala's abbreviated lambda syntax, but couldn't pin down what it was that bothered me. Seeing these examples clarified it:

    def apply() = l map (_())

    println (users filter (_.age < 18))

    def addOneToAll(a: Int, b: Int) = (a + 1, b + 1)
The first two uses of () are anonymous functions, the last is a tuple. The only way to tell them apart, best I can tell, is the use of _ turns the scope of the surrounding parens into a lambda.

Clojure uses the reader macro #() to indicate an anonymous function.

    #(< (.age %) 18)
For me, at least, having a visual clue to distinguish between abbreviated lambda syntax and other kinds of expressions (tuples in the case of Scala) greatly improves code readability.


> The first two uses of () are anonymous functions

No they're not. They are just containers for arguments to a function. In Scala whenever you call a function which takes as it's only parameter another function, you can even replace them entirely with curly brackets:

    scala> (1 to 5).map(_ * 5)
    res1: scala.collection.immutable.IndexedSeq[Int] = Vector(5, 10, 15, 20, 25)
is equivalent to:

    scala> 1 to 5 map { _ * 5 }
    res3: scala.collection.immutable.IndexedSeq[Int] = Vector(5, 10, 15, 20, 25)

The _ symbol is equivalent to the % in your Clojure example. So both examples above are equivalent to:

    scala> (1 to 5).map((x:Int) => x * 5)
    res2: scala.collection.immutable.IndexedSeq[Int] = Vector(5, 10, 15, 20, 25)



You don't need _any_ characters or visual indicators to declare an anonymous function. Example:

    scala> def apply(op: Int => Int, y: Int) = op(y)
    apply: (op: (Int) => Int, y: Int)Int
Can then be called as:

    scala> apply(_ * 10, 10)
    res4: Int = 100
Or:

    scala> apply((x:Int) => x * 10, 10)
    res5: Int = 100
Or even:

    scala> apply((_ * 10), 10)
    res6: Int = 100
Perhaps your original point stands that in Clojure you have _better_ visual clues for picking out anonymous functions at a glance, but I disagree that you even need them in the Scala code you posted.


"Perhaps your original point stands that in Clojure you have _better_ visual clues for picking out anonymous functions at a glance"

Yes, this is what I was trying to get at. Thanks for clarifying the examples, though. So, using _ in any expression makes that expression an anonymous function? Is _ by itself the identity function?


> So, using _ in any expression makes that expression an anonymous function?

Ah, I should have said - the syntax above only works with one-liners. The following wouldn't work:

    scala> apply(val y = _ * 50; y * 100, 10)
    scala> apply((val y = _ * 50; y * 100), 10)
    scala> apply((x: Int) => val y = x * 50; y * 100, 10)
etc.

Instead you would need to explicitly surround the method body with curly brackets:

    scala> apply((x:Int) => { val y = x * 20; y }, 10)
    res18: Int = 200

And in this case, it's obvious what is happening.

So it's more like providing a one line expression where a function is expected makes it an anonymous function. The use of _ is simply a shortcut when you don't need to assign parameters to a local variable. It even works with multiple parameters. I.e. compare:

    scala> (1 to 5).foldLeft(0)((accumulator:Int,x:Int) => accumulator + x)
    res22: Int = 15
To:

    scala> (1 to 5).foldLeft(0)(_ + _)
    res19: Int = 15


In Scala the _ is the anaphoric it, not necessarily a lambda form (although Scala does the lambda inference based on it). That is, _ serves the same general role as Clojure's % in these examples.


Scala has a lot of utility and I hope that people don't completely discount the platform entirely just because of these examples. Hopefully in time as the platform matures we'll see a better solution to the above.


" Hopefully in time as the platform matures we'll see a better solution to the above."

The problem is that then you'll have both the old way and the new way, which will be even more confusing to read and keep straight.


I agree with you totally. Maybe in that case you could depreciate the 'older' methods in time.


Yah, scala uses "_" a lot:

http://www.slideshare.net/normation/scala-dreaded

The visual clue is the method/function signature which you get from the REPL or IDEA scala plugin. I think F#, O'Caml and haskell programmers rely on these heavily also

(There is talk of deprecating one "_" usage)

http://groups.google.com/group/scala-language/browse_frm/thr...


Those myriad different meanings of "_" depending on context is positively Perl-like.

Seems like a good Scala style guide would ban the use of it altogether, or just white list a couple of uses.

Are both {} and () equally valid delimiters for scoping an anonymous function? If so, always using {} would help to avoid confusion with tuples.

{ _ + _ } as a function taking two arguments seems just wrong to me. Shouldn't it be { _1 + _2 }?


When I was just starting to play with Scala 5 years ago, I found a lot of stuff that's "cool/neat/tight/convenient", I've since watched the language grow into a monster that's trying too hard to be Java++. The xml embedding syntax that looked neat initially looks like an anachronism now.

The result is a Java++ that's worse than C++. It slows down compilation 10x and makes proper tooling (IDE support) 10x hard, while providing no performance advantages. In C++, you can often get nice abstraction idioms (mostly due to template (partial) specialization, SFINAE) with zero performance penalty.

Java folks should just enjoy the superb IDEs (not just 1 but 3) and look forward to Java 8 or something like that (pending the Oracle issues), which will have a reasonable closure implementation ((JSR-335 looks OK to me), which would make much of the user (vs library/framework writer) side verbosity go away.

People use Java because its stability, compatibility and ecosystem, so C# wouldn't be a viable choice for them but an interesting thing to watch and learn lessons from.


There is no doubt in my mind that if Java had added just a few features of these languages we wouldn't be having this discussion. My MVP would be lambdas, type inference, properties and extension methods and that would probably have been enough to make explorations outside of Java mere curiosities. In the mean time, I'll keep helping out on JDK8 to get 2/4 in there.


Gosu has lambdas, type inference, properties and extension methods: http://gosu-lang.org

It's a Java-compatible JVM language that doesn't change stuff up too much, just addresses some shortcomings of Java.


Gosu, Ceylon ann Fantom all have really nice designs, from what little I've seen of them. I think the big corporate backer (Red Hat) makes a big difference.


These languages are all pretty well designed but without tool support they can't really hold a candle to Java for those developers that want strong IDEs. Scala and Groovy are pretty well supported but still far behind Java on this mark.


100% agreement, which is why we, the Gosu guys, are working feverishly on IDE support.


Scala is great. Everything I've used of it says that it really is a better Java.

However, it is also incredibly confusing to learn/use at times because it is still maturing and such. The tooling isn't as good as Java.

The web frameworks for Scala are actually both awful and awesome. Lift is beautiful, but designed by a nerd and won't ever get Rails-like traction. Play is fantastic, but it's just as fantastic for Java, so it almost negates the desire for Scala... almost.

Ultimately, Scala is a breath of fresh air largely because most of modern Java focuses so heavily on Java EE. Scala provides a clean break from that (if that is what you're looking for).

Scala is going to be a niche JVM language. It will never reach the usage levels of Java/C#. It might hit Groovy levels of usage, maybe. I doubt it will ever be as big of a hit as Ruby/Python.


If Java is a tool that provides the functionality needed for a particular developer, why investigate a new language? Seriously? It isn't just a case of the developer and the language features that matter to a commercial business, there are the IT folks running the thing, their familiarity with the tools, the logging facilities, etc.

Tools are great and learning new ones is a good thing. But articles like "X should look forward to/embrace Y" are short sighted unless they take into account the simple fact -- what is the end goal. If it is shipping product, the whole team needs to be on board from design, implementation, running, and maintenance.


C# isn't a realistic option for a lot of people with big investments in the JVM. It is clearly an interesting language, but, it's no F#.

Obviously there are no silver bullets that make software development easy. But after having written a handful of high performance, high availability systems in Scala, the benefits over the other alternatives on the JVM are so evident to me, it's easy for me to get frustrated that they aren't obvious to everyone. Of course we still have occasional bugs, and sometimes they are hard to diagnose. Just exactly like Java, and any other language you care to choose. Bugs are inevitable. But there are a couple of things that make Scala stand out, and I'm a bit surprised at how fickle the community is about this language. One day everybody loves it, the next day, everybody seems to hate it because it didn't make programming easy. Both are extreme; as engineers and scientists we should approach cautiously and methodically; doing so, in my view, makes a few truths unescapable:

1. Scala is far less code than any statically typed language on the JVM. Less code means fewer bugs.

2. The Scala collection framework is a tour de force. If you can't see that, you should keep looking. Seriously, it is quite simply amazing for anyone coming from Java -- there is nothing like it. Not since I first got a taste of STL have I enjoyed the hybrid sensation of aesthetic awe with the 120M volts of power. It is just so clean, so orthogonal, and such a pleasure to work with. It is hard to go back after you have gotten used to this thing.

3. Scalacheck takes testing to another level. When I take the care to properly use a tool like Scalacheck to cover what I'm working on, the number of bugs goes as low as I've seen on any platform, anywhere. I have live code which I am pretty damn sure doesn't have any bugs. The only code I've written in 20 years of doing this that doesn't have any "not critical enough to fix" bugs, is written in Scala. I cannot tell you how satisfied that makes me feel -- it's a long time since I considered that possible.

It is difficult to argue against the idea that there are too many ways to do things in Scala. There is more than one way to do a lot of things, and I personally find the right way for me to be fairly evident after writing a few thousand lines of code. As an engineer, I'm all for constraints to make my job easier. But at the same time, since writing code is a very indirect way to express ideas, it can be nice to have an expressive, fastidiously symmetric, means to do so. The symmetry in Scala is breathtaking ... the edge cases in Scala are an order of magnitude less bizarre than the edge cases in Java. After a few months of Scala, the pathological examples touted in these comments look completely obvious. They are doing a powerful thing. Learning to think in the language is required if you want to be fluent. And what I love about learning to think in Scala, is the extremely intelligent hand of its creator is evident everywhere.


"It is difficult to argue against the idea that there are too many ways to do things in Scala. There is more than one way to do a lot of things, and I personally find the right way for me to be fairly evident after writing a few thousand lines of code."

And that is the problem. Most people will never reach the state of having writing a few thousand lines of code, because they are to confused to begin with.

In my mind, consistency is a prerequisite to a short learning curve. How can it be short if what you have learned in the past is constantly questioned along the way?

When the experts provide multiple ways of achieving the same thing, they force the act of making the choice upon everyone, which is a huge barrier for beginners. Scala could attract a lot more beginners, if it didnt make them think about choices at every step of the way.


The people who actually manage to write a few thousands lines of Scala (and end up happy), are great people to code with (or hire) in my experience.

It's easier to better engineer complicated things in simple ways when you are less encumbered by non-essential complexity. Once you surmount the learning curve, Scala brings a lot. If you can't or won't put enough in to make it, well, sure, it won't be for you. Personally I like solving problems that are hard enough to benefit from Scala's expressiveness. But I completely concede that for lots of people, there's just no reason not to keep on doing Java. Or Cobol for that matter.


I agree, I just gave reasons what in my mind prevents others to follow the same path.


The original article he's responding to mentions true generics (i.e. runtime supported). Despite all of Scala's great features, it still compiles down to Java bytecode and lacks these features that are available in the CLR. The "glacial rate" (as someone else put it) at which the Java language and runtime progresses is a major turn-off for people who want to move to the Java platform from C#/CLR or other platforms where these features already exist. Edit: and with Oracle at the helm now, it's even more of a turn-off...


I still can't believe how many people are unaware of C#. Coming from a java background, C# is a far better route than Scala.

The Scala syntax, I must say is not as readable: def apply() = l map (_())


That is only one way of writing that snippet. Another would be:

    def apply() = l.map((f) => f())
Is that more clear?


This actually is one of my frustrations with Scala, too many right ways to do the same thing. Makes it easier to write but harder to read especially when people have drastically differing styles. One of the advantages of Java is how easy it is to read and use someone else's code since the base language is so limited.


Exactly. I thought perl (and c++) demonstrated that TMTOWTDI is a misfeature pretty convincingly, but I guess some people weren't paying attention.


Same here, i love the "There should be one and only one obvious way of doing things"-paradigm of Python. Scala is in my mind the complete opposite to that.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: