# Packages

A fundamental principle in programming is the acronym DRY: Don’t Repeat Yourself.

Multiple identical pieces of code require maintenance whenever you make fixes or improvements. So duplicating code is not just extra work—every duplication creates opportunities for mistakes.

The import keyword reuses code from other files. One way to use import is to specify a class, function or property name:

import packagename.ClassName
import packagename.functionName
import packagename.propertyName

A package is an associated collection of code. Each package is usually designed to solve a particular problem, and often contains multiple functions and classes. For example, we can import mathematical constants and functions from the kotlin.math library:

// Packages/ImportClass.kt
import kotlin.math.PI
import kotlin.math.cos  // Cosine

fun main() {
  println(PI)
  println(cos(PI))
  println(cos(2 * PI))
}
/* Output:
3.141592653589793
-1.0
1.0
*/

Sometimes you want to use multiple third-party libraries containing classes or functions with the same name. The as keyword allows you to change names while importing:

// Packages/ImportNameChange.kt
import kotlin.math.PI as circleRatio
import kotlin.math.cos as cosine

fun main() {
  println(circleRatio)
  println(cosine(circleRatio))
  println(cosine(2 * circleRatio))
}
/* Output:
3.141592653589793
-1.0
1.0
*/

as is useful if a library name is poorly chosen or excessively long.

You can fully qualify an import in the body of your code. In the following example, the code might be less readable due to the explicit package names, but the origin of each element is absolutely clear:

// Packages/FullyQualify.kt

fun main() {
  println(kotlin.math.PI)
  println(kotlin.math.cos(kotlin.math.PI))
  println(kotlin.math.cos(2 * kotlin.math.PI))
}
/* Output:
3.141592653589793
-1.0
1.0
*/

To import everything from a package, use a star:

// Packages/ImportEverything.kt
import kotlin.math.*

fun main() {
  println(E)
  println(E.roundToInt())
  println(E.toInt())
}
/* Output:
2.718281828459045
3
2
*/

The kotlin.math package contains a convenient roundToInt() that rounds the Double value to the nearest integer, unlike toInt() which simply truncates anything after a decimal point.

To reuse your code, create a package using the package keyword. The package statement must be the first non-comment statement in the file. package is followed by the name of your package, which by convention is all lowercase:

// Packages/PythagoreanTheorem.kt
package pythagorean
import kotlin.math.sqrt

class RightTriangle(
  val a: Double,
  val b: Double
) {
  fun hypotenuse() = sqrt(a * a + b * b)
  fun area() = a * b / 2
}

You can name the source-code file anything you like, unlike Java which requires the file name to be the same as the class name.

Kotlin allows you to choose any name for your package, but it’s considered good style for the package name to be identical to the directory name where the package files are located (this will not always be the case for the examples in this book).

The elements in the pythagorean package are now available using import:

// Packages/ImportPythagorean.kt
import pythagorean.RightTriangle

fun main() {
  val rt = RightTriangle(3.0, 4.0)
  println(rt.hypotenuse())
  println(rt.area())
}
/* Output:
5.0
6.0
*/

In the remainder of this book we use package statements for any file that defines functions, classes, etc., outside of main(), to prevent name clashes with other files in the book, but we usually won’t put a package statement in a file that only contains a main().

Exercises and solutions can be found at www.AtomicKotlin.com.