# Code Smell 208 - Null Island

> TL;DR: Don't use null for real places

# Problems

- Coupling

- Unexpected Results

# Solutions

1. Model the unknown location with polymorphism

# Context

[Null Island](https://en.wikipedia.org/wiki/Null_Island) is a fictional place, which is located at the coordinates [0°N 0°E](https://www.google.com/maps/place/0%C2%B000'00.0%22N+0%C2%B000'00.0%22E/@0,0,35771m/), at the intersection of the Prime Meridian and the Equator in the Atlantic Ocean. 

The name "Null Island" comes from the fact that this location represents the point where a lot of GPS systems place any data that has missing or invalid location coordinates.

In reality, there is no landmass at this location, and it is actually in the middle of the ocean. 

This point has become a popular reference for geographic information systems (GIS) and mapping software, as it serves as a way to filter out errors in location data.

# Sample Code

## Wrong

[Gist Url]: # (https://gist.github.com/mcsee/8103413f0cbda26e2133f977a3180d8a)
```kotlin
class Person(val name: String, val latitude: Double, val longitude: Double)

fun main() {
    val people = listOf(
        Person("Alice", 40.7128, -74.0060), // New York City
        Person("Bob", 51.5074, -0.1278), // London
        Person("Charlie", 48.8566, 2.3522), // Paris
        Person("Tony Hoare", 0.0, 0.0) // Null Island
    )
    
    for (person in people) {
        if (person.latitude == 0.0 && person.longitude == 0.0) {
            println("${person.name} lives on Null Island!")
        } else {
            println("${person.name} lives at (${person.latitude}, ${person.longitude}).")
        }
    }
}

```

## Right

[Gist Url]: # (https://gist.github.com/mcsee/dea28242b003409926f2d49cf7ad0849)
```kotlin
abstract class Location {
    abstract fun calculateDistance(other: Location): Double
}

class Coordinates(val latitude: Double, val longitude: Double) : Location() {
    override fun calculateDistance(other: Location): Double {    
        val earthRadius = 6371.0 // kilometers
        val latDistance = Math.toRadians(latitude - other.latitude)
        val lngDistance = Math.toRadians(longitude - other.longitude)
        val a = sin(latDistance / 2) * sin(latDistance / 2) +
                cos(Math.toRadians(latitude)) * cos(Math.toRadians(other.latitude)) *
                sin(lngDistance / 2) * sin(lngDistance / 2)
        val c = 2 * atan2(sqrt(a), sqrt(1 - a))
        return earthRadius * c
    }
}

class UnknownLocation : Location() {
    override fun calculateDistance(other: Location): Double {
        throw IllegalArgumentException("Cannot calculate distance from unknown location.")
    }
}

class Person(val name: String, val location: Location)

fun main() {
    val people = listOf(
        Person("Alice", Coordinates(40.7128, -74.0060)), // New York City
        Person("Bob", Coordinates(51.5074, -0.1278)), // London
        Person("Charlie", Coordinates(48.8566, 2.3522)), // Paris
        Person("Tony Hoare", UnknownLocation()) // Unknown location
    )
    
    val rio = Coordinates(-22.9068, -43.1729) // Rio de Janeiro coordinates
    
    for (person in people) {
        try {
            val distance = person.location.calculateDistance(rio)
            println("${person.name} is ${distance} kilometers from Rio de Janeiro.")
        } catch (e: IllegalArgumentException) {
            println("${person.name} is at an unknown location.")
        }
    }
}

```

# Detection

[X] Semi-Automatic 

We can check for special numbers used as nulls

# Tags

- Null

# Conclusion

Don't use [Null](https://maximilianocontieri.com/null-the-billion-dollar-mistake) to represent [real objects](https://maximilianocontieri.com/code-smell-126-fake-null-object)

# Relations

%[https://maximilianocontieri.com/code-smell-12-null]

%[https://maximilianocontieri.com/code-smell-126-fake-null-object]

# More Info

%[https://maximilianocontieri.com/null-the-billion-dollar-mistake]

%[https://en.wikipedia.org/wiki/Null_Island]

# Disclaimer

Code Smells are my [opinion](https://maximilianocontieri.com/i-wrote-more-than-90-articles-on-2021-here-is-what-i-learned).
  
* * *

> The billion dollar mistake of having null in the language. And since JavaScript has both null and undefined, it's the two billion dollar mistake.

_Anders Hejlsberg_

%[https://maximilianocontieri.com/software-engineering-great-quotes]

* * *

This article is part of the CodeSmell Series.

%[https://maximilianocontieri.com/how-to-find-the-stinky-parts-of-your-code]
