Scala 3’s type system is based on something called dependent object types / DOT or path dependent types. This isn’t true dependent type theory afaict. The documentation example is:
trait Entry { type Key; val key: Key }
def extractKey(e: Entry): e.Key = e.key // a dependent method
val extractor: (e: Entry) => e.Key = extractKey // a dependent function value
// ^^^^^^^^^^^^^^^^^^^
// a dependent function type
Compare
module type Entry = sig
type key
val x : key
end
let extractor (module E : Entry) : E.key = E.x
Is there any direct comparison of module-dependent functions with Scala 3’s type system?
I believe both draw from Rossberg’s paper.
I don’t think anyone tried to match them 1:1, but the papers Scalable Component Abstractions
and A Path to DOT: Formalizing Fully Path-Dependent Types already identified that, loosely speaking:
Scala objects correspond to ML modules, classes to
functors, and interfaces to signatures.
So Scala is kinda like writing programs entirely in OCaml’s module system (except they don’t need wrapper modules for regular values, since they are objects already.) With module-dependent functions in OCaml 5.5, you could instead replace OCaml records with first-class modules entirely to approach the Scala calculus.
As @hyphenrf said, 1ML has been influential on both. DOT however has a focus on allowing recursive references and mixins, to match the OOP and JVM style of programming.