The 10 Most Annoying Things Coming Back to Java After Some Days of Scala

So, I’m experimenting with Scala because I want to write a parser, and the Scala Parsers API seems like a really good fit. After all, I can implement the parser in Scala and wrap it behind a Java interface, so apart from an additional runtime dependency, there shouldn’t be any interoperability issues. After a few days of getting really really used to the awesomeness of Scala syntax, here are the top 10 things I’m missing the most when going back to writing Java:

1. Multiline strings

That is my personal favourite, and a really awesome feature that should be in any language. Even PHP has it: Multiline strings. As easy as writing:

println ("""Dear reader,

If we had this feature in Java,
wouldn't that be great?

Yours Sincerely,
Lukas""")

Where is this useful? With SQL, of course! Here’s how you can run a plain SQL statement with jOOQ and Scala:

println(
  DSL.using(configuration)
     .fetch("""
            SELECT a.first_name, a.last_name, b.title
            FROM author a
            JOIN book b ON a.id = b.author_id
            ORDER BY a.id, b.id
            """)
)

And this isn’t only good for static strings. With string interpolation, you can easily inject variables into such strings:

val predicate =
  if (someCondition)
    "AND a.id = 1"
  else
    ""

println(
  DSL.using(configuration)
      // Observe this little "s"
     .fetch(s"""
            SELECT a.first_name, a.last_name, b.title
            FROM author a
            JOIN book b ON a.id = b.author_id
            -- This predicate is the referencing the
            -- above Scala local variable. Neat!
            WHERE 1 = 1 $predicate
            ORDER BY a.id, b.id
            """)
)

That’s pretty awesome, isn’t it? For SQL, there is a lot of potential in Scala. jOOQ: The Best Way to Write SQL in Scala

2. Semicolons

I sincerely haven’t missed them one bit. The way I structure code (and probably the way most people structure code), Scala seems not to need semicolons at all. In JavaScript, I wouldn’t say the same thing. The interpreted and non-typesafe nature of JavaScript seems to indicate that leaving away optional syntax elements is a guarantee to shoot yourself in the foot. But not with Scala.

val a = thisIs.soMuchBetter()
val b = no.semiColons()
val c = at.theEndOfALine()

This is probably due to Scala’s type safety, which would make the compiler complain in one of those rare ambiguous situations, but that’s just an educated guess.

3. Parentheses

This is a minefield and leaving away parentheses seems dangerous in many cases. In fact, you can also leave away the dots when calling a method:

myObject method myArgument

Because of the amount of ambiguities this can generate, especially when chaining more method calls, I think that this technique should be best avoided. But in some situations, it’s just convenient to “forget” about the parens. E.g.

val s = myObject.toString

4. Type inference

This one is really annoying in Java, and it seems that many other languages have gotten it right, in the meantime. Java only has limited type inference capabilities, and things aren’t as bright as they could be. In Scala, I could simply write

val s = myObject.toString

… and not care about the fact that s is of type String. Sometimes, but only sometimes I like to explicitly specify the type of my reference. In that case, I can still do it:

val s : String = myObject.toString

5. Case classes

I think I’d fancy writing another POJO with 40 attributes, constructors, getters, setters, equals, hashCode, and toString

— Said no one. Ever
Scala has case classes. Simple immutable pojos written in one-liners. Take the Person case class for instance:

case class Person(firstName: String, lastName: String)

I do have to write down the attributes once, agreed. But everything else should be automatic. And how do you create an instance of such a case class? Easily, you don’t even need the new operator (in fact, it completely escapes my imagination why new is really needed in the first place):

Person("George", "Orwell")

That’s it. What else do you want to write to be Enterprise-compliant? Side-note OK, some people will now argue to use project lombok. Annotation-based code generation is nonsense and should be best avoided. In fact, many annotations in the Java ecosystem are simple proof of the fact that the Java language is – and will forever be – very limited in its evolution capabilities. Take @Override for instance. This should be a keyword, not an annotation. You may think it’s a cosmetic difference, but I say that Scala has proven that annotations are pretty much always the wrong tool. Or have you seen heavily annotated Scala code, recently?

