Hierarchy fns follow the reference contracts; deftype classes join the class graph
derive/underive/ancestors/descendants/parents/isa? re-ported from clojure.core with the argument assertions and throw contracts intact: derive asserts tag/parent shapes (AssertionError) and throws on redundant or cyclic derivation; underive/derive on a non-hierarchy value throw at the parents lookup (the map is called as a function, like the reference); (descendants h SomeClass) throws UnsupportedOperationException. isa? gains the reference's supers arm (a relationship derived on a class's super applies to the class). The class arms now answer fully through the one class graph: parents of a class are its direct supers (bases), ancestors are the transitive set rooted at java.lang.Object for concrete classes (interfaces are marked and don't root at Object, matching getSuperclass semantics). deftype/defrecord classes register into the graph at definition — protocol interfaces they implement appear as supers (JVM-munged ns spelling), records carry the record interfaces (IRecord/IPersistentMap/... whose closure supplies Associative/Seqable), bare deftypes carry IType. The type NAME var still holds the ctor (a jolt-ism); class-key maps it back to the class so (ancestors TypeName)/(isa? x TypeName) work. canonical-host-tag learned to NOT canonicalize deftype names through the graph arm (extend-type on a deftype was registering under the bare segment its values never report). Five old corpus rows used non-namespaced derive tags that throw on the JVM too; now namespaced. 8 new JVM-certified corpus rows; spec entries for the hierarchy family; cts baseline 5730 -> 5781 pass (ancestors/derive/ descendants/parents/underive namespaces fully clean), 74 baselined namespaces.
This commit is contained in:
parent
7e1df2c600
commit
6e333b3020
10 changed files with 618 additions and 401 deletions
|
|
@ -232,6 +232,56 @@ clojure-test-suite `core_test/special_symbol_qmark.cljc` and every
|
|||
|
||||
---
|
||||
|
||||
### make-hierarchy, derive, underive, isa?, parents, ancestors, descendants — since 1.0
|
||||
|
||||
```
|
||||
(make-hierarchy)
|
||||
(derive tag parent) (derive h tag parent)
|
||||
(underive tag parent) (underive h tag parent)
|
||||
(isa? child parent) (isa? h child parent)
|
||||
(parents tag) (ancestors tag) (descendants tag) ; + (f h tag) forms
|
||||
```
|
||||
|
||||
**Semantics**
|
||||
|
||||
- S1. A hierarchy is a pure value `{:parents {tag #{...}} :ancestors {...}
|
||||
:descendants {...}}`; the 3-arity forms are pure, the shorter arities read and
|
||||
mutate the global hierarchy.
|
||||
- S2. `isa?` is true when `(= child parent)`, when the host type system says
|
||||
parent is assignable from child (both classes), when the relationship was
|
||||
`derive`d — including a relationship derived on one of a class child's
|
||||
supers — or component-wise for equal-length vectors.
|
||||
- S3. Class tags answer through the host type hierarchy: `(parents c)` includes
|
||||
the class's direct supers (`bases` — a concrete class's chain roots at
|
||||
`java.lang.Object`, an interface's does not); `(ancestors c)` is the
|
||||
transitive set plus anything `derive`d on the class or its supers. A
|
||||
deftype/defrecord class's ancestry includes its implemented protocol
|
||||
interfaces and, for records, the record interfaces
|
||||
(`clojure.lang.IRecord`/`IPersistentMap`/`Associative`/…; `clojure.lang.IType`
|
||||
for a bare deftype).
|
||||
- S4. `derive` returns the updated hierarchy (3-arity) or nil (2-arity);
|
||||
deriving a relationship that already holds transitively, or one that would
|
||||
create a cycle, throws.
|
||||
|
||||
**Errors**
|
||||
|
||||
- X1. `derive` asserts its argument shapes: parent must be a namespaced Named
|
||||
value; tag must be a class or a Named value (namespaced in the 2-arity
|
||||
global form); `(derive h tag tag)` fails the `not=` assert. AssertionError.
|
||||
- X2. `underive`/`derive` with a non-hierarchy `h` throw at the parents
|
||||
lookup (the map is called as a function, like the reference).
|
||||
- X3. `(descendants h SomeClass)` throws UnsupportedOperationException
|
||||
("Can't get descendants of classes") — Java type inheritance is not
|
||||
enumerable downward.
|
||||
|
||||
**Conformance**
|
||||
|
||||
S1–S4, X1–X3 → corpus `hierarchy / *` rows; clojure-test-suite
|
||||
`core_test/{derive,underive,isa_…,parents,ancestors,descendants}.cljc`
|
||||
(all fully passing).
|
||||
|
||||
---
|
||||
|
||||
## Authoring notes
|
||||
|
||||
- Source examples from the ClojureDocs export (`clojuredocs-export.edn`,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue