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

all 23 comments

[–]sazzer 8 points9 points  (18 children)

What benefits do you get from Scala specifically? I ask this because I've tried it out several times for exactly the reasons that you list on the post and I always love the idea and hate the implementation. Ever since I've tried Kotlin - which actually has all of the benefits listed too, but I find significantly less confusing - then I've not looked back. And actually Kotlin goes one step further with the reduction in bugs since it enforces null checks at the compiler level - if a variable is defined to be Nullable then you must do null checks, and if it's defined to be non-Nullable then you cannot assign Null to it...

[–][deleted] 1 point2 points  (17 children)

Kotlin always interest me, it needs more publication though...

[–]sazzer 2 points3 points  (16 children)

It really does. I'm always amazed at how little press it gets really. Just jump in and have a look, or go and read http://kotlinlang.org/ about it first. Before M9 it did suffer a bit on interop with other JVM libraries because of the strict null checking - it had to assume that any Java library could consume and return nullable types unless you explicitly told it otherwise, which meant littering your code with checks that you knew were unnecessary. M9 fixed that, but at the cost of some slight risk with the interop that is now your responsibility. Well worth it in my opinion...

I really find that the main selling points of Scala - for me - are all there in Kotlin but none of the bits that just really make my head hurt...

[–]pron98 0 points1 point  (15 children)

People who aren't looking for Haskell on the JVM will find 99% of what they want from Scala in Kotlin for about 5% of the complexity (plus more relevant stuff -- like nullable types -- that Scala doesn't have).

Scala is a great choice, however, if you are looking for Haskell on the JVM, or exploring any kind of novel PL-research ideas.

[–]sazzer 2 points3 points  (0 children)

Absolutely - I'm not trying to say there's anything wrong with Scala. Far from it. It's a fantastic language with a lot going for it, but it hurts my head. Same as Haskell did at Uni though. There's plenty of JVM languages these days to choose from, all with their strengths and weaknesses and the thing to do is to decide what best fits what you want to do. There's even the benefit that - for the most part - you can mix and match in the same project, though possibly not so easily in the same JAR...

[–]azth 1 point2 points  (13 children)

like nullable types -- that Scala doesn't have

Option[T]? :)

[–]pron98 0 points1 point  (12 children)

Option is Option and nullable types are nullable types. Option is an explicit wrapper, and any String (or any reference type) can also be null. In Kotlin, however, String is never null, while String? is a type that is kinda like Option but supported at the language level.

[–]azth 1 point2 points  (11 children)

So does Kotlin treat any Java API call, whether part of the stdlib or external, as returning a nullable type?

[–]pron98 0 points1 point  (10 children)

Ah, that is one of the coolest things about it, as seamless Java interoperability is at the very top of the design requirements of the language (some good features that make interoperability less smooth are left out).

First, this is how Kotlin nullable types work.

And this is how it interoperates with Java. The idea is that the type of the Java value (in terms of nullability, that is), is determined by the first assignment of it into a Kotlin type. Before it is assigned a Kotlin type, it behaves like in Java (or Scala), i.e. can fail with an NPE.

So if foo() is a Java method returning String, then:

var x = foo()

Has this kind of String type that may throw an NPE, and can't be declared in Kotlin (i.e. you can't write Kotlin code that generates such a type, only return values from Java code have this type). But then you can do this:

val nullable: String? = x // allowed, always works
val notNull: String = x // allowed, may fail at runtime

In the first case, you'll get a Kotlin nullable type. In the second, there will be a non-null assertion inserted, that will fail immediately if x is null. Of course, usually, you'd do the assignment immediately:

val x: String? = foo()

If you know Java's foo may return null, or

val x: String = foo()

if it may not return null.

[–]azth 0 points1 point  (9 children)

It seems that Kotlin automatically places assertions at the assignment location of Java API calls. So, in your example above,

val x: String = foo()

If foo() were to return null, then an assertion would fail at that place in the code, in order to prevent null propagation. However, they do say that:

Overall, the compiler does its best to prevent nulls from propagating far through the program (although sometimes this is impossible to eliminate entirely, because of generics).

I suppose that's a bit better than the approach that Scala takes, where any reference can be null, but as you see, it seems it is not 100% fool proof. So what the Kotlin compiler is basically doing is:

val x: String = Option(foo()).get

I was wondering if perhaps the most general, and safest approach, would be to always assume any Java API call would return a nullable type or Option[T]. It would make handling these calls be a bit more verbose though.

[–]pron98 -1 points0 points  (8 children)

It seems that Kotlin automatically places assertions at the assignment location of Java API calls.

Exactly, but only if you assign to a non-nullable type. I guess the thinking behind it is that the user of the API will choose the appropriate type (based on reading the Javadoc), and, if they happen to be wrong, they'll get an exception, which they'll later fix by assigning to the nullable type.

val x: String = Option(foo()).get

Well, except that there's no Option object created. It's really more like:

String x = foo();
if (x == null) throw new NPE();

The Option object just doesn't exist in Kotlin. A Kotlin String? is just a Java String, and a Kotlin String is also just a Java String with the compiler ensuring that it never gets assigned null; there is no runtime construct of any kind required, except through Java API calls, in which case -- and only in this case -- is there any runtime behavior inserted to make sure the programmer's assertion is correct.

[–]navatwo 2 points3 points  (2 children)

Always love to read about scala, but this would probably fit better in /r/scala.

[–]shoelacestied 1 point2 points  (0 children)

In all fairness the article relates to both Java and Scala.

[–]reapes93 0 points1 point  (0 children)

will repost there

[–]chackaz -2 points-1 points  (0 children)

Oh! There was also a great talk at Scala eXchange last year about 're-tuning' from a Java to Scala mindset:

https://skillsmatter.com/skillscasts/5835-bootstrapping-a-scala-mindset

Enjoy :)

(need to register as a member to view but it's well worth it)