6. Methods (functions!) everywhere

This one is really one of the most useful features in any language, in my opinion. Why do we always have to link a method to a specific class? Why can’t we simply have methods in any scope level? Because we can, with Scala:

// "Top-level", i.e. associated with the package
def m1(i : Int) = i + 1

object Test {

    // "Static" method in the Test instance
    def m2(i : Int) = i + 2
    
    def main(args: Array[String]): Unit = {

        // Local method in the main method
        def m3(i : Int) = i + 3
        
        println(m1(1))
        println(m2(1))
        println(m3(1))
    }
}


Right? Why shouldn’t I be able to define a local method in another method? I can do that with classes in Java:

public void method() {
    class LocalClass {}

    System.out.println(new LocalClass());
}

A local class is an inner class that is local to a method. This is hardly ever useful, but what would be really useful is are local methods. These are also supported in JavaScript or Ceylon, by the way.

7. The REPL

Because of various language features (such as 6. Methods everywhere), Scala is a language that can easily run in a REPL. This is awesome for testing out a small algorithm or concept outside of the scope of your application. In Java, we usually tend to do this:

public class SomeRandomClass {

    // [...]
  
    public static void main(String[] args) {
        System.out.println(SomeOtherClass.testMethod());
    }

    // [...]
}

In Scala, I would’ve just written this in the REPL:

println(SomeOtherClass.testMethod)

Notice also the always available println method. Pure gold in terms of efficient debugging.

8. Arrays are NOT (that much of) a special case

In Java, apart from primitive types, there are also those weird things we call arrays. Arrays originate from an entirely separate universe, where we have to remember quirky rules originating from the ages of Capt Kirk (or so) array Yes, rules like:

// Compiles but fails at runtime
Object[] arrrrr = new String[1];
arrrrr[0] = new Object();

// This works
Object[] arrrr2 = new Integer[1];
arrrr2[0] = 1; // Autoboxing

// This doesn't work
Object[] arrrr3 = new int[];

// This works
Object[] arr4[] = new Object[1][];

// So does this (initialisation):
Object[][] arr5 = { { } };

// Or this (puzzle: Why does it work?):
Object[][] arr6 = { { new int[1] } };

// But this doesn't work (assignment)
arr5 = { { } };

Yes, the list could go on. With Scala, arrays are less of a special case, syntactically speaking:

val a = new Array[String](3);
a(0) = "A"
a(1) = "B"
a(2) = "C"
a.map(v => v + ":")

// output Array(A:, B:, C:)

As you can see, arrays behave much like other collections including all the useful methods that can be used on them.

9. Symbolic method names

Now, this topic is one that is more controversial, as it reminds us of the perils of operator overloading. But every once in a while, we’d wish to have something similar. Something that allows us to write

val x = BigDecimal(3);
val y = BigDecimal(4);
val z = x * y

Very intuitively, the value of z should be BigDecimal(12). That cannot be too hard, can it? I don’t care if the implementation of * is really a method called multiply() or whatever. When writing down the method, I’d like to use what looks like a very common operator for multiplication. By the way, I’d also like to do that with SQL. Here’s an example:

select ( 
  AUTHOR.FIRST_NAME || " " || AUTHOR.LAST_NAME,
  AUTHOR.AGE - 10
)
from AUTHOR
where AUTHOR.ID > 10
fetch

Doesn’t that make sense? We know that || means concat (in some databases). We know what the meaning of - (minus) and > (greater than) is. Why not just write it? The above is a compiling example of jOOQ in Scala, btw. jOOQ: The Best Way to Write SQL in Scala Attention: Caveat There’s always a flip side to allowing something like operator overloading or symbolic method names. It can (and will be) abused. By libraries as much as by the Scala language itself.

