Hacker News new | ask | show | jobs
by qammm 4698 days ago
I don't want to sidetrack that thread as it was about Clojure. Just a quick correction: Java has no type inference, higher order functions, coroutines, implicits (it has some standard implicit conversions but not implicit conversions that can be added by the user) and no Turing complete type system.

And of course: Using a statically typed language is no excuse to not write unit tests. Unit tests serve as a safety net checking if the behavior of the implemented unit is (and stays) correct. As a side effect this will also find all type errors a compiler will find. I have programmed a lot in Java and also in dynamic programming languages and in my opinion type errors just don't happen often enough to justify the additional amount of work and complexity that comes with static type systems. However I'd agree that if you want to get the best possible performance you probably need a statically typed language as the compiler can then optimize the generated code better.

1 comments

  > Java has no type inference, higher order functions,
  > coroutines, implicits (it has some standard implicit
  > conversions but not implicit conversions that can be
  > added by the user) and no Turing complete type system.
Type inference in Java:

  int bar = new Object(){ int foo = 42; }.foo;
  // Magic? No. Type inference.
Higher order functions in Java:

  http://download.java.net/jdk8/docs/api/java/util/stream/Stream.html
  Looks pretty higher-order to me.
  Also possible in older version in Java with stuff like Google Guava or FJ.
Coroutines in Java:

  http://stackoverflow.com/questions/2846428/available-coroutine-libraries-in-java
Implicits:

  Having them built into the language is even worse.
  In Scala you could just de-import them and have them gone.
  Anyway, pick C# as an example instead if you want to have
  user-defined implicit conversions.
No Turing complete type system:

  interface Interface<T> {}
  class Bang<T> implements Interface<Interface<? super Bang<Bang<T>>>> {
      static void bang() {
          Interface<? super Bang<Byte>> bang = new Bang<Byte>();
      }
  }

  Looks pretty undecidable to me. In a way, it is even
  worse than other languages: You are unable to tell
  whether the type checker will terminate in finite time
  (like some other languages), but don't get any additional
  expressivness in return (unlike those other languages).


  > As a side effect this will also find all type errors
  > a compiler will find.
No, absolutely not.

  > I have programmed a lot in Java and also in dynamic
  > programming languages and in my opinion type errors
  > just don't happen often enough to justify the
  > additional amount of work and complexity that comes
  > with static type systems.
This comment certainly explains a lot. You are suffering from the "I used Java and Java is statically typed and it sucks, therefore all statically typed languages have to suck" fallacy.
It seems we have different definitions of what type inference, higher order functions and Turing completeness means. :-) Regarding coroutines in Java: I don't know if libraries using native continuation mechanisms or bytecode manipulations prove that Java (the language) has continuation support. :-) I don't have anything against Scala. In my very first message I even said that I see the odds for Scala winning higher than the odds for Clojure winning - because I already see some enterprise adoption of Scala. Although I see the probability of Scala winning quite low. As you noticed with Java 8 Java is already borrowing a lot of useful things from Scala. I am sure conservative corporate decision makers will see less and less reasons to switch to Scala as time passes by. Also I don't think that Java sucks. I was just making a point from personal productivity experience. Your experience might differ from that.

If I have a function: def upcase(s: String): String... The compiler with its static type system can tell me if e. g. I am trying to call the upcase function with an Int argument. But in my experience something like that just does not happen very often. Most programmers are not so stupid that they try to fit a square peg in a round hole. ;-)

A unit test can check if the returned string is really the upcase version of the input parameter. Plus if the programmer would really assume that he could upcase an Int it would just as well give the feedback that his assumption was wrong-like the compiler.

  > It seems we have different definitions of what type 
  > inference, higher order functions and Turing 
  > completeness means. :-)
I don't think so. The definitions are pretty much standard and those are the ones I'm using.

I think we can agree that the way Java supports those features ranges between unusable and pretty terrible in practice, but that's not what your claims were about.

Your notion of Scala having more features than a "standard" mainstream language might even be correct, it is just that the points you have given don't support your point here.

  > Regarding coroutines in Java: I don't know if libraries
  > using native continuation mechanisms or bytecode
  > manipulations prove that Java (the language) has
  > continuation support. :-)
Then Scala doesn't have continuation support either. Whatever definition is applied, it needs to be applied consistently.

  > I don't have anything against Scala.
I never suggested that and even if you had something against Scala, it would be perfectly fine – for me and probably for everyone else.

It's just that you have claimed a few things which I think are incorrect, either factually or in the way they were worded, and I'm offering some data points against it. This all happens in good faith and in the hope that we both will have gained some knowledge at the end of this discussion.

  > As you noticed with Java 8 Java is already borrowing a lot
  > of useful things from Scala. I am sure conservative
  > corporate decision makers will see less and less reasons
  > to switch to Scala as time passes by.
I think most Scala users would agree that Java 8 copying Scala is a good thing, because it strongly validates what the designers and users of Scala have been doing for the last 10 years. With Java moving closer to Scala, adopting Scala becomes a lot easier from a management POV which in turn removes a lot of the concerns corporate decision makers have.

  > If I have a function: def upcase(s: String): String [...]
  > A unit test can check if the returned string is really
  > the upcase version of the input parameter.

  def upcase(s: String): UppercasedString
Now the compiler can check it, too.
Only replying partially as I don't want to repeat myself.

Ok, then let's just ignore continuations as they are somehow available in both languages although the Scala one feels a bit more officially endorsed to me.

> def upcase(s: String): UppercasedString

Even with that type signature of course the compiler can not check that for input "a" the output will be "A". Your code could have a bug and upcase "a" to "B" (Off-by-one errors are quite common) and your compiler would be perfectly happy. That is the whole point why unit test are more valuable than compiler type checks: checking specific code behavior and not only static types.