aboutsummaryrefslogtreecommitdiff
path: root/doc/context-types.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/context-types.html')
-rw-r--r--doc/context-types.html1138
1 files changed, 1138 insertions, 0 deletions
diff --git a/doc/context-types.html b/doc/context-types.html
new file mode 100644
index 00000000..7ac29205
--- /dev/null
+++ b/doc/context-types.html
@@ -0,0 +1,1138 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="generator" content="AsciiDoc 8.4.4" />
+<title>A high-level type system for the Free Desktops</title>
+<style type="text/css">
+/* Debug borders */
+p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
+/*
+ border: 1px solid red;
+*/
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+tt {
+ color: navy;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ font-family: sans-serif;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+
+div.sectionbody {
+ font-family: serif;
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+
+pre {
+ padding: 0;
+ margin: 0;
+}
+
+span#author {
+ color: #527bbd;
+ font-family: sans-serif;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+span#email {
+}
+span#revision {
+ font-family: sans-serif;
+}
+
+div#footer {
+ font-family: sans-serif;
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+div#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+div#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+div#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.5em;
+ margin-bottom: 2.5em;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-family: sans-serif;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid silver;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid silver;
+ background: #f4f4f4;
+ padding: 0.5em;
+}
+
+div.quoteblock {
+ padding-left: 2.0em;
+ margin-right: 10%;
+}
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock {
+ padding-left: 2.0em;
+ margin-right: 10%;
+}
+div.verseblock > div.content {
+ white-space: pre;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 2px solid silver;
+}
+
+div.exampleblock > div.content {
+ border-left: 2px solid silver;
+ padding: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+div.imageblock img { border: 1px solid silver; }
+span.image img { border-style: none; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead {
+ font-family: sans-serif;
+ font-weight: bold;
+}
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+@media print {
+ div#footer-badges { display: none; }
+}
+
+div#toctitle {
+ color: #527bbd;
+ font-family: sans-serif;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+/* Workarounds for IE6's broken and incomplete CSS2. */
+
+div.sidebar-content {
+ background: #ffffee;
+ border: 1px solid silver;
+ padding: 0.5em;
+}
+div.sidebar-title, div.image-title {
+ color: #527bbd;
+ font-family: sans-serif;
+ font-weight: bold;
+ margin-top: 0.0em;
+ margin-bottom: 0.5em;
+}
+
+div.listingblock div.content {
+ border: 1px solid silver;
+ background: #f4f4f4;
+ padding: 0.5em;
+}
+
+div.quoteblock-attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock-content {
+ white-space: pre;
+}
+div.verseblock-attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+
+div.exampleblock-content {
+ border-left: 2px solid silver;
+ padding-left: 0.5em;
+}
+
+/* IE6 sets dynamically generated links as visited. */
+div#toc a:visited { color: blue; }
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+window.onload = function(){generateToc(2)}
+/* Author: Mihai Bazon, September 2002
+ * http://students.infoiasi.ro/~mishoo
+ *
+ * Table Of Content generator
+ * Version: 0.4
+ *
+ * Feel free to use this script under the terms of the GNU General Public
+ * License, as long as you do not remove or alter this notice.
+ */
+
+ /* modified by Troy D. Hanson, September 2006. License: GPL */
+ /* modified by Stuart Rackham, October 2006. License: GPL */
+
+function getText(el) {
+ var text = "";
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
+ text += i.data;
+ else if (i.firstChild != null)
+ text += getText(i);
+ }
+ return text;
+}
+
+function TocEntry(el, text, toclevel) {
+ this.element = el;
+ this.text = text;
+ this.toclevel = toclevel;
+}
+
+function tocEntries(el, toclevels) {
+ var result = new Array;
+ var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
+ // Function that scans the DOM tree for header elements (the DOM2
+ // nodeIterator API would be a better technique but not supported by all
+ // browsers).
+ var iterate = function (el) {
+ for (var i = el.firstChild; i != null; i = i.nextSibling) {
+ if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
+ var mo = re.exec(i.tagName)
+ if (mo)
+ result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
+ iterate(i);
+ }
+ }
+ }
+ iterate(el);
+ return result;
+}
+
+// This function does the work. toclevels = 1..4.
+function generateToc(toclevels) {
+ var toc = document.getElementById("toc");
+ var entries = tocEntries(document.getElementsByTagName("body")[0], toclevels);
+ for (var i = 0; i < entries.length; ++i) {
+ var entry = entries[i];
+ if (entry.element.id == "")
+ entry.element.id = "toc" + i;
+ var a = document.createElement("a");
+ a.href = "#" + entry.element.id;
+ a.appendChild(document.createTextNode(entry.text));
+ var div = document.createElement("div");
+ div.appendChild(a);
+ div.className = "toclevel" + entry.toclevel;
+ toc.appendChild(div);
+ }
+ if (entries.length == 0)
+ document.getElementById("header").removeChild(toc);
+}
+/*]]>*/
+</script>
+</head>
+<body>
+<div id="header">
+<h1>A high-level type system for the Free Desktops</h1>
+<div id="toc">
+ <div id="toctitle">Table of Contents</div>
+ <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
+</div>
+</div>
+<div id="preamble">
+<div class="sectionbody">
+<div class="paragraph"><p>Desktop environments are not just for starting applications anymore.
+Data is flowing freely between well-integrated components, and the
+easier the data flows, the better the integration of the components.</p></div>
+<div class="paragraph"><p>Not all components are written in the same programming language, of
+course, and when letting data flow between them, it needs to be
+represented in many different ways. For example, GConf stores values
+differently than they travel over D-Bus, which is different again from
+how they are passed as GValues to signal handlers, which is different
+from how Perl wants to store it.</p></div>
+<div class="paragraph"><p>The desktop environment is heading towards a cooperative, dynamic
+environment, and it needs a rich and strong type system to tie its
+components together. Sending lines of text over pipes and matching
+them against ad-hoc regular expressions just doesn&#8217;t cut it.</p></div>
+<div class="paragraph"><p>In an attempt to define such a common type system, this document
+collects many different systems for representing values, and unifies
+them by mapping the common dynamic type system into them.</p></div>
+<div class="paragraph"><p>The common type system defined here is rich enough to represent any
+reasonable value; it&#8217;s roughly equivalent to what dynamic languages
+like Perl and Python have.</p></div>
+<div class="paragraph"><p>But it goes one crucial step further: it allows the definition of new
+abstract, intentional types. Intentional types give additional
+information about a value that is not available from the
+representation alone.</p></div>
+<div class="paragraph"><p>For example, a integer can be used to denote a point in time by saying
+that it is the number of seconds since a certain epoch. All places
+that interact with such a value need to agree on this intention.</p></div>
+<div class="paragraph"><p>This agreement can happen informally, via documentation or just plain
+common sense. Nothing wrong with that. It is, however, also helpful
+to formalize this so that documentation can be precise without much
+extra effort, up to a level where the machine itself is able to check
+whether everybody agrees on the intentional types.</p></div>
+<div class="paragraph"><p>The age old battle between static and dynamic types also matters here:
+how much type information should be associated with the values
+themselves? The boundary is exactly between intentional and
+representational types. Intentional types are those that only the
+programmer or compiler know about, representational types are those
+that are only known at run-time.</p></div>
+<div class="paragraph"><p>In a completely statically typed language, we only have raw bytes at
+run-time without any representational type information. All parts of
+the program need to agree that the intention is for those four bytes
+over there to be used as a 32-bit integer. Statically typed programs
+are littered with declarations of intentional types, and language
+processors use them to (more or less) check program consistency and to
+select the right division instruction based on whether the four bytes
+over there are intended to be a signed number or an unsigned one.</p></div>
+<div class="paragraph"><p>In a dynamically typed language, values carry a lot of
+representational type information. Code can easily be polymorphic and
+do different things depending on whether a value is an integer or a
+string. It can also perform consistency checks at run-time, which is
+more robust than doing it at compile time, but doesn&#8217;t go as far since
+intentional types are not available.</p></div>
+<div class="paragraph"><p>Dynamic languages often don&#8217;t have any means to declare intentional
+types for the benefit of the compiler; they only exist in the head of
+the programmer who expresses them by selecting the right operation
+manually. For example, if a string is intended to be a URL, you need
+to use <em>utils.net.web.url.get_scheme (url)</em> explicitly. If the
+intentional type could have been declared in the language, it could
+have selected the right function automatically from just <em>url.scheme()</em>.</p></div>
+<div class="paragraph"><p>Thus, and coming back to the ground now, we define a concrete type
+system here with a rich representational part and a lightweight and
+flexible intentional part.</p></div>
+<div class="paragraph"><p>For the representational part, we define how it is implemented for a
+number of existing value systems. For the intentional part, we define
+how it can be translated into a number of languages, both those with
+static type declaration and those where intent is mainly expressed by
+manually selecting the right operations.</p></div>
+<div class="paragraph"><p>Intentional types are not optional; they are generally needed to make
+sense of values. A programmer learns about them by reading
+documentation; if a debugging tool needs to find out a intentional
+type at run-time, there must be some way to find it.</p></div>
+<div class="paragraph"><p>This means that declaration languages like D-Bus introspection
+facilities and GConf schemas need to be extended to support our
+intentional types. Thus, purely declarative languages like these are
+also included in our list of supported languages.</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><tt>/* Witty example here. */</tt></pre>
+</div></div>
+<div class="paragraph"><p>We also give a list of common intentional types, of course.</p></div>
+<div class="paragraph"><p>This document then has three dimensions of extensibility:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+A new value system can be added by defining how the representational
+ part of the common type system maps to it.
+</p>
+</li>
+<li>
+<p>
+A new language can be added by defining how intentional types are
+ implemented in it, and by implementing all common intentional types.
+</p>
+</li>
+<li>
+<p>
+A new common intentional type can be added by defining it and
+ implementing it in all languages.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The representational part of the common type system is not supposed to
+change frequently, but adding a new intentional type should be
+considered routine.</p></div>
+<div class="paragraph"><p>The representation part of the common type system is restricted by the
+lowest common denominator of all the value system implementations that
+we want to include. We don&#8217;t want to distort the existing value
+systems too much, and force people to write code that feels unnatural
+for them.</p></div>
+<div class="paragraph"><p>For example, not all value systems can directly represent complex
+numbers or multiple precision integers, but any grown up type system
+should include them. We solve this conflict by relying on the
+intentional types: Instead of grafting complex numbers onto every
+value system, we only define a intentional type for them.</p></div>
+<div class="paragraph"><p>Currently supported value systems: QVariant, D-Bus messages, GValue,
+GConfValue, GVariant, Python values, Perl values, JavaScript values,
+GKeyFile, JSON, YAML, Nepomuk ontologies, SQL, SparQL, Common Lisp
+values.</p></div>
+<div class="paragraph"><p>Currently supported languages: Python, Perl, JavaScript, Java, C#, C<tt>
+with QVariant, plain C</tt>, C with D-Bus/GValue/GConfValue/GVariant,
+plain C, Vala, D-Bus introspection, D-Bus IDL (didl), GConf schema,
+our own XML schema.</p></div>
+</div>
+</div>
+<h2 id="_representational_types">Representational types</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Converting a value from one representation to another is not
+guaranteed to be loss-less: if you convert the value back, it might be
+different and even have a different type. Intentional types are used
+to make sense of the value anyway. [ XXX - so maybe we shouldn&#8217;t
+bother with representational types at all&#8230; ]</p></div>
+<div class="paragraph"><p>Whenever there is a choice of representation in the following table,
+it should be taken to mean: Represent the value with the first
+alternative in the list that is possible, even if that loses
+precision.</p></div>
+<div class="paragraph"><p>For example, a 64 bit signed integer is represented in GConf as a
+"int" if it fits, and as a "double" if not. It will always fit into a
+double, but it might mean chopping off some low bits.</p></div>
+<div class="paragraph"><p>What we are defining then is nothing more than the rules for
+converting values between different representations.</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+null
+</p>
+<div class="paragraph"><p>The null value.</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::Null
+D-Bus: '()'
+GValue: G_TYPE_NONE
+GConf: empty GCONF_VALUE_LIST with type GCONF_VALUE_BOOL
+GVariant: '()'
+Perl: undef
+Python 2: None
+CL: nil</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+bool
+</p>
+<div class="paragraph"><p>A boolean</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::Bool
+D-Bus: 'b'
+GValue: G_TYPE_BOOLEAN
+GConf: GCONF_VALUE_BOOL
+GVariant: 'b'
+Perl: number, 0 or 1.
+Python 2: number, 0 or 1.
+CL: nil or t</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+int32
+</p>
+<div class="paragraph"><p>Signed 32 bit integer</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::Int
+D-Bus: 'i'
+GValue: G_TYPE_INT
+GConf: GCONF_VALUE_INT
+GVariant: 'i'
+Perl: number
+Python 2: int
+CL: number</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+int64
+</p>
+<div class="paragraph"><p>Signed 64 bit integer</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::LongLong
+D-Bus: 'x'
+GValue: G_TYPE_INT64
+GConf: GCONF_VALUE_INT or GCONF_VALUE_DOUBLE
+GVariant: 'x'
+Perl: number
+Python 2: int or long
+CL: number</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+uint32
+</p>
+<div class="paragraph"><p>Unsigned 32 bit integer</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::UInt
+D-Bus: 'u'
+GValue: G_TYPE_UINT
+GConf: GCONF_VALUE_INT or GCONF_VALUE_DOUBLE
+GVariant: 'u'
+Perl: number
+Python 2: int or long
+CL: number</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+uint64
+</p>
+<div class="paragraph"><p>Unsigned 64 bit integer</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::ULongLong
+D-Bus: 't'
+GValue: G_TYPE_UINT64
+GConf: GCONF_VALUE_INT or GCONF_VALUE_DOUBLE
+GVariant: 't'
+Perl: number
+Python 2: int or long
+CL: number</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+double
+</p>
+<div class="paragraph"><p>Double precision floating point number</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::Double
+D-Bus: 'd'
+GValue: G_TYPE_DOUBLE
+GConf: GCONF_VALUE_DOUBLE
+GVariant: 'd'
+Perl: number
+Python 2: double
+CL: number</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+string
+</p>
+<div class="paragraph"><p>String of Unicode code points</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::QString
+D-Bus: 's'
+GValue: G_TYPE_STRING
+GConf: GCONF_VALUE_STRING, UTF-8.
+GVariant: 's'
+Perl: string
+Python 2: unicode
+CL: string</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+list
+</p>
+<div class="paragraph"><p>List of values</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::List
+D-Bus: 'av'
+GValue: G_TYPE_POINTER pointing to a GSList of GValues.
+ (XXX - find something better, must be somewhere.)
+GConf: GCONF_VALUE_LIST or chained GCONF_VALUE_PAIRs
+GVariant: 'av'
+Perl: array
+Python 2: list
+CL: list</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+map
+</p>
+<div class="paragraph"><p>Mapping from strings to values, with no duplicated keys.</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>QVariant: QVariant::Map
+D-Bus: 'a{sv}'
+GValue: G_TYPE_HASH_TABLE (?)
+GConf: Chain of GCONF_VALUE_PAIRs,
+ with the cars being a pair of GCONF_VALUE_STRING and an
+ arbitrary value.
+GVariant: 'a{sv}'
+Perl: hash
+Python: dict
+CL: alist</tt></pre>
+</div></div>
+</li>
+</ul></div>
+</div>
+<h2 id="_association_trees">Association trees</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>A map (or dictionary, or hashtable) is a useful data structure, and by
+nesting them you can express a lot of interesting things. Two things
+are missing however: maps do not preserve the order of their entries,
+and they don&#8217;t allow duplicate keys. These two things are often
+necessary.</p></div>
+<div class="paragraph"><p>So, we like to use lists insteads of maps and define a couple of
+conventions how to express associations between things with them. The
+resulting values are called "association trees".</p></div>
+<div class="paragraph"><p>An association tree always has a name (which is always a string), and
+has either a single value, or a list of subordinate association trees.</p></div>
+<div class="paragraph"><p>An association tree is represented as a list. The first element is
+the name. If the association tree is of the first form, then the list
+always has a second element, which is the value. In the second form,
+the remaining elements of the list after the name are the subordinate
+association trees.</p></div>
+<div class="paragraph"><p>A couple of example will hopefully show that this is all very simple:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+The first form, essentially a key/value pair:
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>[ 'foo', 12 ]</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+The second form, with two sub-trees:
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>[ 'foo', [ 'bar', 42 ], [ 'baz', 'quux' ]]</tt></pre>
+</div></div>
+</li>
+</ul></div>
+<div class="paragraph"><p>The second example can be interpreted as mapping the "key path"
+foo/bar to 12, and the path foo/baz to <em>quux</em>.</p></div>
+<div class="paragraph"><p>As you can see, the two forms of a assocation tree can not be reliably
+distinguished from each other just by looking at them. This tree</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>[ 'foo', [ 'bar', 12 ]]</tt></pre>
+</div></div>
+<div class="paragraph"><p>can be interpreted both as mapping foo to the value [ <em>bar</em>, 12 ], and
+as mapping foo/bar to 12. You have to know what is intended and use
+the right interpretation.</p></div>
+<div class="paragraph"><p>As a special case, a association tree with an empty list of sub-trees
+can be expressed just with a string, which is the name of the tree.
+Thus, the following two lines are equivalent:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>[ 'foo ' ]
+'foo'</tt></pre>
+</div></div>
+<div class="paragraph"><p>Language bindings for association trees usually offer the following
+operations:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>name (tree): returns the name of the tree (which is either the first
+ element of tree if it is a list, or tree itself if
+ it isn't)</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>value (tree): returns the value of the tree (which is the second
+ element of tree, which must be a list)</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>node (tree, name): returns the first sub-tree with the given name of tree.</tt></pre>
+</div></div>
+<div class="paragraph"><p>Usually, convenience functions are provided as well that make
+accessing values and nodes at the end of a key path less verbose:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>value (tree, name1) == value (node (tree, name1))
+value (tree, name1, name2) == value (node (node (tree, name1), name2))
+..etc..</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>node (tree, name1, name2) == node (node (tree, name1), name2))
+..etc..</tt></pre>
+</div></div>
+<div class="paragraph"><p>Of course, association trees are one of the pre-defined intentional
+types.</p></div>
+<div class="paragraph"><p>Association trees are very useful. This Desktop Types system uses
+them for type definitions, for example, and also for type references.</p></div>
+</div>
+<h2 id="_a_nano_dom">A Nano-DOM</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>Association trees (see above) can be used to represent a subset of
+XML. This is useful when the small subset suffices but you still want
+to be enterprise ready. Intentional type definitions use this subset,
+for example, and are thus easily handled at run-time.</p></div>
+<div class="paragraph"><p>Association trees tht are used to represent XML are called Nano-DOM
+here, since they can fulfill the role of a document object model.</p></div>
+<div class="paragraph"><p>Converting a piece of XML into its Nano-DOM representation proceeds
+according to simple rules:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+First, all attributes of elements are converted to child elements,
+ in order and at the beginning. Thus, the following XML fragments
+ are equivalent:
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;bar size="12"&gt;...&lt;/bar&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;bar&gt;&lt;size&gt;12&lt;/size&gt;...&lt;/bar&gt;</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+Then, text is turned into strings, and elements are turned into
+ association trees with the name of the tree being the name of the
+ element, and the remaining elements of the association tree list
+ being the children of the element. For example, this XML
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;foo&gt;hello&lt;/foo&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>would be turned into this Python value</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>['foo', 'hello']</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>When creating the strings for text, surrounding whitespace is
+removed.</tt></pre>
+</div></div>
+</li>
+</ul></div>
+<div class="paragraph"><p>More examples:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;key name="Example.Random"
+ type="string"&gt;
+ &lt;doc&gt;
+ A random property.
+ &lt;/doc&gt;
+&lt;/key&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>=&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>['key',
+ ['name', 'Example.Random' ],
+ ['type', 'string' ],
+ ['doc', 'A random property.']
+]</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;key name="Example.Random"&gt;
+ &lt;type&gt;
+ &lt;list type="number"/&gt;
+ &lt;/type&gt;
+&lt;/key&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>=&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>['key',
+ ['name', 'Example.Random' ],
+ ['type',
+ ['list', ['type', 'number' ] ]
+ ]
+]</tt></pre>
+</div></div>
+<div class="paragraph"><p>You can think of the Nano-DOM representation as a simple abstract
+syntax tree for XML.</p></div>
+</div>
+<h2 id="_intentional_types">Intentional types</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>The most important part by far of a intentional type definition is its
+documentation. The documentation is the thing that explains the
+intent to programmers, so that they can <em>reify</em> the abstract
+intentional type into concrete code. For example, by reading the
+documentation, they know how to write a C++ class for the intentional
+type and add useful methods to it, or how to write a UI widget that
+allows displaying and maybe high-level editing of values of that type.</p></div>
+<div class="paragraph"><p>Intentional types are <em>not</em> a static type system. They are only a
+tool for cross-referencing documentation. Sometimes, intentional
+types are mapped into a static type system and the compiler will then
+perform some additonal checks at compile time, and the code using the
+types might look more natural, but that is not the main goal of the
+intentional types.</p></div>
+<div class="paragraph"><p>In essence, intentional types use English as the <em>formal</em> language to
+express their definitions. Their documentation should basically be a
+description of the set of values that are permissible for this type
+(by referring to other already defined intentional types or the
+representational types from above), and what they mean. For example,
+the "calendar-time" type could say that only "uint64" values are
+allowed, and that they are the number of nano-seconds since midnight
+January 1, UTC.</p></div>
+<div class="paragraph"><p>Another example are enumerations: the documentation of
+"compass-direction" can say that the value is one of the four "int32"
+values 0, 90, 180, 270 where 0 means North, 90 means East, etc.</p></div>
+<div class="paragraph"><p>As shown in the examples, intentional types have names, so that you
+can refer to them in the documentation of other types and in other
+places that refer to intentional types, such as in D-Bus introspection
+declarations.</p></div>
+<div class="paragraph"><p>When other people refer to your type, they can provide a set of
+parameters to specialize it. You should document which parameters are
+meaningful and what they do, of course. You should also formally
+declare which paramaters are valid. (See below for concrete
+examples).</p></div>
+<div class="paragraph"><p>Type parameters allow us to define a small set of fundamental and
+general types, which can be instantiated to create a wide range of
+useful types. For example, there is a generic "int-enum" type that
+can be turned into a specific enumeration via its parameters. A
+single UI widget could be written for "int-enum" that is then
+(automatically) parameterized at run-time with the concrete set of
+choices. The "int-enum" type is defined so that its parameters
+include the text to use for each enumeration choice, and the UI widget
+will get access to these parameters at run-time.</p></div>
+<div class="paragraph"><p>A intentional type definition can specify a "base" type for itself, by
+referring to another intentional type. This base can be used to make
+the documentation a bit more formal, and of course to provide
+parameters for the base type. For example, the documentation for the
+"compass-direction" type would not need to explicitly say that the
+numbers are "int32"s; it would just declare its base to be "int32".
+Even better, it sould say that it&#8217;s actually a "int-enum" and specify
+the concrete values.</p></div>
+<div class="paragraph"><p>To recap: when referring to a type, you need to specify its name and
+you can optionally specify values for some or all of its parameters.
+Such a type reference is expressed as a association tree: the name of
+the tree gives the name of the referenced type, and the sub-trees give
+values for parameters. Of course, the name of such a sub-tree names
+the parameter, and the value of the sub-tree usually gives the value
+of that parameter.</p></div>
+<div class="paragraph"><p>Formally, however, it is up to the type definiton to say how a
+association tree that refers to it is being interpreted. The
+"string-enum" type, for example, does not define any parameters for
+itself; instead, it specifies that the sub-trees in a reference to it
+should be interpreted as naming the possible enumeration choices. (If
+that sounds too obscure, just ignore it for now. It will become
+clear.)</p></div>
+<div class="paragraph"><p>Type references are written in XML by following the Nano-DOM rules, of
+course.</p></div>
+<div class="paragraph"><p>A type definition is also expressed as an association tree. The name
+of such a tree is always the string "type", to identify it as a type
+definition. The following key paths can be used in a type definition:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+type/name (string)
+ The symbolic name of the type. Don&#8217;t use too fancy characters here.
+</p>
+</li>
+<li>
+<p>
+type/doc (string)
+ The documentation for the type.
+</p>
+</li>
+<li>
+<p>
+type/base (type)
+ The base type for this type. All values that are valid for this
+ type are valid for the base type, and if a piece of code does not
+ understand this type, it is allowed to use the base type instead.
+</p>
+</li>
+<li>
+<p>
+type/parms (node)
+ The parameters of this type, one per sub-tree of this node. If you
+ want to specify special rules for interpreting association trees
+ that refer to this type, just omit the type/parms node in the
+ definition.
+</p>
+</li>
+<li>
+<p>
+type/parms/&lt;p&gt;/doc (string)
+ The documentation for parameter &lt;p&gt;.
+</p>
+</li>
+<li>
+<p>
+type/parms/&lt;p&gt;/type (type)
+ The type for parameter &lt;p&gt;.
+ XXX - this doesn&#8217;t really work since XML can only express association trees.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>As an example, consider a hypothetical XML schema for describing
+key-value pairs. Let&#8217;s also assume that this schema follows our
+Nano-DOM rules. It has a "key" element which needs name, doc and type
+attributes. The "type" attribute should refer to an intentional type
+of course. We can describe a key for the current temperature,
+expressed as one of "low", "medium", "high", in the following ways.</p></div>
+<div class="paragraph"><p>First, we can refer to the predefined "three-level-enum" type, if
+there would be such a type. Documentation of the possible values is
+left to the definition of "three-level-enum", which presumably would
+tell us that they are the strings "low", "medium", and "high".</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;key&gt;
+ &lt;name&gt;Temperature&lt;/name&gt;
+ &lt;doc&gt;The current temperature.&lt;/doc&gt;
+ &lt;type&gt;three-level-enum&lt;/type&gt;
+&lt;key&gt;</tt></pre>
+</div></div>
+<div class="paragraph"><p>Using the Nano-DOM rules, this can be shortened to:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;key name="Temperature"
+ doc="The current temperature"
+ type="three-level-enum"/&gt;</tt></pre>
+</div></div>
+<div class="paragraph"><p>Instead of referring to the pre-defined "three-level-enum" type, we
+can instantiate a "string-enum" explicitly, which is one of the
+pre-defined generic types.</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;key name="Temperature"
+ doc="The current temperature"&gt;
+ &lt;type&gt;
+ &lt;string-enum&gt;
+ &lt;low doc="Brrrr"/&gt;
+ &lt;medium doc="Comfy."/&gt;
+ &lt;high doc="Siesta!"/&gt;
+ &lt;/string-enum&gt;
+ &lt;/type&gt;
+&lt;/key&gt;</tt></pre>
+</div></div>
+<div class="paragraph"><p>The common intentional types are defined <a href="core-types.html">here</a>.</p></div>
+</div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2009-12-08 18:28:03 EEST
+</div>
+</div>
+</body>
+</html>