Hacker News new | past | comments | ask | show | jobs | submit login

I agree that Java is the best programming language to write web services in right now.

But I have to admit that the most threatening counter-argument to using Java in 2016 is that Scala is, to all appearances, a strictly better language. It's similar to Java and does everything Java does, but better- it has type inference, it does away with primitive types and arrays, it has compiler-checked string interpolation, it has declaration site variance, it has a richer collections library, powerful syntactic sugar, robust mechanisms for dealing with asynchronous programming... I could go on and on. And it's deeply interoperable with Java so it should be a no-brainer to use it wherever possible.

Java's saving grace in my opinion is, ironically given Java's history, its culture. When you find that you need to use a small class from a library, you pray that it's written in Java, because most of the time you can just go to its source in your IDE and see painstakingly detailed Javadoc describing exactly what each public method does and common pitfalls. And Java isn't very expressive so all code looks the same- you just have to understand how the components interact with each other. If, on the other hand, the class is written in Scala, you're vastly more likely to crash into a brick wall of undocumented one-liners that are complicated greatly by uses of the downright tricky bits of Scala's type system. Using typesafe's libraries (akka/akka-stream/slick) is an exercise in poking your code experimentally until it magically compiles, usually due to some random undocumented import. And scala culture's love of DSLs and lifted types is downright hostile to ease of debugging. It's hard to overstate how much of an impact these factors make throughout a workweek.

And yes, lots of Scala code is good and lots of Java code is bad. But I think the stereotype generally holds true.




On the contrary Scala is baroque, its syntax is not following any known pattern. For example if I want to write a recursive function I have to indicate my return parameter type otherwise not. It doesn't matter whether you come from a C background or a Java background...or any background because of this:

> def addInt( a:Int, b:Int ) : Int = {

> var sum:Int = 0

> sum = a + b

> return sum

> }

You have to relearn how a function looks like in the first place. Return types are at the end, parameter types are after the parameter name separated by a colon.

If you want a language which runs on the JVM Clojure is a way better option. You don't have to learn its syntax since there is hardly anything you can call one. It is binary compatible with itself which is not true with Scala, you can choose whether you want a type system or not since it is optional (look at clojure/core.typed). It is also interoperable with java but it has a much better functional approach to programming compared to Scala since everything is immutable but it is not wasteful because of persistent data structures and for concurrency you have the STM which IMHO is a strict upgrade to the Actor model. Writing DSLs with the powerful macros Clojure has is more usable than any non-lisp language and the result is more expressive.

So to add it all up with Scala you add a lot of complexity and a lot of pitfalls you can fall into while with Clojure you take away complexity while retaining the vast Java ecosystem for interoperability. Don't take my word for it but take a look at Uncle Bob's talk "Clojure is the new C" : http://www.infoq.com/presentations/clojure-c


Function declaration syntax where the return type is last is very common in functional languages. It's even allowed in C++11, because it allows one to define return types that depend on parameter types. An example taken from http://en.cppreference.com/w/cpp/language/auto,

  template<class T, class U>
  auto add(T t, U u) -> decltype(t + u) // return type is type of operator+(T, U)
  {
    return t + u;
  }
It's quite a sensible approach, and hardly an impediment to understanding. A more valid concern is that Scala introduces a lot more concepts. I don't necessarily agree with it, but I think it's a potential issue, whereas a simple syntax difference that a lot of languages have is not a big deal.


I agree the syntax is sensible. I quite like it in Swift:

    protocol Numeric {
        func +(lhs: Self, rhs: Self) -> Self
    }

    func<T: Numeric>(a: T, b: T) -> T {
        return a + b
    }


Correction: Function name.

    func add<T: Numeric>(a: T, b: T) -> T {
        return a + b
    }


I see. I was not aware that this kind of syntax was present elsewhere, thanks for pointing it out!


> You have to relearn how a function looks like in the first place. Return types are at the end, parameter types are after the parameter name separated by a colon.

baroque syntax?

Like these:

- https://swift.org/getting-started - https://doc.rust-lang.org/book/functions.html - https://golang.org/doc/effective_go.html#functions - https://kotlinlang.org/docs/reference/functions.html

Sorry but you pretty much say clojure is the best, however it has a lisp syntax, which IS baroque and most people aren't use to this. These days if you want to have a functional style. You eiter use Scala or Kotlin. Clojure is too much of a unicorn. People won't learn this. Also people doesn't care how good the language is or what design patterns were used. People use these languages cause they think the language has a actual value for them (as you think about clojure)


By baroque I mean it is overly complicated. Clojure syntax or LISP syntax for that matter is everything bot overly complicated.

> People won't learn this.

Say that to Uncle Bob or the guys who maintain ClojureScript, Cursive (JetBrains based Clojure IDE) or Om which is a port of React not to mention Apache Storm which was written in Clojure.


Don't get me wrong I still think Clojure has it's place, but saying others are overly complicated when talking about Clojure is somehow awful. Lisp is near dead, without Clojure lisp would only be used to train how to implement parsers, compilers, academic stuff.

Yeah there are a few people who know lisp, you also forgotten about Walmart, which is a lisp user, however the majority of people in functional languages still won't learn Clojure.

But still don't care about, use the tool/language you are familiar with, especially if you could use it in your company. I also see a lot of pressure against scala, and I'm a scala user, but I just don't care.


There are a lot of reasons to hate on Scala and the order of definitions of types in the functions is not a huge one.


