# Introduction to coulomb

## Quick Start

### documentation

API documentation for `coulomb` is hosted at javadoc.io

### packages

Include `coulomb` with your Scala project:

``````libraryDependencies += "com.manyangled" %% "coulomb-core" % "0.8.0"
libraryDependencies += "com.manyangled" %% "coulomb-units" % "0.8.0"``````

### import statements

Import `coulomb` definitions:

``````// fundamental coulomb types and methods
import coulomb.*
import coulomb.syntax.*

// algebraic definitions
import algebra.instances.all.given
import coulomb.ops.algebra.all.given

// unit and value type policies for operations
import coulomb.policy.standard.given
import scala.language.implicitConversions

// unit definitions
import coulomb.units.si.{*, given}``````

### examples

Use `coulomb` to do typelevel unit analysis in Scala!

``````// acceleration
val a = 9.8.withUnit[Meter / (Second ^ 2)]
// a: Quantity[Double, /[Meter, ^[Second, 2]]] = 9.8

// time or duration
val t = 10.withUnit[Second]
// t: Quantity[Int, Second] = 10

// velocity
val v = a * t
// v: Quantity[Double, /[Meter, Second]] = 98.0

// position
val x = a * (t.pow[2]) / 2
// x: Quantity[Double, Meter] = 490.00000000000006``````

Improper unit analysis is a compile-time failure.

``````val time = 1.withUnit[Second]
val dist = 1.withUnit[Meter]

// Incompatible unit operations are a compile-time type error
val fail = time + dist
// error:
// Addition not defined in scope for Quantity[Int, coulomb.units.si.Second] and Quantity[Int, coulomb.units.si.Meter].
// I found:
//
//       coulomb.units.si.Meter](<:<.refl[Int], scala.util.NotGiven.value,
//       coulomb.policy.standard.ctx_Quantity_Conversion_2V2U[Int,
//         coulomb.units.si.Meter, Int, coulomb.units.si.Second](
//         coulomb.policy.standard.ctx_VC_Int[Int](scala.math.Numeric.IntIsIntegral),
//         /* missing */
//           summon[
//             coulomb.conversion.UnitConversion[Int, coulomb.units.si.Meter,
//               coulomb.units.si.Second]
//           ]
//       ),
//     ???)
//
// But no implicit values were found that match type coulomb.conversion.UnitConversion[Int, coulomb.units.si.Meter,
//   coulomb.units.si.Second].
// val fail = time + dist
//                   ^^^^``````

## Packages

`coulomb` publishes the following packages

name description
coulomb-core Provides core `coulomb` logic. Defines policies for `Int`, `Long`, `Float`, `Double`.
coulomb-units Defines common units, including SI, MKSA, Accepted, time, temperature, and US traditional
coulomb-spire Defines policies for working with Spire and Scala numeric types
coulomb-refined Unit analysis with typelevel refined awareness
coulomb-pureconfig Configuration I/O with Quantity values
coulomb-runtime Runtime units and quantities
coulomb-parser Parsing of expressions into runtime units

## Resources

The following resources expand the concepts behind `coulomb` and typelevel unit analysis:

## Previous versions

Versions of `coulomb` beginning with 0.6 require Scala 3, and are not compatible with Scala 2.13.

`coulomb` versions <= 0.5.x require Scala 2.13. The 0.5.x series will continue to be supported on a maintenance basis only.

You can browse the legacy scala doc for the `*_2.13` packages here.

The legacy tutorial documentation will continue to be viewable here.

The `scala2` branch of `coulomb` on github will continue to hold coulomb <= 0.5.x

## Code of Conduct

The `coulomb` project supports the Scala Code of Conduct. All contributors are expected to respect this code. Any violations of this code of conduct should be reported to the author.