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.html1384
1 files changed, 1384 insertions, 0 deletions
diff --git a/doc/context-types.html b/doc/context-types.html
new file mode 100644
index 00000000..d090e4a4
--- /dev/null
+++ b/doc/context-types.html
@@ -0,0 +1,1384 @@
+<!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.2.7" />
+<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,
+div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-right: 10%;
+ 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 {
+ margin-right: 0%;
+}
+div.listingblock > div.content {
+ border: 1px solid silver;
+ background: #f4f4f4;
+ padding: 0.5em;
+}
+
+div.quoteblock {
+ padding-left: 2.0em;
+}
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock {
+ padding-left: 2.0em;
+}
+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;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+div.olist > ol {
+ list-style-type: decimal;
+}
+div.olist2 > ol {
+ list-style-type: lower-alpha;
+}
+
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead {
+ font-family: sans-serif;
+ font-weight: bold;
+}
+tfoot {
+ font-weight: bold;
+}
+
+div.hlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hlist td {
+ padding-bottom: 15px;
+}
+td.hlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+}
+td.hlist2 {
+ vertical-align: top;
+}
+
+@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; }
+
+/* Because IE6 child selector is broken. */
+div.olist2 ol {
+ list-style-type: lower-alpha;
+}
+div.olist2 div.olist ol {
+ list-style-type: decimal;
+}
+</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>
+<title>A high-level type system for the Free Desktops</title>
+</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="para"><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="para"><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="para"><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't cut it.</p></div>
+<div class="para"><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="para"><p>The common type system defined here is rich enough to represent any
+reasonable value; it's roughly equivalent to what dynamic languages
+like Perl and Python have.</p></div>
+<div class="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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't go as far since
+intentional types are not available.</p></div>
+<div class="para"><p>Dynamic languages often don'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="para"><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="para"><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="para"><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="para"><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"><!-- Generator: GNU source-highlight 2.11.1
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-style: italic"><span style="color: #9A1900">/* Witty example here. */</span></span>
+</tt></pre></div></div>
+<div class="para"><p>We also give a list of common intentional types, of course.</p></div>
+<div class="para"><p>This document then has three dimensions of extensibility:</p></div>
+<div class="ilist"><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="para"><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="para"><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'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="para"><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="para"><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="para"><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="para"><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't
+bother with representational types at all&#8230; ]</p></div>
+<div class="para"><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="para"><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="ilist"><ul>
+<li>
+<p>
+null
+</p>
+<div class="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="_a_nano_dom">A Nano-DOM</h2>
+<div class="sectionbody">
+<div class="para"><p>The representational types can be used as a Nano-DOM for 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="para"><p>Converting a piece of XML into its Nano-DOM representation proceeds
+according to simple rules:</p></div>
+<div class="ilist"><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 quivalent:
+</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
+ lists with the first element being a string with the name 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="para"><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;uniform-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',
+ ['uniform-list', ['type', 'number' ] ]
+ ]
+]</tt></pre>
+</div></div>
+<div class="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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="para"><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 (as a map,
+incidentally).</p></div>
+<div class="para"><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's actually a "int-enum" and specify
+the concrete values.</p></div>
+<div class="para"><p>In a context where a type is expected:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>NAME - refers to type named NAME
+&lt;NAME&gt;PARM...&lt;/NAME&gt; - refers to type named NAME, specialized
+ with PARM...</tt></pre>
+</div></div>
+<div class="para"><p>Attributes for type definitions:</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>name - the name (string)
+parms - valid paramaters (map from parm name to map of ...)
+doc - documentation (either string, or a map language code -&gt; string)
+base - the base type (type)</tt></pre>
+</div></div>
+<div class="para"><p>As an example, consider a hypothetical XML schema for describing
+key-value pairs. Let'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="para"><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="para"><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="para"><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="para"><p>The common intentional types are defined in XML, as a list of "type"
+elements that have "name", "parms", "doc", and "base" child elements,
+as expected.</p></div>
+<div class="para"><p>In the following, we give the type definitions verbatim, as XML, as an
+extended example (and because the real XML definition of the types
+does not exist yet). In the future, this part of the document will be
+generated from the type definitions and will look nicer.</p></div>
+<h3 id="_fundamental_types">Fundamental types</h3><div style="clear:left"></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;typedef name="int32"&gt;
+ &lt;doc&gt;
+ A int32 value.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="int64"&gt;
+ &lt;doc&gt;
+ A int64 value.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="uint32"&gt;
+ &lt;doc&gt;
+ A uint32 value within the given limits.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="uint64"&gt;
+ &lt;params&gt;
+ &lt;min doc="Minimum value"/&gt;
+ &lt;max doc="Maximum value"/&gt;
+ &lt;params&gt;
+ &lt;doc&gt;
+ A uint64 value within the given limits.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="double"&gt;
+ &lt;params&gt;
+ &lt;min doc="Minimum value"/&gt;
+ &lt;max doc="Maximum value"/&gt;
+ &lt;params&gt;
+ &lt;doc&gt;
+ A double value within the given limits.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="string"&gt;
+ &lt;parms&gt;
+ &lt;must-match doc="Regular expression that must match"/&gt;
+ &lt;/parms&gt;
+ &lt;doc&gt;
+ A string value that matches the given regular expression.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="list"&gt;
+ &lt;params&gt;
+ &lt;min doc="Minimum length"/&gt;
+ &lt;max doc="Maximum length"/&gt;
+ &lt;params&gt;
+ &lt;doc&gt;
+ A list of arbitrary values, with the minimum and maximum
+ length given by the "min" and "max" parameters, respectively.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="map"&gt;
+ &lt;params&gt;
+ &lt;keys doc="Allowed keys"/&gt;
+ &lt;/params&gt;
+ &lt;doc&gt;
+ A map. If given, the "keys" parameter determines which keys are
+ allowed. The "keys" parameter should be a map itself, from key
+ names to a map with the attributes of the key. Attributes of a
+ key are "doc" and "type".
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<h3 id="_generic_types">Generic types</h3><div style="clear:left"></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="value"&gt;
+ &lt;doc&gt;
+ Any representable value.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="number" base="value"&gt;
+ &lt;doc&gt;
+ A number, represented as either a "int32", "uint32", "int64", "uint64", or "double".
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="integer" base="number"&gt;
+ &lt;params&gt;
+ &lt;min doc="Lower bound"/&gt;
+ &lt;max doc="Upper bound"/&gt;
+ &lt;/params&gt;
+ &lt;doc&gt;
+ A integer, represented as any of the numeric types. If the value
+ is a "double", it is rounded to an integer, but not necessarily to
+ the nearest. The "min" and "max" parameters, when given, constrain
+ the range of the integer.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="uniform-list" base="list"&gt;
+ &lt;params&gt;
+ &lt;min doc="Minimum length"/&gt;
+ &lt;max doc="Maximum length"/&gt;
+ &lt;type doc="Type of the elements"/&gt;
+ &lt;/params&gt;
+ &lt;doc&gt;
+ A list of values of the given type, with the
+ minimum and maximum length given by the "min" and "max" parameters.
+ The type of all elements is given by the "type" parameter.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="string-enum" base="string"&gt;
+ &lt;parms&gt;
+ &lt;rest doc="The possible values"&gt;
+ &lt;/parms&gt;
+ &lt;doc&gt;
+ This is the base type for enumerations of fixed strings. The
+ parameters describe the possible values. Each parameter is one
+ of the choices: the name of the parameter is the string for the choice
+ itself and the value of the parameter is a map with further
+ information of that choice, such as a "doc" entry.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="int-enum" base="int32"&gt;
+ &lt;parms&gt;
+ &lt;rest doc="The possible values"&gt;
+ &lt;/parms&gt;
+ &lt;doc&gt;
+ This is the base type for enumerations of fixed integers. The
+ parameters describe the possible values. Each parameter is one
+ of the choices: the name of the parameter is the symbolic name
+ for the choice itself and the value of the parameter is a map
+ with further information of that choice, such as a "val" entry
+ for the numerical value for that choice, and a "doc" entry.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<h3 id="_specific_types">Specific types</h3><div style="clear:left"></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="type"&gt;
+ &lt;doc&gt;
+ A type, represented as a map. The map is the one you get as the Nano-DOM
+ for the type definiton. E.g., it will have "doc" mapped to a string,
+ and "base" mapped to either a string or another map, etc.
+ &lt;/doc&gt;
+ &lt;base&gt;
+ &lt;map&gt;
+ &lt;allowed-keys&gt;
+ &lt;name/&gt;
+ &lt;parms/&gt;
+ &lt;doc/&gt;
+ &lt;base/&gt;
+ &lt;/allowed-keys&gt;
+ &lt;/map&gt;
+ &lt;/base&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="geoloc"&gt;
+ &lt;doc&gt;
+ A list of two or three doubles giving a geographical location.
+ The first number is latitude, the second longitude, both in degrees.
+ If a third number is present, it is the altitude in meters.
+ &lt;/doc&gt;
+ &lt;base&gt;
+ &lt;uniform-list min="2" max="3" type="double"/&gt;
+ &lt;/base&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="temperature"
+ base="double"
+ doc="A temperature in Kelvin."/&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="screen-edge"&gt;
+ &lt;doc&gt;
+ Indicates an edge of a rectangular screen, relative to
+ the natural orientation of the video hardware driving it.
+ It can be one of the four strings "top", "left", "right",
+ and "bottom".
+ &lt;/doc&gt;
+ &lt;base&gt;
+ &lt;string-enum&gt;
+ &lt;top/&gt; &lt;left/&gt; &lt;right/&gt; &lt;bottom/&gt;
+ &lt;/string-enum&gt;
+ &lt;/base&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="screen-edge-ints"&gt;
+ &lt;doc&gt;
+ Indicates an edge of a rectangular screen, relative to
+ the natural orientation of the video hardware driving it.
+ It can be one of the four values "top", "left", "right",
+ and "bottom", encoded as an integer.
+ &lt;/doc&gt;
+ &lt;base&gt;
+ &lt;int-enum&gt;
+ &lt;top val="0"/&gt; &lt;left val="1"/&gt; &lt;right val="2"/&gt; &lt;bottom val="3"/&gt;
+ &lt;/string-enum&gt;
+ &lt;/base&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="energy" base="double"&gt;
+ &lt;doc&gt;
+ An amount of energy, in Joule.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="power" base="double"&gt;
+ &lt;doc&gt;
+ A power, in Watt.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="time" base="int64"&gt;
+ &lt;doc&gt;
+ A point in time, represented as the number of nano-seconds since
+ 00:00 January 1, 1970, UTC.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="duration" base="uint64"&gt;
+ &lt;doc&gt;
+ A time duration, in nano-seconds.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>&lt;type name="percentage" base="int32"&gt;
+ &lt;doc&gt;
+ A percentage.
+ &lt;/doc&gt;
+&lt;/type&gt;</tt></pre>
+</div></div>
+</div>
+<h2 id="_intentional_types_and_static_languages">Intentional types and static languages</h2>
+<div class="sectionbody">
+<div class="para"><p>The normal use of intentional types is as follows: while programming
+in some language, you read some API documentation and find out that
+some argument to a function is of type "geoloc"; you then go to the
+documentation of "geoloc" and read how a "geoloc" works in your
+language.</p></div>
+<div class="para"><p>For C++ with QVariants, say, a geoloc could simply remain a list of
+two or three doubles, or it could be a QVariant::RectF with the height
+being abused as the altitude, a new QMetaType could be invented, or a
+completely new class could be defined that can be converted to and
+from a QVariant (together with an appropriate QMetaType). In any
+case, there will be a QVariant involved in there somewhere.</p></div>
+<div class="para"><p>In other words, we need C++ language bindings for the intentional
+types. These language bindings are maintained together with the
+intentional types.</p></div>
+<div class="para"><p>At the language boundaries, such as when marshalling and unmarshalling
+values for a D-Bus message, a geoloc value needs to be converted to
+and from a list of doubles. This conversion code is also maintained
+together with the language bindings. In any case, the types are well
+enough documented that the necessary code can be written manually if
+needed.</p></div>
+<h3 id="_c_with_gvariant">C with GVariant</h3><div style="clear:left"></div>
+<div class="ilist"><ul>
+<li>
+<p>
+geoloc
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>typedef struct {
+ double latitude;
+ double longitude;
+ double altitude; // NaN if unknown.
+} DGeoLoc;</tt></pre>
+</div></div>
+</li>
+</ul></div>
+<div class="para"><p>Rest is done with inheritance:</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
+duration
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>typedef int64_t DDuration;</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+screen-edge
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>typedef char *DScreenEdge;</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+screen-edge-ints
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>typedef int DScreenEdgeInts;
+#define D_SCREEN_EDGE_TOP 0
+#define D_SCREEN_EDGE_LEFT 1
+#define D_SCREEN_EDGE_RIGHT 2
+#define D_SCREEN_EDGE_BOTTOM 3</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+percentage
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>typedef int DPercentage;</tt></pre>
+</div></div>
+</li>
+<li>
+<p>
+type
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>typedef GVariant DGType;</tt></pre>
+</div></div>
+</li>
+</ul></div>
+<div class="para"><p>These definitions are in libdesktoptypes, built from the desktop-types
+source package, which includes everything else as well, such as this
+document, bindings for C++ with QVariant, etc.</p></div>
+<div class="para"><p>There is also g_variant_from_geoloc, etc.</p></div>
+<div class="para"><p>Then, libcontextprovider has context_provider_set_geoloc,
+context_provider_set_duration, etc, probably as macros using
+g_variant_from_geoloc. Maybe we can have support for doing this
+automatically.</p></div>
+<h3 id="_c_with_qvariant">C++ with QVariant</h3><div style="clear:left"></div>
+<div class="para"><p>Types should be compatible with C and have the same names.</p></div>
+<div class="ilist"><ul>
+<li>
+<p>
+geoloc
+</p>
+<div class="literalblock">
+<div class="content">
+<pre><tt>struct DGeoLoc {
+ double latitude;
+ double longitude;
+ double altitude; // NaN if unknown.</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt>DGeoLoc();
+DGeoLoc(double, double);
+DGeoLoc(double, double, double);</tt></pre>
+</div></div>
+<div class="literalblock">
+<div class="content">
+<pre><tt> DGeoLoc (QVariant);
+ operator QVariant ();
+};</tt></pre>
+</div></div>
+<div class="para"><p>Registered as "DGeoLoc" with QMetaType.</p></div>
+</li>
+<li>
+<p>
+rest identical with C, except "type", hmm&#8230;
+</p>
+</li>
+</ul></div>
+<div class="para"><p>This is in libdesktoptypes-qt, built from the same desktop-types as
+the C bindings.</p></div>
+</div>
+<h2 id="_run_time_introspection_for_intentional_types">Run-time introspection for intentional types</h2>
+<div class="sectionbody">
+<div class="para"><p>libdesktoptypes contains an API for reading a type definition
+repository, in /usr/share/desktop-types/. It can lookup DType values
+given a name.</p></div>
+<div class="para"><p>A DType contains name, doc, parms, and base, of course.</p></div>
+<div class="para"><p>Existing introspection APIs need to be extended to return DTypes, as
+well.</p></div>
+</div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2009-10-23 08:59:29 EEST
+</div>
+</div>
+</body>
+</html>