10. Tuples

Being a SQL person, this is again one of the features I miss most in other languages. In SQL, everything is either a TABLE or a ROW. few people actually know that, and few databases actually support this way of thinking. Scala doesn’t have ROW types (which are really records), but at least, there are anonymous tuple types. Think of rows as tuples with named attributes, whereas case classes would be named rows:
  • Tuple: Anonymous type with typed and indexed elements
  • Row: Anonymous type with typed, named, and indexed elements
  • case class: Named type with typed and named elements
In Scala, I can just write:

// A tuple with two values
val t1 = (1, "A")

// A nested tuple
val t2 = (1, "A", (2, "B"))

In Java, a similar thing can be done, but you’ll have to write the library yourself, and you have no language support:

class Tuple2<T1, T2> {
    // Lots of bloat, see missing case classes
}

class Tuple3<T1, T2, T3> {
    // Bloat bloat bloat
}

And then:

// Yikes, no type inference...
Tuple2<Integer, String> t1 = new Tuple2<>(1, "A");

// OK, this will certainly not look nice
Tuple3<Integer, String, Tuple2<Integer, String>> t2 =
    new Tuple3<>(1, "A", new Tuple2<>(2, "B"));

jOOQ makes extensive use of the above technique to bring you SQL’s row value expressions to Java, and surprisingly, in most cases, you can do without the missing type inference as jOOQ is a fluent API where you never really assign values to local variables… An example:

DSL.using(configuration)
   .select(T1.SOME_VALUE)
   .from(T1)
   .where(
      // This ROW constructor is completely type safe
      row(T1.COL1, T1.COL2)
      .in(select(T2.A, T2.B).from(T2))
   )
   .fetch();

Conclusion

This was certainly a pro-Scala and slightly contra-Java article. Don’t get me wrong. By no means, I’d like to migrate entirely to Scala. I think that the Scala language goes way beyond what is reasonable in any useful software. There are lots of little features and gimmicks that seem nice to have, but will inevitably blow up in your face, such as:
  • implicit conversion. This is not only very hard to manage, it also slows down compilation horribly. Besides, it’s probably utterly impossible to implement semantic versioning reasonably using implicit, as it is probably not possible to foresee all possible client code breakage through accidental backwards-incompatibility.
  • local imports seem great at first, but their power quickly makes code unintelligible when people start partially importing or renaming types for a local scope.
  • symbolic method names are most often abused. Take the parser API for instance, which features method names like ^^, ^^^, ^?, or ~!
Nonetheless, I think that the advantages of Scala over Java listed in this article could all be implemented in Java as well:
  • with little risk of breaking backwards-compatibility
  • with (probably) not too big of an effort, JLS-wise
  • with a huge impact on developer productivity
  • with a huge impact on Java’s competitiveness
In any case, Java 9 will be another promising release, with hot topics like value types, declaration-site variance, specialisation (very interesting!) or ClassDynamic With these huge changes, let’s hope there’s also some room for any of the above little improvements, that would add more immediate value to every day work.

