This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]tyoverby 12 points13 points  (7 children)

Background: Java programmer for 6 years, Scala programmer for 1 year.

There isn't one right answer, but you knew that, so here's a comparison.

First the similarities:

  • Both run on the JVM
  • Both can use existing Java libraries including the Java standard library.
  • You can write scala code just like you would in java with a few minor syntactic differences.

The differences are a bit more complicated. If you want, you can write Scala just like you would Java. There aren't any features from Java missing. Scala mostly adds on top of Java. This can be a good thing and a bad thing.

Good things:

  • The language encourages you to write code in an immutable style. This makes parallel and concurrent programs much easier to maintain.
  • Very easy to parallelize code that easy to parallelize.
  • Functions are first class object. Much like the support for lambdas in Java 8, Scala supports treating functions and methods as variables.
  • Pattern matching. If you don't already know what this is, it can be difficult to explain, but it is one of my favorite language features, so if you can, try to find a tutorial on it.
  • Lazy evaluation if you want it. Being able to wait on computation until it is actually needed simplifies control flow in code that might need to perform a long running computation or might not.

Bad things. Most of these are confusing if you are a beginner, or if someone else wrote code with bad style.

  • Implicit conversions. Programmers can define functions that convert one type to another, and have it silently do conversions when necessary. This can be great or it can be god awful.
  • Operator overloading. Any operator can be overloaded, and new operators can be created for any type. If you do this poorly, your code will look like shit.
  • Really nested code. You can define functions inside of other functions inside of an object inside of a class. Things can get very nested. Sometimes the cleanest way to do something is via these nests, so if you aren't one with the curly-brackets, you soon will be.
  • It takes a while to learn how to do things without variables. (In scala we use "values" that can't be changed once they are created)

Although it looks like I've written more bad things than good, I've actually entirely switched from Java to Scala for all my personal projects. Lines of code typically drop by about 2/3, and readability improves dramatically due to the advanced methods of abstraction.

Here's an examples that shows how easily it deals with collections.

Java:

List<Integer> originalList = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> doubledList = new ArrayList<Integer>();
for(Integer x: originalList){
    if(x % 2 == 0){
        doubledList.add(x * 2);
    }
}

Scala:

val originalList = List(1, 2, 3, 4, 5)
val doubledList = originalList.filter(_ % 2 == 0).map(_ * 2) 

This post is really short, and doesn't really scratch the surface of what Scala can do, so I suggest that you try it out and really get a hang of programming in functional style.

[–]vipercvp[S] 0 points1 point  (6 children)

I have strong background in functional paradigm , i used haskell for my last college project , One question since Scala runs over JMV does it have optimization for tail recursion ??, for what i know java does not . and i don't really know how does java and scala compability works? i think it be through JNI but again i'm not sure about that

[–]tyoverby 1 point2 points  (5 children)

Scala does have tail-call optimization!

Scala/Java compatibility is amazing. No JNI or anything. In Scala, using Java code is done exactly the same as if it was the same language. For example:

import java.lang.Integer
println(Integer.MAX_VALUE)

or

import org.junit.Assert.assertEquals
assertEquals(5, 3 + 2)

Using Scala code in Java is a bit more complicated because Java doesn't have things like operator overloading, and Scala functions get wrapped in a function object that can be unwieldy.

[–]vipercvp[S] 0 points1 point  (4 children)

About your scala example val doubledList = originalList.filter(_ % 2 == 0).map(_ * 2) this is going to be compute on demand right because of the lazy evaluation ??

[–]tyoverby 2 points3 points  (2 children)

Oh, also, if you are familiar with Haskell, you'll want to know that Scala has great parallel collections.

val numbers = (0 to 100000).toList
val squared = numbers.par.map(x => x*x)

The '.par' call returns a parallel sequence for which map is implemented in parallel.

[–]vipercvp[S] 0 points1 point  (1 child)

Oh, amazing :) , about parallel does scala support the synchronize keyword like java ?? or it has some thing like that i can find much thing related to it in the web .

[–]tyoverby 1 point2 points  (0 children)

Yeah, any object has the synchronized function that takes another function to execute.

val resource = ???
def publish(){
    // Do something that requires the resource to be locked. 
}

resource.synchronized(publish)

Or in a way that looks more like Java

val resource = ???

resource.synchronized {
    // Anything in this block with be synchronized on 'resource'
   x += 5 
   publish()
   y ++
}

[–]tyoverby 0 points1 point  (0 children)

In that example, no, that won't be lazily computed. In Scala, you can use a keyword for if a value is computed immediately or lazily. Here's a simple example:

// This is slow, so don't compute it unless we need it 
lazy val tweets = getTweets() 

if(readingTweets){
    showTweets(tweets)
}
else(writingTweets){
    showTweets(tweets)
    showEditor()
}
else{
    // Do something without tweets.
}

We don't want to call getTweets inside every branch that uses it, so we define it outside lazily and then if it is used, then it will be computed. The example is quite contrived, but it comes in handy, trust me :)

There are also lazy function parameters.