Nullsafety warning

I think this is the main difference in our understanding which results in broader disagreement in this topic.

You consider type-safety and null-safety separate things. For me null-safety is a part of type-safety. Not nullable type is simply a subtype of a nullable type and we can cast between them. There is no difference between: animal as Dog, nullableString as String and nullableString!! - these are all operations of downcasting.

No, not everyone :slight_smile: For me this is simply an overcomplicated way of saying value as Foo. As a matter of fact, I think IDE should suggest a code improvement here.

1 Like

What do you mean by

For me it seems like you suggest to do what I’m asking for

I meant it could/should suggest changing (value as Foo?)!! into value as Foo - similarly, as it suggests many other improvements to simplify the code.

1 Like

Yes it can. If you pass a non-null Foo object to the function then it succeeds just fine.

3 Likes
fun some(value: Foo?) {
    val foo = value as Foo // Silent
    ...
}

some(value = null) // NullPointerException

val value: Foo? = null
some(value = value) // NullPointerException

Hmm… I don’t see it

Maybe we stop thinking that our code without bugs at all, and start thinking how we can prevent some of our bugs. For example… Kotlin already has null safety, maybe null safety concept should help us to prevent NullPointerExceptions in our code? What do you think?

Similarly:

open class Foo
class Bar: Foo()
fun some(value: Foo) {
  val bar = value as Bar // Silent
}
fun main() {
  some(value = Foo()) // ClassCastException
  val value: Foo = Foo() // ClassCastException
  some(value = value)
}

Same point. Foo? is a type that can be Foo or null. Casting it to Foo means you’re telling the compiler that it is never null. Same as casting a Foo into a Bar. You’re telling the compiler that it will always be Bar. That’s on you, the compiler cannot be warning you for every single cast that you make because the whole point of casts is that they’re a “trust me, bro” measure. Btw, some(value = Bar()) would run with no exception in my example, and some(value = Foo()) would run with no exception in your example because casting a Foo? that actually contains a Foo into a Foo won’t throw an error, obviously.

1 Like

He means some(value = Foo())

Null Safety means not including the null value as a member of all reference types.
In Java, String is actually String | null. In Kotlin, String is just String. That makes a language null safe, because there is NO WAY for you to get a null from String variable.

Null safety does NOT mean the banning of inherently unsafe but explicit operations (e.g. as and !!)
The moment you use the operator “as” or “!!”, you should already start being cautious and you need not the compiler to warn you about them. They themselves are explicit warnings. They are inherently unsafe. They are basically assertions. They need not to be warned about.

There is a reason why there is a safe cast operator as? as an alternative to as and a bunch of null-related operators (i.e. elvis operator ?:, safe call operator ?.) as alternatives to !!. You don’t complain about the lack of warning when you go out of your way to use the unsafe operators when there are safer alternatives.

By your logic, we should start getting warnings everywhere we use as and !!. With which I don’t agree.

1 Like

I said pass a non-null Foo, but you have passed a null.

val value = Foo()
some(value = value) // no exception
2 Likes

I agree that using as as unsafe non-null operator is suspicious. But should it be a compiler warning or a rule in a “code-smell” analysis ?

I tend to believe that if it is an easily avoidable mistake (some might call it a weak signal), linters are more fit for these kind of warning, because they can be easily/extensively tuned for your needs/team.

However, I tend to agree that the cast operator has some problems. For example, I find very strange that a cast which cannot succeed (foo as Bar) raises only a warning and not a compile time error, as in Java language (Cf. this issue).