49 thoughts on “The 10 Most Annoying Things Coming Back to Java After Some Days of Scala

    1. Could be. I like Kotlin’s flow-sensitive typing. On the other hand, I just wish sometimes that some of those features were implemented directly in the Java Language…

    2. I would agree on Kotlin. But when will JetBrains ever finish it?

      I currently use both Scala and Java 8.

      1. Oh most definitely we will :). We’re using Kotlin heavily now in production (despite not being 1.0) and many companies we know of are also. 1.0 is coming.

        1. Thanks for chiming in. Yeah, looking forward to playing around with that some time! Your talk at JavaZone two weeks ago was quite convincing :-)

          Unfortunately, we didn’t get a chance to talk at PartyOne last night. Would be interesting to learn a bit more about Kotlin

    1. It’s true. I just happen to have no experience with Groovy at all, and I needed to write a parser, which is extremely easy to do with Scala.

  1. Agree with you except that I am pretty comfortable using project lombok for getting a more concise Java (ok, I admit it’s annotation-driven which is not “perfect”, but it works).

    Anyhow, instead of lombok, perhaps you want to give Xtend (http://www.eclipse.org/xtend/) a try?

    1. Yes, Lombok “works”. You can make anything “work”. But I have a very uneasy feeling with annotation-driven code generation. It just feels like the wrong tool is being used for what should be supported in the language itself.

      Yes, I’m using Xtend for source code generation. I have the same feeling there. It works, but the Java/Xtend interface is far from optimal – I’m only using it for very limited use-cases.

      1. Lombok more than just “works”; for me it works perfectly. Moreover, I find it more useful than all the Java 8 goodies together. Really.

        You’re totally right saying that all the stuff should be in Java itself, but this is neither Lombok’s fault nor anything we could change. For people not ready to switch to Groovy/Scala/Whatever, Lombok is a huge win.

  2. Lucas, you write:

    “OK, some people will now argue to use project lombok. Annotation-based code generation is nonsense and should be best avoided.”

    Perhaps.

    I’m somewhat uncomfortable with how lombok works it’s magic, though I think that conceptually the idea of having something like equality defined via annotations is very sound.

    But this next isn’t right at all:

    “In fact, many annotations in the Java ecosystem are simple proof of the fact that the Java language is – and will forever be – very limited in its evolution capabilities. Take @Override for instance. This should be a keyword, not an annotation.”

    I think this is completely backwards. Conceptually, “override” is most certainly an annotation! It’s just an annotation that is built into the language. Same goes for “public”, “final”, etc, etc.

    The huge mistake is that languages like Java and Scala build a special “privileged” list of annotations into the compiler, and relegate user-defined annotations to second-class status and give them an awful syntax “@Override” or worse.

    If *all* annotations were ordinary declarations, like they are in Ceylon, then there would have been no discomfort associated with adding new annotations to the language, and Java would have been able to add a new “override” annotation seamlessly.

    “You may think it’s a cosmetic difference, but I say that Scala has proven that annotations are pretty much always the wrong tool. Or have you seen heavily annotated Scala code, recently?”

    Well, in the immediately preceding code example, there is an annotation: “case”, which does precisely some (but not all) of the stuff that lombok does!

    Sure, sure, it’s one that is built into the Scala compiler and language specification. But that’s a Bad Thing. One day, the Scala guys will discover the need to add a new annotation to the language, and, just like in Java, they won’t be able to add a new keyword to the language, and Scala will be stuck with a new @Wart.

    1. You write “able to add a new keyword to the language”, but this is always easy, assuming you don’t use a too strong notion of backwards compatibility. IMHO there’s no reason for every Java 8 source to be also a valid Java 9 source: As long as the new tools can both *recognize* and *handle* the legacy code, everything’s fine. With something like `package 9 com.example.something` you could make the recognition trivial and then add 10 new keywords and get zero problems (unless upgrading some legacy code, but this is very rarely needed).

      1. In fact, this happened with strictfp, assert, and enum before, and it will probably happen again if a very specific feature is added to the language that cannot be modeled with an existing keyword.

        In any case, I generally agree with you. Java is evolving slowly enough to be able to add 1-2 keywords to the language over time, safely. Also, it should be possible to plan 4-5 years ahead by adding compiler warnings to previous Java versions, about tokens that will eventually be keywords in future language versions.

        1. Yes and no. You’re right, it works, but you’re sticking with the IMHO wrong notion of backwards compatibility. Imagine, Java 9 would need `select` as a keyword. If there was a way to tell apart Java 9 source code from older versions, you could easily use Java <9 sources with methods called `select` and Java 9 sources with `select` used as a keyword. You could also prohibit raw types and other obsolete nonsense in Java 9 without running into any problems. The compiler would simply accept both new and old source files, i.e., parse two slightly different languages (IMHO "javac -source" is non-sense; the version should be detected from the source itself on a per file basis).

          1. That’s actually quite clever. Like a per-compilation-unit JLS dependency. But it probably isn’t that easy, because Java 9 doesn’t just include the corresponding JLS. It also includes the JDK and all the libraries. When I’m running Java-6-compatible code, I’m not only relying on @Override being available to method implementations (from interfaces, which wasn’t possible in Java 5), I’m also going to be relying on methods like String.isEmpty(). In order to implement your idea correctly, n sets of JDK libraries would need to available.

            On the other hand, already today, you can specify the javac version on a per-project / per-module basis in most IDEs and build environments. I suspect that from a mere keywords-compatibility perspective, that ought to be enough…?

          2. There’s no replay button below your post, so I’m replaying to myself.

            The other problems like added or removed methods (`Thread.stop`) are a different problem. That’s about the same problem as choosing a library version, just much simpler, as removals and incompatible changes in JDK are very rare. There are also some incompatibilities on the bytecode level etc., but this is a different problem. My point was to allow more flexibility in the syntax changes (add keywords, drop raw types and other corpses).

            Agreed that specifying the version per project suffices most of the time, but it’s a terrible idea: 1. The Java version is a property of the source file, so you shouldn’t have to re-specify it. 2. It makes upgrading to a new version harder (imagine the `@Overrride` annotation would get dropped in favor of a new shiny `overrride` keyword; you’d have to change all project files at once in order to get the project compile again). 3. It works now, but only because there are no incompatible syntax changes.

            1. There’s no replay button below your post, so I’m replaying to myself.

              Yes, I know. WordPress…

              overrride

              Java Pirate’s Edition? ;-)

              I really think that you’re trying to solve a problem that among all languages on this planet, Java will never have. Java is evolving that slowly… Scala, on the other hand would definitely be able to profit from that. Have you ever suggested your idea to anyone (e.g. the JDK9 mailing lists)?

          3. I’m rather comfortable with Java not using many keywords (unlike SQL) and evolving slowly, but using this idea could allow some syntactical evolution, too. I’ve heard, something like mixed site variance or template specialization should come in the next 100 years and it’d stupid to cripple their syntax by using a stupid notion of backward compatibility.

            I’ve posted the idea to SO somewhere, that’s all.

          4. What you describe, is the way it works. When using “-source 1.4”, you can use “enum” as a method name, when using a newer language level, you can’t. This also implies that if a library author uses that older language level and names a public method “enum”, this method can’t be invoked by code using a newer language level. Same would apply to a Java 9 keyword “select”, it wouldn’t affect code compiled targeting the older language level but how does it help? You’ll have to migrate one day and, as said, when mixing code you still may encounter problems due to the disagreement about valid identifiers.

            And since you say yourself, that you are comfortable with Java not using many keywords, being reluctant about adding new keywords still is the best language evolution strategy.

          5. This also implies that if a library author uses that older language level and names a public method “enum”, this method can’t be invoked by code using a newer language level.

            That’s true, however, it’s no big problem. The probability is pretty low, usually you hit something private. Otherwise, the library has to evolve, deprecate the old name, and add an alias like `enumerate`. Now this library can work with *both* legacy and new code. By marking the library source with it’s version, you can still compile it.

            And since you say yourself, that you are comfortable with Java not using many keywords, being reluctant about adding new keywords still is the best language evolution strategy.

            Sure, but we shouldn’t let the need for a new syntax block the language evolution. And there should be no useless workarounds like
            https://stackoverflow.com/a/4734759/581205
            Just say “this is a version 10” and all syntax compatibility problems are solved.

          6. You’re right, the probability of a name conflict is low, that’s why keywords were eventually added in some versions. But of course, the probability would rise if dozens of new keywords were added in every release.

            However, that’s about keywords. Regarding other syntactical aspects, which do not even touch linkage between classes, I’m absolutely with you. I have no idea why compiling pre-Java 5 code with “-source 1.5” should be supported as “-source 1.4” is exactly supposed to be there for compiling older code which hasn’t been adapted.

            Especially as there *are* corner cases where that doesn’t work. Also, there are more than just a few cases which could be compiled in Java 7 and need adaptation to be compiled with Java 8. If that’s acceptable, why not others?

            That “diamond operator” is a good example. Changing the rule to “new X()” is exactly like “new X()”, if X is generic, is unlikely to break anything, besides code that is obviously wrong. But I don’t think that there is a need for a language level arbitration syntax. My rule would be “as soon as code uses a language construct introduced with Java 5 or newer, legacy mode is off”.

            Because, there is no reason why I need a “” in a line like

            List list=new ArrayList(); // vs new ArrayList()
            

            to tell the compiler that I know Generics and want Generics as the type of the variable already tells that this isn’t pre-Generics code and that using raw types is not intended. Note that this isn’t so far-fetched as a newer syntax construct like ArrayList::new does not require a diamond operator, not even support it.

          7. Oh, the lower-than and greater-than characters are not shown in my previous comment. Hope, it’s possible to infer (scnr) them while reading…

          8. dozens of new keywords

            Would I get banned if I said that it’d make Java to something as terrible as SQL?

            But I don’t think that there is a need for a language level arbitration syntax.

            Sure, there’s no *strict* need as they’re always possible workarounds, but I’d prefer not to have to think about them. Sometimes, there are semantic changes like @Override from Java 5 to 6, which surely had some cost. There’s also the cost of avoiding such problems (“we’d like to fix it, but you know… compatibility).

            OTOH, my package 42 foo.bar idea is dead simple and the IDE would take care of it anyway. Compact, but explicit. With such a declaration, you may introduce breaking changes like e.g. requiring all variables to be non-null, unless declared nullable (e.g., using Kotlin syntax).

            1. Would I get banned if I said that it’d make Java to something as terrible as SQL?

              We don’t censor commenters around here, although I am deeply disappointed by your opinion ;) (there’s actually a blog post coming up about that very topic!)

    2. Hi Gavin,

      just like in Java, they won’t be able to add a new keyword to the language, and Scala will be stuck with a new @Wart.

      I will have to cite that 1-2 times :-)

      Thanks for commenting. I must admit, I have never thought of keywords as being annotations – conceptually – but of course you’re right. Whether users should be able to extend a given language with their own keywords has always been an interesting topic. SQLJ is an example where a whole language is embedded into another one by specifying a syntax that is implemented “on top” of Java. With jOOQ, we’re eventually trying to do a similar thing – our ultimate goal would be to implement what SQLJ should have been from the beginning.

      Nonetheless, annotations have always been a bit limited in what they can model, being synthetic keywords. There is, for instance, no annotation model in any language that I’m aware of to construct a new control flow. So, I don’t think that things like case (of case class) being built in the compiler and language specs is a Bad Thing per se. In this particular case, a keyword was reused in a different context. That’s a trick that language designers often apply (e.g. Java 8’s reuse of default), and I personally prefer that to annotations.

      But you’ve obviuosly given this much more thought than I have. Does Ceylon model its own keywords as annotations, internally? That would indeed be quite clever! – And worthy of a dedicated blog post. If so, do you have some resources to read up on this?

      1. Well we still use keywords where needed to drive the grammar of the language, things like “if”, “for”, “class”, etc. But for stuff annotations like “shared”, “abstract”, “formal”, etc, etc, yes, they’re just annotations, defined in Ceylon, in the language module. This means that we can very easily add new ones without needing to worry about breaking existing source code.

        1. That’s really awesome! Well, this makes a couple of reflection queries much more regular. Instead of having two different APIs for querying annotations or modifiers, there’s only one API, I suspect… I’ll have to experiment with this. And I’ll certainly blog about this, pretty soon.

  3. Languages evolve too slowly. New features must be written in the form of IDE plugins. That way nobody could stop you.

  4. The features you listed are basically a subset of what I consider the “obvious wins” in switching to Scala from Java. They’re mostly just syntactic sugar over common patterns where Scala has the benefit of learning from Java’s mistakes.

    It is possible to write Scala code that’s basically using it as just “a better Java”, and it’s a good place to start for people with a Java background. However, I think people often find that as they start incorporating more and more paradigms from functional programming (and using more of Scala’s features that encourage this style) there are tangible benefits to Scala that aren’t merely cosmetic.

    Certainly neither language is perfect, but for me Scala’s downsides are dramatically lower than Java’s.

    1. They’re mostly just syntactic sugar over common patterns where Scala has the benefit of learning from Java’s mistakes.

      That’s why I listed them. Apart from local functions and type inference, they’re all feasible in the Java language as well, without introducing too many “complex” new ideas, or backwards-incompatibility.

      However, I think people often find that as they start incorporating more and more paradigms from functional programmin

      Yes, yes. When in Rome, do as the Romans do. I really pattern matching, nameless function types and many other language features. But they’re mostly pretty out of reach for any (near) future Java, so I wanted to keep the list simple, with “obvious wins”.

  5. A note on point 3, Parentheses. Leaving out the dots and leaving out parenthesis are separate things. The former is nice for developing DSLs, for regular coding I avoid them too. For the parenthesis there’s a convention: omit them when the method has no side effects. They’re similiar to a property access then and since Scala has a single namespace for fields and methods one can override a field in a subclass with a method and the parenthesis-less access still works. It’s also nicely readable on the caller side: no parenthesis == no side effects. I guess this unification of flieds access and method access comes from the functional mindset that focuses on what the caller wants (get something) rather than how to get it. Admittedly, I didn’t learn that in the first few days ;-)

    1. That’s a nice way of seeing it. Intuitively, I’ve understood it the same way, but I haven’t thought about it from that syntactical point of view

  6. The only ones I disagree with are semicolons and parenthesis. As much as I like Scala it is the one thing that drives me absolutely bonkers. I know I could use them anyway, but it’s “not proper” in terms of writing pure Scala, which I what SHOULD be done.

    My biggest thing right now is the adoption rate of Scala. It’s not that people aren’t using it out there and it’s not that it’s a great language: I’m just not seeing the jobs posted:

    – Java – 87,578 listings (http://www.indeed.com/jobs?q=java&l=)
    – Scala – 4,063 listings (http://www.indeed.com/jobs?q=scala&l=)

    I’m wondering if the evangelism simply is not there within some companies for adoption of Scala. Using the Scala+Akka is definitely a great experience (as is Java+Akka, honestly).

    This is why I keep using BOTH Scala and Java right now and have not switched 100%.

    1. Hey. You’re comparing Scala with the biggest player in the room. Don’t worry about the jobs. OK, you might need to relocate, but then you can earn tons of money. I think.

  7. I just have to point out that the string interpolation example is a SQL injection attack waiting to happen. Please don’t do that.

  8. Well, if go to Scala or come back to Java for the good reasons, there is nothing to complain about, really … it is only if you go back and forth for the bad reasons that you feel frustrated about. Choose the right tool for the problem and you’ll use it happy everly after :) …

    1. Well, we could sell a commercial library to the Scala ecosystem (i.e. the 5 farts that use the language), but that might just not pay the bills would it? :)

  9. #3 seems to address two separate issues: leaving off parentheses because a method takes zero arguments is different from leaving off parentheses (and a preceding period) where there is an argument.

    1. You’re absolutely right. In fact, many other languages (including e.g. PL/SQL) allow for leaving off parentheses on a zero argument method. I suspect that’s a much less risky language feature than the latter.

Leave a Reply to Ishaaq ChandyCancel reply