The ArchetypeClass participates in the ADT supers map that defines the inheritance hierarchy, and also appears uniquely in the ADT classes registry set. It is roughly the ADT equivalent of what one might normally consider a "Class" to be in most (mere) OO coding languages, but it is not exactly the same, because it can be "super functional" thanks to the Wolfram Language.
There are two main ArchetypeClass creation cases:
Case 1: Direct pattern injection: The ArchetypeClass is created by "invoking" or "calling" its immediate concrete super parent definer to create an ADT-Class on-the-fly; it does not have its own "hard-coded" definer:
ClearAll[ADT$TestString];
pattern = adt$def$ADT[
ADT$TestString,
"DEVEL: ADT for a scalar String. Typically only used for testing.",
ADT$TestString[$$_String],
True (*!isAllSuper*)
];
ADT$TestString /: stringLength[pattern] := StringLength[$$];
[© Copyright Brad Bird and PIXAR or someone, reproduced solely for educational purposes.]
Case 2:The ArchetypeClass has its own "hard-coded" definer. In this example the definer supports templated pattern injection with a default (fallback):
ClearAll[ADT$Map];
Clear[adt$def$ADT$Map];
adt$def$ADT$Map[
class_,
$usage_String,
template_:None,
isDirectSuper:(True|False):True
] := With[
{
pattern = If[template===None, class[$$_Association],template]
},
adt$def$ADT[class,$usage,pattern,class===ADT$Map];(*!isAllSuper*)
If[isDirectSuper,adt$addSuper[class,ADT$Map]];
(* Define ADT-Methods *)
class /: lookup[pattern,$key_String] := get[$$[$key]];
class /: keys[pattern] := Keys[$$];
class /: keysHeads[pattern] := develKeysHeads[$$,class];
class /: keyDrop[pattern,$key_String] := KeyDrop[$$,$key];
class /: dataset[pattern] := Dataset[$$];
...
}];
pattern
];
Then explicitly register register the Archetype for ADT$Map
:
adt$def$ADT$Map[
ADT$Map,
"Abstract ADT base for an Association with any key or RHS kind."
];
Note that it respects this POLICY:
If you come from a regular OO language background, you might consider the above "hard-coded". Don't forget though, in the Wolfram Language, it's just an Expression, and such can also be generated EASILY.
Dr Darren says:Maybe now you are beginning to understand the potential of it all! Generics? You ain't seen nothing yet!Note that no specific pattern was injected into the template pattern slot, it takes the default (which you can see if you "invoke" the above without a semi-colon):
adt$def$ADT$Map[
ADT$Map,
"Abstract ADT base for an Association with any key or RHS kind."
]
ADT$Map[$$_Association]
The Head
will be the ADT$Map
:
Head[%]
ADT$Map
The Head
will also be the same for a specific usage:
i: ADT$Map[<|"a" -> 1, "b" -> 2|>]
o: ADT$Map[<|a -> 1, "b" -> 2|>]
i: Head[%]
o: ADT$Map
Which is of course how the ADT "strong typing" works. You can now use it like this, where keys
is a pre-generated ADT-Method UpValue:
i: fGet[a_ADT$Map] := keys[a];
i: ADT$Map[<|"a" -> 1, "b" -> 2|>]
o: {a,b}
The XL$XL
(which is from a client package) is a special case, it's a Webel ADT-MemberInterface:
Its ArchetypeClass registration is performed via its definer as:
xl$def$XL$XL[class_,$usage_String,pattern_,isDirectSuper:(True|False):True] :=
With[ {...}, ..
];
xl$def$XL$XL[
XL$XL,
"XL ADT Membership interface for all OpenXML handler classes.",
XL$XL[A`$$:None],
False (*!*)
];
The A`$$
is used here rather than just $$
because: