Print

Print


Lars,

 > > Thinking along those lines brings up a couple of questions:
 > > 
 > > 
 > > What is the signature of an object type?
 > > ========================================
 > > 
 > [snip]
 > > 
 > > Coming back to the question: which if the following should be the defined
 > > behavior?
 > > 
 > > a) the object type defines the semantic of an object (of that type) including
 > >    the semantics of its mandatory arguments. The optional dictionary is not
 > >    considered and can be used in different ways by objects belonging to the
 > >    same object type.
 > > 
 > > b) the dictionary is part of the definition of an object type, ie the keys it
 > >    can contain and their semantics are defined by it, i.e., two objects only
 > >    belong to the same object type if their semantics are the same on all levels
 > > 
 > > c) kind of in between: the object type can define the semantics of certain keys
 > >    in which case all objects of this type have to support exactly that
 > >    interpretation, however an object is free to accept/interpret additional
 > >    keys.
 > 
 > I'd prefer (c), but I'd also like to remark that you seem to presume a 
 > rather rigid view of compatibility here; in RFC-speak, I get the 
 > impression that you're thinking in terms of MUST and SHALL, even though 
 > much of the material covered would perhaps be better suited by SHOULD 
 > or MAY.

that makes two of us (prefering c). As to rigid view of compatibility:
perhaps. There is nothing really that allows us to enforce rigid compatibility
on semantics, other than documenting the semantics and asking people/template
writers to obey them (for their own good).

This is a similar situation like with the 2e idea of document
classes. article.cls defined a certain type of document class and to be able
to reuse a document written for it with another class the other class would
need to offer the same semantics. But there wasn't any way to enforce that, so
that we nowadays have a number of classes that are nearly article but not
quite (like handling the abstract env as part of the title or not)

So the best one can do is to carefully document the object type its mandatory
arguments and their semantics (and a list of standard named arguments and
their expected semantics) and to ask for any template that nominally
implements that object type to follow the spec.


 > Some general principles:
 > 
 > 1. It's a good thing if the standard heading object type declaration 
 > comes with with a comprehensive list of "standard" key names for 
 > template authors to make use of when appropriate, but it's no disaster 
 > if something rather common should happen to be missing from this list; 
 > later releases can always make amendments.

agreed

 > 2. If the value associated with a key is not simply supposed to be of 
 > type "some piece of text"[*], then it MUST be specified what the type 
 > of that data is. E.g., if the "author" key is generally an 
 > \and-separated list of author names, then whatever authority is 
 > specifying the "author" key MUST be clear about this. For a key as 
 > basic as "author", that authority would probably be (the documentation 
 > for) the xpackage defining the "heading" object type, but for other 
 > keys it could be (the documentation of) the template that makes use of 
 > this key, or (ditto) the package/class defining the user level commands 
 > that includes it in the dictionary.

I think for any named key explicitly mention with the object type as a
standard named key that should have its semantics documented with the document
type with the intention that this is binding for all templates of this object
type. Of course a template might decided to not use the key at all, but if
used the semantics should be as in the object type spec.

For additional keys they should then be specified on the individual templates

 > 3. One shouldn't specify something if one doesn't have a good 
 > understanding of what that specification should say. It's much easier 
 > to add a specification for a key at version .2 or .3 than to admit at 
 > version .3 that "the spec we've had for this since version .0 is 
 > basically useless, so from now on we'll do it like this instead".

agreed



 > > How should the dictionary be specified?
 > > =======================================
 > > 
 > > Basically I see two ways:
 > > 
 > > a) passing the dictionary in a mandatory argument, e.g., the first or the last
 > > one, for example like
 > > 
 > >   \foo {...} {...}
 > >        {
 > >         \ToDictionary{key1}{val1}
 > >         \ToDictionary{key2}{val2}
 > >         ...
 > >         \ToDictionary{keyn}{valn}
 > >        }
 > 
 > I think this is the way to go. For objects, I furthermore think it 
 > should typically be the last argument, since this makes it easier to 
 > visually connect the other arguments with the underlying command, i.e., 
 > it improves code readability.

agreed on the first not sure on the second point. The advantage of using the
last argument is clear, the disadvantage being that inside each template in
which you refer to a named key you potentially have different argument number,
eg in one type of template it will be \GetKey{foo}{#3} and in the next
\GetKey{bar}{#5} but perhaps that is less an issue

 > > Should there be some inheritance of dictionaries?
 > > =================================================
 > > 
 > > If the dictionary is not fully tied to the object type (ie case a) or c) in
 > > the first question) we have two different possibilities to specify the
 > > dictionary behavior:
 > 
 > I think dictionary processing should be a generic functionality, rather 
 > than tied in with instance invokation.
 > 
 > As for inheritance, the dictionary semantics sketched above make it 
 > trivial to override or provide defaults for keys in a parent 
 > dictionary: just prepend or append respectively the necessary 
 > \ToDictionary items to the base dictionary.

agreed, it is probably best to do any inheritance explicitly when desired. As
long as the dictionary comes as an argument that is trivial to do.

frank