Getting started
The calculator runs inside your build tool. Add the plugin, run one command, read the number. Nothing is uploaded and no source leaves the machine.
sbt
Add the plugin to project/plugins.sbt:
addSbtPlugin("dev.constructive" % "sbt-cardinality" % "0.0.6")
sbt 1.10 and later use the same line: sbt selects the sbt 1 artifact
(sbt-cardinality_2.12_1.0). Then run:
sbt cardinalityReport
sbt cardinalityReport measures every definition the project's Compile sources
introduce — nested definitions included — and logs a report. The same report is written to
target/cardinality/report.txt (cardinalityReportFile), so a build can keep it, diff
it, or post it as an artifact.
scala-cardinality — 1 source, 10 definitions
stored-value estimates: constructor inputs only; finite capacities are upper bounds
?: unresolved, not a proof of infinity
2 unresolved · 4 with more than one value · 2 with one value · 2 abstract
Stored-value estimates (constructor inputs; `?` = unresolved)
? example.Holder[A] class Light.scala:11 unresolved: A
ω example.Succ class Light.scala:17
ω example.Timeline class Light.scala:19
2 example.Custom class Light.scala:5
1 example.Zero object Light.scala:16
— example.Light abstract Light.scala:3
cardinalityReportSelected analyzes named signatures only:
sbt 'cardinalityReportSelected example.Accessor.get'
cardinalityReportOf runs the same report over sources the build does not compile itself
— a directory, a single file, or a published -sources.jar:
sbt 'cardinalityReportOf path/to/sources.jar'
Mill
For Mill 1.3 or later, load the plugin in build.mill's header and mix
CardinalityModule into a ScalaModule:
//| mvnDeps: ["dev.constructive::mill-cardinality_mill1:0.0.6"]
import millcardinality.CardinalityModule
object foo extends ScalaModule with CardinalityModule { def scalaVersion = "3.9.0" }
mill foo.cardinalityReport, mill foo.cardinalityReportOf <path>... and
mill foo.cardinalityReportSelected <qualified-method-name>... run the reports; each
writes report.txt under the command's out/ directory.
The calculator alone
"dev.constructive" %% "scala-cardinality" % "0.0.6"
The build tool may run on JDK 17, 21 or 25. The calculator reads dependencies compiled by
Scala up to the version its TASTy reader supports: 0.0.5 and later read Scala 3.0 through
3.10. A newer Scala's jars appear as dependency stub not read: … TASTy signature has
wrong version at the end of the report.
Next
Reading a report explains the rows, the tiers and the moves that lower a number. Assumptions states what every count assumes.