Although it is not explicitly stated that Nothing is the subtype of all types, this (among others) suggests it:
fun f(x:Float) { }
fun g(x:Char) { }
fun dead(q: Nothing) {
f(q)
g(q)
}
However, this fails with “unresolved reference”:
fun dead(q: Nothing) {
q.not()
}
Is this a bug or a feature?
Notes:
First piece of code compiles (with warnings), second does not
It's possible to use a Nothing typed receiver, for instance calling toString()
This is legal: {b:Boolean -> b.not()}(q)
Upcast too: (q as Boolean).not()
Equivalent question for Scala
Nothing is Nothing for a reason. You can't call any functions on it. Besides not() is only applicable for Boolean so it is not present on Nothing. In fact there are no methods on Nothing:
/**
* Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
* if a function has the return type of Nothing, it means that it never returns (always throws an exception).
*/
public class Nothing private constructor()
The documentation pretty much explains its existence.
There is one loophole though. What happens if you return Nothing? from a function?
fun dead(): Nothing? {
return null
}
That's right. It can only return null:
#JvmStatic
fun main(args: Array<String>) {
dead() // will be null
}
I wouldn't say that there is a valid use case to do this but it is possible.
An example for Nothing to indicate nothingness in trees:
sealed class Tree<out T>() {
data class Node<out T>(val value: T,
val left: Tree<T> = None,
val right: Tree<T> = None): Tree<T>()
object None: Tree<Nothing>()
}
Here Nothing denotes a leaf node with no children.
The premise itself doesn't make sense. Nothing is a class which can not be instantiated. You'll never have a variable that holds a Nothing instance.
This means that a function that takes Nothing as a parameter can never be invoked, because you can't get a Nothing instance to pass to it. Anything you write inside it is irrelevant, as is a function like this existing in the first place.
Nothing is made to act like a subtype to all types so that certain uses of language features like throw and return work nicely with the type system. In essence, the compiler lets you pass a Nothing in places where some other type is required, because it knows that you'll never actually reach that code (because again, you can't get a Nothing instance), so it doesn't matter what you're passing in.
Related
I want to pass a value to a function so when I change the value outside that function I could see it updated in my function as well. I know that when I pass Boxed types like Int, Boolean etc they passed by value. But looks like classes are passed by value as well:
data class TestClass(var b:Boolean)
fun printBooleanIn1sec(b: TestClass) {
Thread.sleep(1000L)
println(b.b)
}
fun main(args: Array<String>) {
var testClass = TestClass(false)
printBooleanIn1sec(testClass)
testClass.b = true
}
// prints "false"
Is there a way to pass something by reference but not by value in Kotlin if I need it?
Class instances are always passed by value of the reference. So the reference used in the function is pointing to the same thing as the reference passed to it, but you never have direct access to pointers in Kotlin/Java. It's important to make this distinction because "pass by reference" would mean that the function could end up looking at a different object if the higher code on the stack changed what its variable was pointing at.
The reason your code prints false is that the Thread you're sleeping is the same one that called your function, and printBooleanIn1sec() returns before testClass.b = true is reached. To illustrate the situation you wanted, you would need to spin up a new thread that sleeps and then prints the value, like:
fun printBooleanIn1sec(b: TestClass) {
thread {
Thread.sleep(1000L)
println(b.b)
}
}
Primitives are abstracted away in Kotlin, so you don't have to think of them differently than a class. But like any other immutable class, you can't change their value at all when you pass them into a function. If you want to "see" changes in the function that occur elsewhere, you'll have to wrap them in classes that hold a var property for them.
I am specifically asking for the non-nullable type Nothing.
I do know that Nothing? allows us to, for example, filter null to make an overload unambiguous, but I'm struggling to think of instances where Nothing would be useful.
Nothing? can have exactly one value, null. So Nothing can have exactly no value. What's the point? Why not simply use Unit?
1. Nothing is the counterpart to Any?
Just as Any? is the base type of any other type, Nothing is the sub type of any other type (even the nullable ones).
Knowing this it becomes clear that s will be of type String in the following example, given name is a String?.
val s = name ?: throw IllegalArgumentException("Name required")
The throw expression returns Nothing, and the common base type of String and Nothing is String. That's what we want, because that's the type we want to work with.
If we would use Unit instead of Nothing the common base type would be Any, which is certainly not what we want, because it would require a cast to String afterward.
That makes sense too, because if the exception will be thrown execution cannot continue there, thus s wouldn't be used any further anyway.
2. Nothing marks code locations that can never be reached
fun foo() {
throw IllegalArgumentException("...")
println("Hey") // unreachable code
}
3. Type inference
If null is used to initialize a value of an inferred type and there's no other information to determine a more specific type, the inferred type will be Nothing?.
val x = null // 'x' has type `Nothing?`
val l = listOf(null) // 'l' has type `List<Nothing?>
Further reading
Nothing is used to tell the compiler that it will never return. For example,
fun main() {
var name: String? = null
val notNullName = name ?: fail("name was null")
println(notNullName)
}
fun fail(message: String): Nothing {
throw RuntimeException(message)
}
fun infiniteLoop(): Nothing {
while (true) {
// Nothingness
}
}
Kotlin has three types that are very similar in nature:
Void
Unit
Nothing
It almost seems like they're making the JavaScript mistake:
null
undefined
void(0)
Assuming that they haven't fallen into the same mistake, what are they all for, and how do they differ?
The Void type is from Java. You generally won't use this from Kotlin unless you're using some Java-library that uses it.
The Unit type is what you return from a function that doesn't return anything of interest. Such a function is usually performing some kind of side effect. The unit type has only one possible value, which is the Unit object. You use Unit as a return type in Kotlin when you would use void (lowercase v) in Java.
The Nothing type has no values. If a function has return type Nothing, then it cannot return normally. It either has to throw an exception, or enter an infinite loop. Code that follows a call to a function with return type Nothing will be marked as unreachable by the Kotlin compiler.
Because Nothing has no values, Nothing? is actually the type that captures only the null value in Kotlin.
Unit
Unit is like void
In Kotlin, when a function does not return any meaningful value, it is declared to return Unit, just like void in Java:
fun greet(): Unit { println("Good day!") }
It's a convention to skip writing Unit when a function returns Unit because Unit is considered the default return type by the compiler:
fun greet() { println("Good day!") }
Unit is a Singleton
The Unit is a class with only a single object (singleton pattern) and that object is the Unit itself. It is declared in the kotlin package using an object declaration as shown below:
public object Unit {
override fun toString() = "kotlin.Unit"
}
Unit in Functional Programming
Kotlin has first-class support for functional programming. It's common to have a Unit in a functional programming language. It makes the function types more readable by enabling all the functions to be declared as having a return value, even when a function does not return a value:
val greet: () -> Unit = { println("Good day!") }
Here, () -> Unit is a function type and the Unit after the -> indicates that this function type does not return any meaningful value. Mentioning the Unit cannot be skipped in function types.
Unit for Extending Generics
Every function has to return a value. Kotlin decided to represent this with a class rather than with a special type void as in Java. The reason for using a class is that the type system can be made more consistent by making it a part of the type hierarchy.
For example, let's say we have a generic interface called Worker<T> that performs some work. The doWork() function of this interface does some work and has to return a value T:
interface Worker<T> {
fun doWork(): T
}
But sometimes, we might want to use this interface for some work where we don't need to return any value, for example, the work of logging, in the LogWorker class shown below that extends the Worker interface:
class LogWorker : Worker<Unit> {
override fun doWork() {
// Do the logging
}
}
This is the magic of Unit where we are able to use the pre-existing interface that was originally designed to return a value. Here we make the doWork() function return the Unit value to serve our purpose in which we don't have anything to return. So, it's useful when you override a function that returns a generic parameter.
Notice that we have also skipped mentioning Unit return type for the doWork() function. There's no need to write a return statement either.
Nothing
Nothing's Value Never Exists
In Kotlin, the class Nothing represents a value that never exists. There can never be any value/object of this class because its constructor is kept private. It's defined in the kotlin package as follows:
public class Nothing private constructor()
Nothing is used for the return type of a function that never returns a value. For example, a function with an infinite loop or a function that always throws an exception. The error() function from Kotlin standard library is an example that always throws an exception and returns Nothing. Here is the code for it:
fun error(message: Any): Nothing = throw IllegalStateException(message.toString())
Nothing is the Bottom Type
In type theory, the type that has no values is called a bottom type and it is a subtype of all other types. So, Nothing is the subtype of all types in Kotlin, just like Any? is the supertype of all types. So, the value(that never exists) of type Nothing is assignable to the variables of all types, for example:
val user: User = request.user ?: error("User not found")
Here, we are calling the error() function that we defined earlier, if the user is null, using the elvis operator(?:). The error() function returns the value of type Nothing but it can be assigned to the variable of type User because Nothing is a subtype of User, just like it is a subtype of any other type. The compiler allows this because it knows that the error() function will never return a value, so there is no harm.
Similarly, you can return Nothing from a function that has any other return type:
fun getUser(request: Request): User {
return request.user ?: error("User not found")
}
Here, even though the getUser() function is declared to return a User, it may return Nothing, if the user is null.
Nothing in Null Object Pattern
Consider the following example of a function that deletes the files given in a list:
fun deleteFiles(files: List<File>? = null) {
if (files != null) files.forEach { it.delete() }
}
The problem with the design of this function is that it doesn't convey whether the List<File> is empty or null or has elements. Also, we need to check whether the list is null before using it.
To solve this problem, we use the null object design pattern. In null object pattern, instead of using a null reference to convey the absence of an object, we use an object which implements the expected interface, but leaves the method body empty.
So, we define the object of the interface List<Nothing>:
// This function is already defined in the Kotlin standard library
fun emptyList() = object : List<Nothing> {
override fun iterator(): Iterator<Nothing> = EmptyIterator
...
}
Now we use this null object in our deleteFiles() function as a default value of our parameter:
fun deleteFiles(files: List<File> = emptyList()) {
files.forEach { it.delete() }
}
This removes the uncertainty of null or empty and makes the intent clearer. It also removes the null checks because the functions on the null object are empty, they will be called but they are no-ops (no operation in them, so they will do nothing).
Nothing for Covariant Generics
In the example above, the compiler allows us to pass List<Nothing> where List<File> is expected. This is because the List interface in Kotlin is covariant since it's defined using the out keyword, that is, List<out T>. And as we learnt, Nothing is a subtype of all types, Nothing is a subtype of File too. And due to covariance, List<Nothing> is a subtype of List<File>, List<Int>, List<User> and so on... List<AllTypes>. This applies to any type with the covariant generics(out), not just List.
Nothing for Better Performance
Just like the function emptyList() used in our example, there are predefined functions like emptyMap(), emptySet(), emptySequence() that return null objects. All these are defined using Nothing. You can define your own objects like this.
The advantage here is that these return singleton objects, for example, you can call the same emptyList() function for getting an empty instance, whether it is for assigning to List<File>, List<Int> and ... List<AllTypes> and in multiple places. Since the same object is returned every time, it saves the cost of object creation and memory allocation.
Void
Void for Extending Generics in Java
The Void class is from the java.lang package while the Unit and Nothing are from the kotlin package. Void is not intended to be used in Kotlin. Kotlin has its own class in the form of Unit.
Void is used in Java for extending generic interfaces like our Worker interface example written for Unit where we have to return a value. So for converting our Kotlin code to Java, we can use Void the same way we have used Unit for our Worker example and rewrite the code in Java as follows:
interface Worker<T> {
T doWork();
}
class LogWorker implements Worker<Void> {
#Override public Void doWork() {
// Do the logging
return null;
}
}
Notice that when using Void, we have to use Void as a return type(can't skip) as well as need to write the return statement whereas for Unit we can skip both. This is another reason to avoid using Void in Kotlin code.
Conclusion
So, Unit and Nothing are not a mistake by Kotlin designers in my opinion and are not as questionable as null, undefined and void(0) in Javascript. Unit and Nothing make the functional programming a breeze while providing other useful features mentioned. They are common in other functional programming languages too.
That's it!
Void is uninstantiable type. It is a plain Java class and has no special meaning in Kotlin.
Unit type has only one value. Replaced Java void (notice: not Void). More info in Kotlin docs.
Nothing has no instances (just like Void). It represents "a value that never exists". In Kotlin if you throw an error it is a Nothing (see Kotlin docs).
I'm constructing a class and then trying to call a member method of that class as a default value for one of the constructor args.
Why isn't this valid Kotlin?
// unresolved reference: defaultText
class MyThing(val text: String = defaultText()) {
fun defaultText() = "hi"
}
It's possible using two separate constructors in both Java and Kotlin, but then I lose the conciseness of default args.
class MyThing {
private val text: String
constructor(text: String) {
this.text = text
}
constructor() {
this.text = defaultText()
}
private fun defaultText(): String {
return "hi"
}
}
The biggest problem of having a constructor's default parameter expression call a member function of the same instance is that the default arguments are evaluated before the constructor is called.
Given that, such a member function would have to run on a completely un-initialized instance of the class (because even the super constructors will work after that, see this answer about the execution order).
Usually, member functions perform some logic taking the instance state into account, and having a member function run on an empty instance might break some of that logic (e.g. all fields will hold nulls, even the backing fields of Kotlin not-null properties). Overall, even when such calls do not fail at runtime, they are likely introduce subtle bugs, so using a completely uninitialized instance is prohibited.
With regard to the secondary constructor, well, at least it runs after the super constructor initializes some part of the instance, which is thus not completely empty, but it's up to you to make sure you don't use the parts of the class that are not initialized (if you do, you may again encounter a runtime failure or introduce a bug).
I'd rather suggest using a function of a companion object (those are initialized before the class is first used) for this purpose:
class MyThing(val text: String = defaultText()) {
companion object {
fun defaultText() = "hi"
}
}
Or even a top-level function:
fun defaultText() = "hi"
class MyThing(val text: String = defaultText())
From the Kotlin documentation:
If a function does not return any useful value, its return type is Unit. Unit is a type with only one value — Unit.VALUE. This value does not have to be returned explicitly:
fun printHello(name : String?) : Unit {
if (name != null)
print("Hello, $name!")
else
print("Hi there!")
// We don't need to write 'return Unit.VALUE' or 'return', although we could
}
What is the purpose of Unit-returning in functions? Why is VALUE there? What is this VALUE?
The purpose is the same as C's or Java's void. Only Unit is a proper type, so it can be passed as a generic argument etc.
Why we don't call it "Void": because the word "void" means "nothing", and there's another type, Nothing, that means just "no value at all", i.e. the computation did not complete normally (looped forever or threw an exception). We could not afford the clash of meanings.
Why Unit has a value (i.e. is not the same as Nothing): because generic code can work smoothly then. If you pass Unit for a generic parameter T, the code written for any T will expect an object, and there must be an object, the sole value of Unit.
How to access that value of Unit: since it's a singleton object, just say Unit
The main reason why Unit exists is because of Generic reasons.
Let's use the example from the Kotlin docs.
class Box<T>(t: T) {
var value = t
}
We can have
var box = Box(Unit)
This is why Unit returns a value so the Kotlin can infer it from the type passed into class initialization. Of course, you could also explicitly write it like this,
var box = Box<Unit>(Unit)
but all the same, it must have a return value.
Now, the void keyword in Java in Kotlin is Nothing. Nothing is the last but one type in the type hierarchy in Kotlin with the last one being Nothing? (Nullable Nothing). This does not return any value at all. Because it doesn't return any value at all, we can't pass it as a type in the above code.
var box = Box(Nothing) //This will return an Error
UNIT actually contains valuable information, it basically just means "DONE". It just returns the information to the caller, that the method has been finished. This is a real piece of information so it can be seen as the return value of a method.