I'm not certain I know what use case you're getting at. It sounds like you 
want to take the current state of the global hierarchy and "fork" it into a 
private hierarchy? Even though the var is private you can still access its 

@#'clojure.core/global-hierarchy (same as (deref (var 

I think you are already aware you can make and use your own hierarchies: 
all multimethod-related functions have an optional argument to accept a 
hierarchy directly as a value (or in a mutable ref container such as a var 
or atom in defmulti's case).

So to "fork" your own hierarchy, grab a snapshot the global-hierarchy var's 
value and use the derive and underive on that value to make your own 
hierarchy. Note that the heirarchy-explicit arities of derive and underive 
are pure: they return the new hierarchy map and do not mutate anything. 
(You also don't have to use namespace keywords for the type names.)

I hope you are not talking about something like a "live fork", where you 
want your own hierarchy expressed as a diff against the global-hierarchy 
and updated when the global hierarchy's value changes? You can probably do 
that with enough ILookup magic or a var watcher to recompute the derived 
hierarchy, but that sounds like a bad idea in general. Hierarchies are only 
useful with the named multimethods that explicitly use them, so it's hard 
to imagine a case where you want a multimethod to be "global hierarchy plus 
changes" and not just an entirely separate hierarchy.

On Sunday, April 8, 2018 at 1:57:41 PM UTC-5, Pedro Iago Carvalho Martins 

> Ok, this is part of a theme that haunts me and I would like to know if 
> anyone shares my view or has a insteresting point.
> The #'global-hierarchy in clojure.core is used to enable things such as 
> multi-methods, and the isa? function.
> Now, we can change a var with alter-var-root, and I see it mostly being 
> used for configuration, as with *unchecked-math* or *warn-on-reflection*.
> But for some reason the global-hierachy is private, and in a weird way 
> where you can change it, as long you play the game.
> Example:
> (def a {:type ::a :val 1})
> (defn cons-a-foo [bar in]
>   (if (isa? (:type in) ::foo)
>     (cons (:val in) bar)
>     bar))
> (cons-a-foo [] a)    ; => []
> (derive ::a ::foo)   ; we change the global-hierarchy
> (cons-a-foo [] a)    ; => [1]
> (underive ::a ::foo) ; yet again
> (cons-a-foo [] a)    ; => []
> ;And then isa? also supports a 3-ary version, which takes a hierarchy as:
> (make-hierarchy) ; => {:parents {} :descendants {} :ancestors {}} ;omg it 
> is just a map! glad I know those
> This is all good, except for one reason: global-hierarchy is private.
> We can't for instance try a "alternate-hierarchy" that is mostly the 
> global one with some expeculations.
> We lose all the other map functions in dealing with, especifically, the 
> global-hierarchy.
> And then we're back to oop.
> If the global-hierarchy was not made private (or any function for that 
> matter), then we could choose if we want to deal it with, or not.
> In my experience, making something private is only worth the trouble if we 
> give a complete substitute, that does everything and better.
> Let's say a rocket would explode if we set it to nil.. Then, just don't.
> With all that say, can we please remove the ^{:private true} from the 
> global-hierarchy definition?
> Sorry if I rant.

You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
For more options, visit this group at
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to