Warning: This discussion may seem more complex than it really is.
Existing protocols such as HTTP, SMTP, or SOAP has similar issues but
MIME-based protocols often solve the same problem on a case-by-case
basis instead of defining a consistent solution. Case-by-case
decisions vary slightly, leading to complex and often incompatible
implementations. We are trying to come up with a consistent design,
nothing else.
On Wed, 21 May 2003, Martin Stecher wrote:
Also, the named-parameter syntax allows only for one value. Do you
think we should change that to
anonym-parameters = values
named-parameter = CRLF name ":" values
values = 1*(SP value)
to better match MIME capabilities? Or is one value per name enough?
Preparing for value lists is a good idea. But what about using a
different list separator character? Comma? That could also allow to
introduce lists as values for anonym-parameters if we'll ever need
them.
SP can be used to separate positional arguments (if we want to support
them in named-parameters). Let's call positional "structures" because
in a structure, you usually know positions of every member. Comma
should be used to separate list items (if we want to support lists).
Structure: An ordered collection of items. Minimum size is known.
Each item usually has a different meaning. Extensions may
add items by "appending" them to the end of the collection.
List: An ordered collection of items. Minimum size is zero.
Each item has the same type and meaning. Extensions are
not possible (adding more items is the basic building mechanism
not an extension).
There are several decisions to make:
1. Should we allow structures?
result: code phrase
2. Should we allow lists?
list: i1,i2,i3
3a. Should we allow one-level nesting of non-atoms?
list-of-lists: (i1,(j1,j2,j3),i3)
list-of-structures: ({x1 y1},{x2 y2},{x3 y3})
structure-of-lists: {(i1,i2) (x1,x2,x3)}
3b. Should we allow deeper nesting?
of-of-of: {({x1 y1},{x2 (y21,y22,y23)},{x3 y3}) b c {d e}}
My current preferences are
1. yes, but add curly braces: {x y}
2. yes, but add parens: (i1,i2,i3)
3. yes, but discourage casual use and limit depth to 3-4 levels.
Arguments regarding structures
------------------------------
OCP already uses structures for anonymous parameters (or, at
least, current use can be interpreted that way). Result
reporting can use a {code prase} structure. Negotiation may
benefit from structures because they are handy to express
[min,max] ranges (as a {min max} structure).
I would like to add curly braces to make structures visually
explicit and to simplify parsing.
Arguments regarding lists
-------------------------
OCP already needs lists to represent, for example, a list of
service IDs to be applied or a list of service IDs that have
been applied to an application message. Negotiation mechanism
may benefit from lists of "allowed profiles" as well.
In my experience, relying on parameter name repetition to
represent multiple values is error prone because implementors
forget which name can be repeated or just fail to handle
repetitions right. We have seen many violations related
to this technique in HTTP. One name, one (possibly complex)
value is a better technique, IMO.
I would like to add parens to make lists visually explicit and
to simplify parsing.
Arguments regarding nesting
---------------------------
I would rather not allow nesting, but I have a specific
example that may require nesting. I expect more examples
like that will crop up later.
During negotiations, a processor needs to offer a list of
"profiles" to the callout server. Each profile is a
{feature-id parameters} structure. The server may not
be able to make a selection (select the best profile)
without seeing the entire list first. We have two
options to implement this:
a) multiple messages with a special grouping mechanism:
P: group-start;
P: offer profile1;
P: offer profile2;
P: offer profile3;
P: group-end;
S: ack profile2;
b) allow nesting:
P: offer (profile1,profile2,profile3);
S: ack profile2;
Clearly, option (b) is much more natural. From implementation
point of view option (a) is likely to be supported using
some kind of profile list anyway. However, with (a) we
have a lot more implicit state to worry about.
On the other hand, if we allow nesting, then the job of
skipping irrelevant/unsupported parameters will be more
difficult. This is especially true if we allow multiple
levels of nesting. That is why I would recommend limiting
nesting levels at 3 or 4: MUST support N levels and MUST
treat more than N levels as syntactically invalid.
Resulting syntax
----------------
anonym-parameters = SP value
named-parameters = 1*named-parameter
named-parameter = CRLF name ":" SP value
value = integral / structure / list
integral = bare-value / quoted-value
structure = "{" *(SP value) "}" ; spaced values
list = "(" *("," value) "}" ; comma-separated values
Examples
--------
connection-start;
i-am-here {};
i-am-here {xid};
i-am-here {xid amid};
offer ({url1 p1},{url2 p21 p22 p23});
ack {url1 p1};
Please comment.
Thank you,
Alex.