#lang scribble/doc @(require scribble/manual (for-label scheme "../hierarchy.ss")) @title[#:tag "hierarchy" #:style '(toc)]{Ad-Hoc Hierarchies of Values} @defmodule[(planet "hierarchy.ss" ("murphy" "multimethod.plt" 2 1))]{ This module provides support for ad-hoc hierarchies of values that can be used by multimethods. } @defproc[(make-hierarchy) hierarchy?]{ Creates a new value hierarchy. } @defproc[(hierarchy? [v any/c]) boolean?]{ Determines whether the given value is a hierarchy. } @defthing[global-hierarchy (parameter/c hierarchy?)]{ The global default value hierarchy. } @defstruct[(exn:fail:hierarchy exn:fail) ([child any/c] [parent any/c]) #:transparent]{ Exception type raised when an illegal modification to a hierarchy is attempted. } @defproc[(parents [h hierarchy? (global-hierarchy)] [v any/c]) hash?]{ Retrieves all direct parents of @scheme[v] registered in @scheme[h]. This is the counterpart of @scheme[children]. Returns a hash table mapping all the parents to @scheme[#t]. } @defproc[(children [h hierarchy? (global-hierarchy)] [v any/c]) hash?]{ Retrieves all direct children of @scheme[v] registered in @scheme[h]. This is the counterpart of @scheme[parents]. Returns a hash table mapping all the children to @scheme[#t]. } @defproc[(ancestors [h hierarchy? (global-hierarchy)] [v any/c]) hash?]{ A transitive version of @scheme[parents]. Retrieves all ancestors of @scheme[v] registered in @scheme[h] or in the global default hierarchy, if the single argument form is used. This is the counterpart of @scheme[descendants]. Returns a hash table mapping all the ancestors to @scheme[#t]. } @defproc[(descendants [h hierarchy? (global-hierarchy)] [v any/c]) hash?]{ A transitive version of @scheme[children]. Retrieves all descendants of @scheme[v] registered in @scheme[h] or in the global default hierarchy, if the single argument form is used. This is the counterpart of @scheme[ancestors]. Returns a hash table mapping all the descendants to @scheme[#t]. } @defproc[(derived? [h hierarchy? (global-hierarchy)] [child any/c] [parent any/c]) boolean?]{ Checks whether @scheme[child] is a descendant of @scheme[parent] using the scheme object system and the ad-hoc hierarchy @scheme[h] or the global default hierarchy, if the two argument form is used. This procedure first converts @scheme[child] and / or @scheme[parent] into interfaces using @scheme[class->interface], if they are classes. Then it returns @scheme[#t] iff any of the following conditions, which are checked in order, is fulfilled: @itemize{ @item{ @scheme[child] and @scheme[parent] are @scheme[equal?]. } @item{ @scheme[parent] is an interface and @scheme[child] extends it. } @item{ @scheme[parent] is a registered ancestor of @scheme[child] in the type hierarchy. } @item{ @scheme[child] is an interface and extends some other interface that is a registered descendant of @scheme[parent] in the type hierarchy. } @item{ @scheme[child] and @scheme[parent] both satisfy @scheme[dict?], all keys from the @scheme[parent] are present in the @scheme[child] and all values in the @scheme[child] are @scheme[derived?] from the corresponding values in the @scheme[parent]. } } } @defproc*[( [(derive [child any/c] [parent (not/c (or/c class? interface?))]) void?] [(derive [h hierarchy?] [child any/c] [parent (not/c (or/c class? interface?))]) hierarchy?] )]{ Registers a direct @scheme[parent] of a @scheme[child] in a value hierarchy. Updates the descendants and ancestors relations accordingly. Before the new relation is registered, the child is converted to an interface using @scheme[class->interface], if it is a class. The parent may not be a class or interface. Inheritance from classes or interfaces must be done through the object system. If the @scheme[child] already derives from the @scheme[parent] or if the new inheritance relation would create a cycle, this procedure signals an error. If the two argument form of the procedure is used, the new modified type hierarchy is based on the global hierarchy and replaces it. In the three argument form, the new hierarchy is returned. The original hierarchy object is never modified by this operation. } @defproc*[( [(underive [child any/c] [parent (not/c (or/c class? interface?))]) void?] [(underive [h hierarchy?] [child any/c] [parent (not/c (or/c class? interface?))]) hierarchy?] )]{ Removes a direct @scheme[parent] of a @scheme[child] from a value hierarchy. Updates the descendants and ancestors relations accordingly. Before the old relation is unregistered, the child is converted to an interface using @scheme[class->interface], if it is a class. The parent may not be a class or interface. Inheritance from classes or interfaces must be done through the object system. If the @scheme[child] isn't derive from the @scheme[parent], this procedure signals an error. If the two argument form of the procedure is used, the new modified type hierarchy is based on the global hierarchy and replaces it. In the three argument form, the new hierarchy is returned. The original hierarchy object is never modified by this operation. }