As an addendum to Sjoerd's great answer, I would simply like to show a use case for defining a custom data type and then using TagSet
to create what is called an abstract data type.
In many cases we would like to be quite sure, that our data have a certain form (e.g. do some type checking). Mathematica nicely supports this by constraining patterns to those with a certain Head
(see Specifying Types of Expressions in Patterns):
func[ input_myDataType ] := ...
Here, func
will only accept expressions that have the form myDataType[ e1, e2, ... ]
. Having constructed any myDataType
"object" in a reliable way (e.g. from basic inputs with very concise and strict pattern matching restrictions) greatly helps to prevent errors down the road.
While Associations are really great for building composite data types, it will usually not suffice to simply check an expression for the head being Association
- instead, we have to look at least at some key(s) as well to be certain.
But, we may (with a maybe negligible disadvantage regarding speed) combine data type filtering using an expression's Head
with the flexibility of associations:
data = Association @@ Table[ "Key" <> ToString @ i -> i , {i,1000} ];
myData = myDataType[ data ];
myDataType/: (key_String)[ data_myDataType ] := Lookup[ data[[1]], key ]
Now, we can elegantly write:
"Key500" @ myData
(* 500 *)
Note, that this is really quite close to object-oriented programming:
class/: method[ instance_class, args___ ] := "What to do"
Instead of overloading some method to work with a new class, we can simply tie the method to the definition of the class as an UpValue
.
Upvalues
are quite important for defining custom (abstract) data types: "Upvalues
are an indispensable tool to overload various functions (built-in or user-defined) on custom data types. They provide the only safe way to do that, in fact." $\endgroup$Derivative
of a functionf
to the symbolf
instead of toDerivative
, so thatClear[f]
clears the derivative definition. (E.g.f /: Derivative[1][f] := #^2 &; D[f[x], x]
) $\endgroup$