Date: 4. 4. 04
Expires: when 1.0 is ready
1995 - 2011
C. von Loesch

Variable Modifiers for PSYC and MMP


Status of this Memo

This document describes portions of version 0.99 of the PSYC Protocol for SYnchronous Conferencing. You may consider it an Internet-Draft and as such subject to all provisions of Section 10 of RFC2026 except that the right to produce derivative works is not granted. In all matters of intellectual property rights and procedures, the intention is to benefit the Internet community and the public at large, while respecting the design decision to keep the original author of the protocol in charge. We don't like the bloat effects other efforts are experiencing. Only if you have developed an application in accordance to this specification you may call it PSYC-compliant to the version mentioned above.


This document describes the syntax of variable modifiers as used by PSYC and its carrier protocol MMP. Variables are semantically comparable to RFC822 headers as they are popular with text-based protocols like HTTP and SMTP, but kept in a more compact syntax.


MMP or PSYC modifiers are defined as follows:
    {modifier} :=
	  "=" {type}* {variable} [ "\t" {arguments} "\n" ]*
	| "+" {type}* {variable} [ "\t" {arguments} "\n" ]*
	| "-" {type}* {variable} [ "\t" {arguments} "\n" ]*
	| ":" {type}* {variable} [ "\t" {arguments} "\n" ]*
	| "?" {type}* {variable} [ "\t" {arguments} "\n" ]*
	| {glyph} {opaque string} [ "\t" {opaque string} "\n" ]*
Your implementation may also accept a space character instead of the tab character ("\t"), but no application should rely on that. It may only be useful for debugging. It is legitimate to make a parser that only accepts the tab character as the grammar above suggests. Variable names follow the Keyword Naming conventions of PSYC and MMP as described in its own document.

Variable arguments may be missing or split over several lines.

All other glyphs are available for experimental extensions, not for widespread use though. Variable modifiers using unknown glyphs SHOULD be ignored silently.


    {type} := "@" | "|" | "$"
NEW: Types are a new extension which avoids such naming tricks such as _list. Currently they are not necessary for basic applications, so they are available only upon negotiation of the _types module.

The default is to have no type glyph, which means the value of the variable can be interpreted as a string or as a number where appropriate. However when a type glyph is present, it indicates that the following data is structured as follows:

"@" stands for an array. All the values are kept in one {argument} seperated by a ";" semi-colon, so you can create the array in your respective programming language simply by splitting at the semi-colon. Data may not contain a semi-colon in arrays.

"|" stands for a list. The list is defined over several lines, each line being an {argument} consisting of

{key} "\t" {value}
. The parser should pass this information on to the applications in form of both a hash of key and value, but also an array of keys to keep the order intact. {value} may not contain newlines.

Syntactically any compound of types is possible, but we shall only define the combination of "|@" as being a list of arrays. We need this for the room member lists, for instance.

"$" indicates a transparent variable. Useful for binary data or any situations where the content may contain characters which would otherwise be misunderstood by the syntax. The {argument} for a {variable} prefixed by "$" is

{length} "\t" {data}
where {length} is the decimal amount of octets contained in {data} to be read without parsing.


Receiption of variable information SHOULD be passed to the target object of the message by doing method calls on it. The technique used to translate the combination of glyph and variable into a method name works like this:

Warning: Most implementations do not use methods like this, they simply operate on the variables at parsing time. The final results are the same however. So the spec needs an update here. TODO

"=" triggers a method "_assign_{variable}"
"+" triggers a method "_augment_{variable}"
"-" triggers a method "_diminish_{variable}"
":" triggers a method "_set_{variable}"
"?" triggers a method "_query_{variable}"


Methods of the _assign family are used to set or reset variables available in the appropriate operative layer and its namespace (which are different for PSYC and MMP, although the syntax is the same). Methods of the _augment family append arguments to existing variables, which must be of the _list family to be applicable. Methods of the _diminish family remove elements from such _list variables.

Methods of the _set family temporarely give a value to a variable valid for this message or packet only. When stateless communication is selected, only the _set methods may be used!

TODO: Semantics of _query are as yet undefined.

In many cases modification of variables will also trigger appropriate functionality as specified with the definition of those variables.


PSYC defines an extension to the variable modifiers syntax for its _struct_group variable.


Is it bad to talk in implementation terms like methods? Or is it useful that a PSYC variable may be set both via a :_variable modifier and a _set_variable method call. Should this be ensured or forbidden? So far the semantic distinction is, that while a method call is immediately delivered to the target object, a variable modification is normally silently applied to the set of variables, and delivered to the target object only when the next method call comes in. Yet again the protocol syntax allows for messages to contain variable modifications only - so one could deliver the changes each time a message is finished, even if no method has been called. The problem with that, is that identifying which variables have been modified can turn out hairy.