Description
I am trying to nail down in my mind, the fundamental orthogonal semantic concepts of our proposed programming language.
Concept | Description |
---|---|
data |
Unified sum, product, recursive, and record data types. No early bound operations other than construction and access. Record types may optionally be mutable. |
typeclass |
Delayed binding of operations to types at the use-site. Contrast to OOP (subclassing) which binds operations at construction of objects. For polymorphic types, typeclass objects delays binding operations until construction of the typeclass object (instead of prematurely binding operations at the construction of an instance of the implementing type); whereas, my posited and proposed solution to the Expression Problem employing unions, in theory further delays binding to the use-site for polymorphic types. Note that delaying is a positive attribute in this context, because it increases degrees-of-freedom. |
module |
Encapsulating data with compile-time (statically) bound operations and access control, enabling more sophisticated types. |
monadic effect system | #4 (comment) |
Thus I am wondering if module
is the most apt name for the concept? I think of a module as a unit of code that is imported separately. We still need to import data
and typeclass
, so is this done by files? Isn't each file then a module? If so, what is the apt name for the concept of module
above? I am thinking the above concept for module
is really a class
(without the subclassing inheritance anti-pattern). Can't modules
extend other modules?
Edit: note also OCaml functors and modules.
Edit#2: on typeclasses, I replied to @keean:
Optional implicit parameters (which Scala has) provide a way of unifying runtime interfaces (passed by value) and monomorphisable interfaces (passed implicitly by type).
I like that summary (in the context of what I had written). We should make sure we frame that and use it in our documentation.
I think it is important to remember that we want to keep implementation of interface (i.e. typeclass) orthogonal to instantiation of data, otherwise we end up with the early binding of subclassing. For example, in subclassing both a rectangle and a square would be subclasses of an interface which provides width and height. Yet a square only has one dimension, not two. Any interfaces which need to operate on the dimensions of rectange and square need to be customized for each, which is what typeclasses do. We will still have subtyping such as when an interface extends another interface then we can subsume to the supertype (which is why we need read-only references and for supersuming then write-only references). Yet references will not have the type of an interface if we don't provide typeclass objects, so then the only case of subtyping will be the subset relationships created by conjunctions and disjunctions of data types.