Template-defining template
Since both an (OTTR-RDF) template's definition and expande body is just a set of triples, we can define a template which expansion is a template definition. For instance as:
Define(template, args, ins1, ins1Args, ins2 --o, ins2Args --o) :: {
template a ottr:Template;
ottr:withVariables args .
[] a ottr:TemplateInstace;
ottr:templateRef ins1;
ottr:withValues ins1Args .
[] a ottr:TemplateInstace;
ottr:templateRef ins2;
ottr:withValues ins2Args .
}
assuming we have a template on the form Triple(s, p, o) :: { s p o . }, to allow for triples in body.
However, in the current OTTR-spec the above definition is not well-defined, as the head of the template is not ambiguous (we have two elements with rdf:type ottr:Template). There are several ways around this problem, e.g. we can use quads/named graphs to explicitly denote the head and body of the template:
:HEAD {
ottr:define a ottr:Template;
ottr:hasParameter [ ottr:index 1; ottr:variable :Template ] ,
[ ottr:index 2; ottr:variable :Args ] ,
[ ottr:index 3; ottr:variable :Ins1 ] ,
[ ottr:index 4; ottr:variable :Ins1Args ] ,
[ ottr:index 5; ottr:variable :Ins2; ottr:optional true ] ,
[ ottr:index 6; ottr:variable :Ins2Args; ottr:optional true ] .
}
:BODY {
:Template a ottr:Template;
ottr:withVariables :Args .
[] a ottr:TemplateInstace;
ottr:templateRef Ins1;
ottr:withValues Ins1Args .
[] a ottr:TemplateInstace;
ottr:templateRef Ins2;
ottr:withValues Ins2Args .
}
We can also introduce a new ottr:TemplateTemplate-class which instances can have ottr:Template-s in body. Or, we could just implement Define explicitly in lurta, without a "normal" definition.
The Define-template above only takes two arguments, and must therefore be nested to allow for more than two instances in a body. An alternate form which removes this restriction, but which needs more complex list-functionality (zip) can be defined (in quasi-DL syntax) as:
Define(name, params, argss, ts) :: { "name(params) :: { zip(ts, argss) } " . }