Could just write `def add(a: Int, b: Int) = a + b`.

Not sure what the var/return business is about; have you even used Scala?


Types on the end are very common in many languages, a lot more common (and IMO readable) than lisp-style (+ a b) which you have to learn to use clojure.

An optional type system is almost useless (believe me I spent a lot of time trying to use the checker framework in Java before switching to Scala), because libraries don't have to follow it, and you never know whether the type definitions for a given library are true or not.

Scala is generally immutable by default and has persistent data structures.

STM is great but you can do it fine in Scala. It's just not a language-level feature because it doesn't need to be - Scala is expressive enough that you can write an STM implementation in a library.

Scala's DSL support is great (look at e.g. Spray route definitions) and can usually done in ordinary code without macros, which in turn means you have full IDE and tool support for them. The trouble with lisp DSLs is that your syntax still has to look like lisp - the support for e.g. infix operator syntax is quite limited (you have to use reader macros which are more complicated and harder to work with). But for a lot of business domains the natural language of the domain uses infix operators.


> When you find that you need to use a small class from a library, you pray that it's written in Java, because most of the time you can just go to its source in your IDE

I have to say, this is the big plus for Java for me. I find myself in the weird position that while I dislike writing Java, I love reading it. The simplicity and constrained nature of the language, the incredible IDE support, the JVM features (connect to a running VM and start setting breakpoints to answer questions like "when does this method get invoked"), etc. It's hard to escape the logic that if I want people to like reading my code, I ought to be writing it in Java.


You are right: Scala is a wonderful language crushed by its culture. Not only the DSL love.

And then there's the in-language tribalism. You find people that work/worked in Twitter, that tell you that anything that Typesafe, the company that does most of the development of the language, is not worth using: They have their own stack for everything. Then, you have the Scalaz tribe: They also dislike the standard library, along with the Twitter libraries. And now we have TypeLevel, which splinters from the scalaz group. You don't have one camp: you at least have three or four, and having talked to prominent members of each of those subcultures, good luck ever getting them to try to unify anything: There is much intra tribe hate in public, and it gets even nastier when they are in private.

Having worked with people from each tribe at one point or another, I think that the situation is pretty hopeless, and the community knows it. The best way for Scala programmers to bond is to hate on a tribe that neither of them belongs to!

Just look at the two keynotes in Scala exchange 2015: One by Jessica Kerr, the other by Miles Sabin. Two people that come from very different backgrounds, writing very different code (business scala vs shapeless). But what both were talking about was how far the community has to go to make the language more approachable. And yet, I am pretty sure that the code Miles finds approachable, Jess would find completely unapproachable, while Miles might hate on how Jess doesn't really use enough types.

It's a very unfortunate problem.


I'd suggest taking a look at kotlin as well


Kotlin has most of the complexity of Scala, and very little of the power. If you want a clean language that offers Scala-like functionality, Ceylon is the one to watch.


I spent literally one evening reading Kotlin reference and I understood an entire language. It's just a Java with slightly altered syntax and a lot of simple yet useful batteries included. I immediately was able to start coding and reading standard library. On the other side in the past I spent around week reading book about Scala. Yet I couldn't read Scala library, it was just too complex. So I don't agree that their complexities are even comparable.

Scala is like a Haskell. It's very powerfull, but to understand and use the entire language, one should make a serious investment.


That's because Kotlin puts the complexity in the language and Scala puts it in the libraries. A lot of things are just a rule of the language in Kotlin but they're implemented in ordinary code in Scala. E.g. extension methods. Which means you can "understand" them quicker in Kotlin, but you can't change how they work or use them to implement a new structure.


> you can "understand" them quicker in Kotlin, but you can't change how they work or use them to implement a new structure.

I'm not sure that extension methods are a particularly fitting example here.

Scala adds a lot of boilerplate for — in my view — very little gain. Of course, Scala's extension methods are actually a special case for implicit conversions; yet, the Scala we write today in my experience tends to avoid implicit conversions per se.

E.g., I'd rather be explicit about a type conversion when that is what I want to achieve: for instance, I'd rather read `javaListMethod(mySeq.asJava)` than `javaListMethod(mySeq.asJava)`. Thus, I'd rather have a first-class construct for extension methods rather than having to write `implicit class RichSeq(val s: Seq) extends AnyVal { def asJava = ... }`

In this case I do prefer Kotlin.


Boilerplate is a problem but doesn't make a language harder to understand. Language-level shortcuts to reduce boilerplate generally make the language harder to understand, IME (I'm thinking of e.g. Perl's $_).

I actually agree that implicit conversions are to be minimized. But you do need a way of doing the equivalent of the magnet pattern - which in Kotlin is either a different language-level feature, or simply impossible. I'm hopeful that a simpler underlying abstraction can be found - but Kotlin feels to me like it's just piling on a bunch of special cases without making any effort to be consistent or unified.


You won't be able to implement type classes. There might be something in that direction after 1.0; still, Kotlin is not supposed to be a contender with Scala w.r.t. expressive power. It is just Java with more concise syntax, and with most design patterns turned into language features: singleton, delegates, lambdas/sam, "utils" classes (extension methods).


This. Ceylon is what Java should have evolved into with better stewardship. Too bad it does not have the marketing muscle of a big corporation/consortium.


could you expand further on this? I actually believe Kotlin to be much simpler than Scala


Have replied to sibling, hopefully that makes my views clearer.




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

Search: