Mirror of the Rel4tion website/wiki source, view at <http://rel4tion.org>
Clone
HTTPS:
git clone https://vervis.peers.community/repos/yEzqv
SSH:
git clone USERNAME@vervis.peers.community:yEzqv
Branches
Tags
project.ctd
<?xml version="1.0" ?><cherrytree><node name="פרויקט יעילות אישית" prog_lang="custom-colors" readonly="False" tags="" unique_id="4"><rich_text>Welcome to the project wiki! See the </rich_text><rich_text link="node 7">Main Page</rich_text><rich_text>.</rich_text><node name="Main Page" prog_lang="custom-colors" readonly="False" tags="" unique_id="7"><rich_text>This is the main page of this wiki, in which I'l be defining and designing my Personal Productivity Project. Unfortunately, Gnote doesn't have a page hierarchy feature, or any form of tagging, so I'm creating this page as a place to start from, when trying to navigate through the growing wiki.
The most basic component of the system is the </rich_text><rich_text link="node 16">Task Data Definition Language</rich_text><rich_text>.</rich_text><node name="Task Data Definition Language" prog_lang="custom-colors" readonly="False" tags="" unique_id="16"><rich_text>Here I'm going to plan and design the definition language used for class and property definitions. These will be used for defining tasks and related objects.</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>Let's examine the </rich_text><rich_text link="node 9">Language Basics</rich_text><rich_text>.</rich_text><node name="Language Basics" prog_lang="custom-colors" readonly="False" tags="" unique_id="9"><rich_text>Basically, from a simple practical point of view, the language allows you to do 4 things:
• Define data types using extension or restriction of the primitive types
• Define relations (properties), which relate objects to other objects or to values of types
• Define classes, which are sets of objects which common characteristics (relations/properties)
• Define objects, which are instances of classes
Data types are described here: </rich_text><rich_text link="node 12">Data Types</rich_text><rich_text>.</rich_text><node name="Studying Existing Languages" prog_lang="custom-colors" readonly="False" tags="" unique_id="12"><rich_text>Before I plan further aspects of the language, I want to make a list of basic predefined data types. Let's read about XSD types on Wikipedia:
</rich_text><rich_text link="webs http://en.wikipedia.org/wiki/XML_Schema_(W3C)#Types">http://en.wikipedia.org/wiki/XML_Schema_(W3C)#Types</rich_text><rich_text>
Okay, inetersting. Let's examine a case study, </rich_text><rich_text link="node 17">XSD</rich_text><rich_text>.</rich_text><node name="Case Study: XML Schema Definition (XSD)" prog_lang="custom-colors" readonly="False" tags="" unique_id="17"><rich_text>I already read several articles and tutorials related to XSD, but I'll try to start from the beginning, assuming no previous knowledge. Maybe except for the purpose of XSD.
Let's start with a simple easy-to-read document, the XML Schema Primer. It's analyzed here: </rich_text><rich_text link="node 8">XSD Primer</rich_text><rich_text>.</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>Now let's study the tutorial at w3schools: </rich_text><rich_text link="node 11">W3Schools XSD Tutorial</rich_text><rich_text>.</rich_text><node name="XSD Primer" prog_lang="custom-colors" readonly="False" tags="" unique_id="8"><rich_text>Here I'm going to learn about XSD from the XSD Primer document, which should be easy to read and understand.</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>
First, let's examine primitive type here: </rich_text><rich_text link="node 13">XSD Primitive Types</rich_text><rich_text>.</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>Now, let's examine type definitions here: </rich_text><rich_text link="node 6">XSD Type Definitions</rich_text><rich_text>.</rich_text><node name="XSD Primitive Types" prog_lang="custom-colors" readonly="False" tags="" unique_id="13"><rich_text justification="left"></rich_text><rich_text scale="h2">Introduction</rich_text><rich_text>
The 19 primitive types are:
• anyURI
• base64Binary
• boolean
• date
• dateTime
• decimal
• double
• duration
• float
• hexBinary
• gDay
• gMonth
• gMonthDay
• gYear
• gYearMonth
• NOTATION
• QName
• string
• time
XSD allows the definition of new types from these primitive types through 3 mechanisms:
</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>• restriction (reducing the set of permitted values)
• list (allowing a sequence of values)
• union (allowing a choice of values from several types).
Twenty-five derived types are defined within the specification itself, and further derived types can be defined by users in their own schemas.
The mechanisms available for restricting data types include the ability to specify:
• minimum and maximum values
• regular expressions
• constraints on the length of strings
• constraints on the number of digits in decimal values
• XSD 1.1 again adds assertions, the ability to specify an arbitrary constraint by means of an XPath 2.0 expression.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">Example
</rich_text><rich_text>A simple example can be found on the </rich_text><rich_text link="node 15">XSD Example</rich_text><rich_text> page.</rich_text><encoded_png anchor="h2-1" char_offset="0">anchor</encoded_png><encoded_png anchor="h2-2" char_offset="964">anchor</encoded_png><node name="XSD Example" prog_lang="custom-colors" readonly="False" tags="" unique_id="15"><rich_text>Let's examine an example from the </rich_text><rich_text link="node 8">XSD Primer</rich_text><rich_text> document:
</rich_text><rich_text link="webs http://www.w3.org/TR/xmlschema-0/#PO">http://www.w3.org/TR/xmlschema-0/#PO</rich_text><rich_text>
First, here's an XML document written according to a specific schema: </rich_text><rich_text link="node 5">example.xml</rich_text><rich_text>.</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>Now, here's the schema on which this document is based: </rich_text><rich_text link="node 14">example.xsd</rich_text><rich_text>.
Let's examine specific features and interesting points.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">Top of the Document
</rich_text><rich_text>This kind of annotation (metadata) may appear at the top:
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation></rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">
Declaration of an Element with a Type
</rich_text><rich_text>Declaring an element with a given name and type is very simple:
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/></rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">
</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">Complex Type As a Sequence
</rich_text><rich_text>We just used a complex type we haven't defined yet. Now let's define this type, as a sequence of elements and also one attribute:
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
<xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
And here's another one:
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType></rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">
</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">Complex Type with Range Restriction
</rich_text><rich_text>Now we'll define a complex type which contains restricted simple types.
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType></rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">
Simple Type with Pattern Restriction</rich_text><rich_text>
Here's a simple type defined through a pattern restriction:
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType></rich_text><encoded_png anchor="h2-1" char_offset="304">anchor</encoded_png><encoded_png anchor="h2-2" char_offset="568">anchor</encoded_png><encoded_png anchor="h2-3" char_offset="783">anchor</encoded_png><encoded_png anchor="h2-4" char_offset="786">anchor</encoded_png><encoded_png anchor="h2-5" char_offset="1697">anchor</encoded_png><encoded_png anchor="h2-6" char_offset="1700">anchor</encoded_png><encoded_png anchor="h2-7" char_offset="2566">anchor</encoded_png><node name="example.xml" prog_lang="xml" readonly="False" tags="" unique_id="5"><rich_text><?xml version="1.0"?>
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
<billTo>
<comment>Hurry, my lawn is going wild</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
<item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
<item>
<items>
</purchaseOrder></rich_text></node><node name="example.xsd" prog_lang="xml" readonly="False" tags="" unique_id="14"><rich_text><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
<xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema></rich_text></node></node></node><node name="XSD Type Definitions" prog_lang="custom-colors" readonly="False" tags="" unique_id="6"><rich_text>We've seen the primitive types in action, and some ways to extends them and define new types based on them. Now let's examine the type definition techniques in more detail.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Learning From Examples</rich_text><rich_text justification="left"></rich_text><rich_text scale="h2">
</rich_text><rich_text>Let's start with a simple example and see what it means.
</rich_text><rich_text justification="left"></rich_text><rich_text>
What does this definition actually define?
• Complex type named USAddress
• The elements comprising the type
• A sequence of elements, which </rich_text><rich_text style="italic">must</rich_text><rich_text> appear in this order, and </rich_text><rich_text style="italic">all of them</rich_text><rich_text> must appear
• The attributes allowed by the type
• An optional attribute with a fixed value, i.e. it is the only value this attribute may have, so either it doesn't appear, or it appears and takes the specified fixed value</rich_text><rich_text strikethrough="true">
</rich_text><rich_text>
In the next example, we again define a type using a sequence, but make some minor new additions.
</rich_text><rich_text justification="left"></rich_text><rich_text>
What's new here?
• The attribute is still optional, but its value isn't fixed (it can have any date as a value)
• The shipTo and billTo elements have complex types, but the definition works exactly the same: the type is specified through the type attribute
• We define an element using a reference instead of using a name
What does "define by reference" mean? Let's compare these two declarations:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In the first line, we define a new element. It means we can now use comment elements. Then, in the PurchaseOrderType type, we want to have comments. We could easily use the first line, just define a new element called "comment". But instead, we can refer to en existing element. Use something we already defined, instead of declaring a new element. This example also uses minOccures, which is an </rich_text><rich_text style="italic">occurence constraint</rich_text><rich_text>. Let's talk about these constraints.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Constraints</rich_text><rich_text>
The following attributes are related to occurence constraints:
• minOccurs
• maxOccurs
• use
• default
• fixed
Rules for minOccurs and maxOccurs, which control constraints for </rich_text><rich_text weight="heavy">elements</rich_text><rich_text>:
• In the example above, the </rich_text><rich_text style="italic">comment</rich_text><rich_text> element is optional because its minOccurs is 0
• In general, an element is required to appear when the value of minOccurs is 1 or more
• maxOccurs may be a positive integer, or 0, or the term </rich_text><rich_text style="italic">unbounded</rich_text><rich_text> to indicate that there's no maximum value
• The default value for minOccurs and maxOccurs is 1
• The </rich_text><rich_text style="italic">comment</rich_text><rich_text> element in the example may thus appear once, or not appear at all
• Make sure you specify the values so that minOccurs <= maxOccurs
Rules for use, default and fixed, which control constraints for </rich_text><rich_text weight="heavy">elements </rich_text><rich_text>and</rich_text><rich_text weight="heavy"> attributes</rich_text><rich_text>:
• An attribute may appear only once, or not at all
• The </rich_text><rich_text style="italic">use</rich_text><rich_text> attribute controls whether an attribute it </rich_text><rich_text style="italic">required</rich_text><rich_text>, </rich_text><rich_text style="italic">optional</rich_text><rich_text> or </rich_text><rich_text style="italic">prohibited</rich_text><rich_text>
• The default value of </rich_text><rich_text style="italic">use</rich_text><rich_text> is </rich_text><rich_text style="italic">optional</rich_text><rich_text>
• The </rich_text><rich_text style="italic">default</rich_text><rich_text> attribute specifies a default value used when an </rich_text><rich_text style="italic">optional</rich_text><rich_text> attribute doesn't appear
• Note that using </rich_text><rich_text style="italic">default</rich_text><rich_text> with an attribute with </rich_text><rich_text style="italic">use</rich_text><rich_text> which isn't </rich_text><rich_text style="italic">optional</rich_text><rich_text>, is an error
• The </rich_text><rich_text style="italic">default</rich_text><rich_text> attribute can also be used with an element, in which case the default value is used when the element is empty
• Note that if the element doesn't appear, the default value is not used
• The </rich_text><rich_text style="italic">fixed</rich_text><rich_text> element defined a fixed value which must be used, for an element or for an attribute
• If an attribute with a fixed value appears, then it has to have the fixed value
• If it doesn't appear, the fixed value is supplied by default (as if the attribute appeared)
• Default value and fixed value </rich_text><rich_text weight="heavy">must not be provided together</rich_text><rich_text>, as they are mutually exclusive concepts
• minOccurs, maxOccues and used </rich_text><rich_text weight="heavy">may not appear in global declarations</rich_text><rich_text> of elements and attributes
A table giving some examples may be found at </rich_text><rich_text link="webs http://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints">http://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Built-In Simple Types</rich_text><rich_text>
XSD doesn't define only primitive types. It also defined some built-in simple types, which are derived from the primitive types. There's a simple table here: </rich_text><rich_text link="webs http://www.w3.org/TR/xmlschema-0/#CreatDt">http://www.w3.org/TR/xmlschema-0/#CreatDt</rich_text><rich_text>.
Later I'll explain in more detail.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Deriving New Simple Types</rich_text><rich_text>
There are several "facets" which allow restricting simple types in different ways, and through these restrictions we can define new types. Here's an example which defines an integer in a range:
</rich_text><rich_text justification="left"></rich_text><rich_text>
So, the </rich_text><rich_text style="italic">minInclusive</rich_text><rich_text> ans </rich_text><rich_text style="italic">maxExclusive</rich_text><rich_text> facets define the lower and upper bounds, and the </rich_text><rich_text style="italic">base</rich_text><rich_text> attribute defines the simple type on which the new type is based.</rich_text><encoded_png anchor="h3-1" char_offset="174">anchor</encoded_png><encoded_png anchor="h2-1" char_offset="197">anchor</encoded_png><codebox char_offset="258" frame_height="200" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><xsd:complexType name="USAddress" >
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType></codebox><codebox char_offset="770" frame_height="200" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType></codebox><codebox char_offset="1174" frame_height="50" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><xsd:element name="comment" type="xsd:string"/>
<xsd:element ref="comment" minOccurs="0"/></codebox><encoded_png anchor="h3-2" char_offset="1632">anchor</encoded_png><encoded_png anchor="h3-3" char_offset="3542">anchor</encoded_png><encoded_png anchor="h3-4" char_offset="3804">anchor</encoded_png><codebox char_offset="4027" frame_height="120" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><xsd:simpleType name="myInteger">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType></codebox></node></node><node name="W3Schools XSD Tutorial" prog_lang="custom-colors" readonly="False" tags="" unique_id="11"><rich_text></rich_text></node><node name="XSD Datatype Theory" prog_lang="custom-colors" readonly="False" tags="" unique_id="3"><rich_text>This is not exactly XSD, but a </rich_text><rich_text weight="heavy">slightly adapted</rich_text><rich_text> version for my own use.
Datatypes are computer representations of abstract concepts.
A datatype is basically a 4-tuple: T = <L, V, f, F>.
L is the Lexical Space of the datatype, which is the set of computer representations the datatype can have.
V is the Value Space of the datatype, which is the set of values the datatype may represent.
f is a function which maps elements of L to elements of V.
F is a group of facets which characterize properties of the value space.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Value Space</rich_text><rich_text>
The value space of a datatype may be defined in one of the following ways:
• Defined axiomatically from fundamental notions
• Defined as an enumeration, i.e. a list of allowed values
• Defined by restricting the value space of an already defined datatype
• Defined by combining values from value spaces of one of more existing types, using a construction method
Values spaces have certain properties. For example, they always have a cardinality. They may be partially ordered or have a total order, etc. The properties of value spaces will be defined later, as Facets.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Lexical Space</rich_text><rich_text>
This is the set of literals which form the computer representation of the value space. The string format used by the language is UTF-8, and this format allows defining text in any known language and symbol. For consistency and simple safe definitions, the identifier names may be restricted to English, but internatiolization mechanisms will allow easy translation of names and description, allowing programs to work with translated names and thus offer the user a localized workspace.
The usage of UTF-8 results in extremely easy direct interoperability with UTF-8 supporting systems. At least for now, systems which don't use UTF-8 for relevant strings, will have to adapt by converting strings to their formats. In any case, the GNU operating system and the Linux kernel, comprising together GNU/Linux, are the first priority. The Hurd kernel, although not widely used, is in high priority too. Proprietary systems, such as Windows and all other Microsoft products and platforms, have the lowest priority.
Literals used here try to be based on the ones found in existing programming languages, but giving the highest priority to open standards and organizations and non-profits which support openness, freedom, sharing and collaboration, while giving the lowest priority, and sometimes even ignoring, to patented formats and organizations and companies limiting federation and interoperability by defining their own specific rules instead of using open standars.
For example, Visual Basic and C# will have a low priority, and Windows technologies and libraries will be mostly ignored, while open tools like C, C++, Python, GNU projects, Gnome Desktop tools, etc. will have the highest priority.
An important guideline is to use textual literals, rather than binary once. Have explicit full names, rather than cryptic codes and obscure rules.
Literals don't always have a 1-1 mapping to value space: For example, 100 and 1.0e2 represent the same number, and '\n' represents a line break in text.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Facets</rich_text><rich_text>
A facet is a single aspect of a value space.
There are two types of facets. A fundamental facet is an abstract property which serves to semantically characterize the values of the value space. All other facets are constraining facets, which may be applied to a datatype to constraint its value space.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Categories</rich_text><rich_text>
</rich_text><rich_text underline="single">Atomic, List and Union</rich_text><rich_text>:
An </rich_text><rich_text weight="heavy">atomic</rich_text><rich_text> datatype is a datatype which has values which cannot be divided. For example, in the abstract manner an integer may be represented as a sequence of digits, but the language defines an integer as an atomic type and does not introduce digits as a base type, as it would over-complicate the language without any advantages.
A </rich_text><rich_text weight="heavy">list</rich_text><rich_text> datatype is a datatype whose values are finite-length sequences of values of an atomic datatype.
Here's a simple List example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Confusing example with 18 (not 3) string list items:
</rich_text><rich_text justification="left"></rich_text><rich_text>
For datatypes derived from list datatypes, the constraining facets which apply are:
• length
• maxLength
• minLength
• enumeration
• pattern
• whiteSpace (fixed to </rich_text><rich_text style="italic">collapse</rich_text><rich_text>)
Example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
A </rich_text><rich_text weight="heavy">union</rich_text><rich_text> datatype is a datatype whole value space and lexical spaces are unions of value spaces and lexical spaces of one or more other datatypes.
An example from XSD itself is the </rich_text><rich_text underline="single">maxOccurs</rich_text><rich_text> attribute, which is a union of non-negative-integer and an enumeration with a single value, the string </rich_text><rich_text style="italic">unbounded</rich_text><rich_text>. Here's some code:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Here's an example in which different union member types are actually used in defined elements:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text underline="single">Primitive and Derived</rich_text><rich_text>:
</rich_text><rich_text weight="heavy">Primitive</rich_text><rich_text> datatypes are not derived from any other types, they just already exist. For example, float.
</rich_text><rich_text weight="heavy">Derived</rich_text><rich_text> types are defined in terms of other datatypes by one of three ways:
• restriction
• list
• union
An example is </rich_text><rich_text style="italic">integer,</rich_text><rich_text> which is a restriction of </rich_text><rich_text style="italic">decimal</rich_text><rich_text>.
</rich_text><rich_text underline="single">Built-in and User-Defined</rich_text><rich_text>:
</rich_text><rich_text weight="heavy">Built-in</rich_text><rich_text> typea are the ones defined by the XSD specification, and can be primitive or derived.
</rich_text><rich_text weight="heavy">User-defined</rich_text><rich_text> oe </rich_text><rich_text weight="heavy">user-derived</rich_text><rich_text> types are the ones defined by the user, a schema designer.
</rich_text><rich_text scale="h3">Built-In Types</rich_text><rich_text>
Here is the type hierarchy of XSD built-in types:
</rich_text><rich_text justification="left"></rich_text><encoded_png anchor="h3-1" char_offset="521">anchor</encoded_png><encoded_png anchor="h3-2" char_offset="1107">anchor</encoded_png><encoded_png anchor="h3-3" char_offset="3127">anchor</encoded_png><encoded_png anchor="h3-4" char_offset="3439">anchor</encoded_png><codebox char_offset="3945" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><simpleType name='sizes'>
<list itemType='decimal'/>
</simpleType>
<cerealSizes xsi:type='sizes'> 8 10.5 12 </cerealSizes></codebox><codebox char_offset="4002" frame_height="160" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><simpleType name='listOfString'>
<list itemType='string'/>
</simpleType>
<someElement xsi:type='listOfString'>
this is not list item 1
this is not list item 2
this is not list item 3
</someElement></codebox><codebox char_offset="4191" frame_height="210" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><xs:simpleType name='myList'>
<xs:list itemType='xs:integer'/>
</xs:simpleType>
<xs:simpleType name='myRestrictedList'>
<xs:restriction base='myList'>
<xs:pattern value='123 (\d+\s)*456'/>
</xs:restriction>
</xs:simpleType>
<someElement xsi:type='myRestrictedList'>123 456</someElement>
<someElement xsi:type='myRestrictedList'>123 987 456</someElement>
<someElement xsi:type='myRestrictedList'>123 987 567 456</someElement></codebox><codebox char_offset="4518" frame_height="330" frame_width="820" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><attributeGroup name="occurs">
<attribute name="minOccurs" type="nonNegativeInteger" use="optional" default="1"/>
<attribute name="maxOccurs" use="optional" default="1">
<simpleType>
<union>
<simpleType>
<restriction base='nonNegativeInteger'/>
</simpleType>
<simpleType>
<restriction base='string'>
<enumeration value='unbounded'/>
</restriction>
</simpleType>
</union>
</simpleType>
</attribute>
</attributeGroup></codebox><codebox char_offset="4618" frame_height="294" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="xml" width_in_pixels="True"><xsd:element name='size'>
<xsd:simpleType>
<xsd:union>
<xsd:simpleType>
<xsd:restriction base='integer'/>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base='string'/>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:element>
<size>1</size>
<size>large</size>
<size xsi:type='xsd:string'>1</size></codebox><encoded_png char_offset="5193">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</encoded_png></node><node name="Datatype Components" prog_lang="custom-colors" readonly="False" tags="" unique_id="57"><rich_text>
</rich_text><rich_text scale="h2">4 Datatype components</rich_text><rich_text>
The following sections provide full details on the properties and significance of each kind of schema component involved in datatype definitions. For each property, the kinds of values it is allowed to have is specified. Any property not identified as optional is required to be present; optional properties which are not present have </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#key-null">absent</rich_text><rich_text> as their value. Any property identified as a having a set, subset or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> value may have an empty value unless this is explicitly ruled out: this is not the same as </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#key-null">absent</rich_text><rich_text>. Any property value identified as a superset or a subset of some set may be equal to that set, unless a proper superset or subset is explicitly called for.
For more information on the notion of datatype (schema) components, see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#components">Schema Component Details</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#structural-schemas">[XML Schema Part 1: Structures]</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">4.1 Simple Type Definition</rich_text><rich_text>
4.1.1 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dc-defn">The Simple Type Definition Schema Component</rich_text><rich_text>
4.1.2 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#xr-defn">XML Representation of Simple Type Definition Schema Components</rich_text><rich_text>
4.1.3 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-rep-constr">Constraints on XML Representation of Simple Type Definition</rich_text><rich_text>
4.1.4 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-validation-rules">Simple Type Definition Validation Rules</rich_text><rich_text>
4.1.5 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-coss">Constraints on Simple Type Definition Schema Components</rich_text><rich_text>
4.1.6 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#anySimpleType-component">Simple Type Definition for anySimpleType</rich_text><rich_text>
Simple Type definitions provide for:
• Establishing the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of a datatype, through the combined set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text>s specified in the definition;
• Attaching a unique name (actually a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text>) to the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text>.
4.1.1 The Simple Type Definition Schema ComponentThe Simple Type Definition schema component has the following properties:
</rich_text><rich_text foreground="#a52a2a">Schema Component</rich_text><rich_text>: </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#datatype">Simple Type Definition</rich_text><rich_text>{name}Optional. An NCName as defined by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>.{target namespace}Either </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#key-null">absent</rich_text><rich_text> or a namespace name, as defined in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>.{variety}One of {</rich_text><rich_text style="italic">atomic</rich_text><rich_text>, </rich_text><rich_text style="italic">list</rich_text><rich_text>, </rich_text><rich_text style="italic">union</rich_text><rich_text>}. Depending on the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text>, further properties are defined as follows:atomic{primitive type definition}A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-primitive">·primitive·</rich_text><rich_text> datatype definition).list{item type definition}An </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> simple type definition.union{member type definitions}A non-empty sequence of simple type definitions.{facets}A possibly empty set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#facets">Facets (§2.4)</rich_text><rich_text>.{fundamental facets}A set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#fundamental-facets">Fundamental facets (§2.4.1)</rich_text><rich_text>{base type definition}If the datatype has been </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-restriction">·restriction·</rich_text><rich_text> then the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dc-defn">Simple Type Definition</rich_text><rich_text> component from which it is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text>, otherwise the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#anySimpleType-component">Simple Type Definition for anySimpleType (§4.1.6)</rich_text><rich_text>.{final}A subset of {restriction, list, union}.{annotation}Optional. An </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#Annotation">annotation</rich_text><rich_text>.Datatypes are identified by their </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-name">{name}</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-target-namespace">{target namespace}</rich_text><rich_text>. Except for anonymous datatypes (those with no </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-name">{name}</rich_text><rich_text>), datatype definitions </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">·must·</rich_text><rich_text> be uniquely identified within a schema.
If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> then the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of the datatype defined will be a subset of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-basetype">{base type definition}</rich_text><rich_text> (which is a subset of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-primitive">{primitive type definition}</rich_text><rich_text>). If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> then the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of the datatype defined will be the set of finite-length sequence of values from the</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-itemType">{item type definition}</rich_text><rich_text>. If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> then the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of the datatype defined will be the union of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>s of each datatype in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-memberTypes">{member type definitions}</rich_text><rich_text>.
If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> then the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-basetype">{base type definition}</rich_text><rich_text> must be </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text>. If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> then the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-itemType">{item type definition}</rich_text><rich_text> must be either</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text>. If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> then </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-memberTypes">{member type definitions}</rich_text><rich_text> must be a list of datatype definitions.
The value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-facets">{facets}</rich_text><rich_text> consists of the set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-facet">·facet·</rich_text><rich_text>s specified directly in the datatype definition unioned with the possibly empty set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-facets">{facets}</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-basetype">{base type definition}</rich_text><rich_text>.
The value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-fund-facets">{fundamental facets}</rich_text><rich_text> consists of the set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-fundamental-facet">·fundamental facet·</rich_text><rich_text>s and their values.
If </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-final">{final}</rich_text><rich_text> is the empty set then the type can be used in deriving other types; the explicit values restriction, list and union prevent further derivations by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-restriction">·restriction·</rich_text><rich_text>,</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> respectively.
4.1.2 XML Representation of Simple Type Definition Schema ComponentsThe XML representation for a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dc-defn">Simple Type Definition</rich_text><rich_text> schema component is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-simpleType"><simpleType></rich_text><rich_text> element information item. The correspondences between the properties of the information item and properties of the component are as follows:
</rich_text><rich_text foreground="#a52a2a">XML Representation Summary</rich_text><rich_text>: simpleType Element Information Item<simpleType
final = (#all | List of (list | union | restriction))
id = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID">ID</rich_text><rich_text>
</rich_text><rich_text weight="heavy">name</rich_text><rich_text> = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>
{any attributes with non-schema namespace . . .}>
Content: (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-annotation">annotation</rich_text><rich_text>?, (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-restriction">restriction</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-list">list</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-union">union</rich_text><rich_text>))
</simpleType>
</rich_text><rich_text justification="left"></rich_text><rich_text>
A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> datatype can be </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-primitive">·primitive·</rich_text><rich_text> datatype or another </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> datatype by one of three means: by restriction, by list or by union.
4.1.2.1 Derivation by restriction</rich_text><rich_text foreground="#a52a2a">XML Representation Summary</rich_text><rich_text>: restriction Element Information Item<restriction
base = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text>
id = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID">ID</rich_text><rich_text>
{any attributes with non-schema namespace . . .}>
Content: (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-annotation">annotation</rich_text><rich_text>?, (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-simpleType">simpleType</rich_text><rich_text>?, (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-minExclusive">minExclusive</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-minInclusive">minInclusive</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-maxExclusive">maxExclusive</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-maxInclusive">maxInclusive</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-totalDigits">totalDigits</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-fractionDigits">fractionDigits</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-length">length</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-minLength">minLength</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-maxLength">maxLength</rich_text><rich_text> |</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-enumeration">enumeration</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-whiteSpace">whiteSpace</rich_text><rich_text> | </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-pattern">pattern</rich_text><rich_text>)*))
</restriction>
</rich_text><rich_text justification="left"></rich_text><rich_text>
ExampleAn electronic commerce schema might define a datatype called Sku (the barcode number that appears on products) from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatype </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string">string</rich_text><rich_text> by supplying a value for the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text> facet.<simpleType name='Sku'>
<restriction base='string'>
<pattern value='\d{3}-[A-Z]{2}'/>
</restriction>
</simpleType>In this case, Sku is the name of the new </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-user-derived">·user-derived·</rich_text><rich_text> datatype, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string">string</rich_text><rich_text> is its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text> is the facet.4.1.2.2 Derivation by list</rich_text><rich_text foreground="#a52a2a">XML Representation Summary</rich_text><rich_text>: list Element Information Item<list
id = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID">ID</rich_text><rich_text>
itemType = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text>
{any attributes with non-schema namespace . . .}>
Content: (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-annotation">annotation</rich_text><rich_text>?, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-simpleType">simpleType</rich_text><rich_text>?)
</list>
</rich_text><rich_text justification="left"></rich_text><rich_text>
A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> datatype must be </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> or a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype, known as the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> datatype. This yields a datatype whose </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> is composed of finite-length sequences of values from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> and whose </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> is composed of space-separated lists of literals of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text>.
ExampleA system might want to store lists of floating point values.<simpleType name='listOfFloat'>
<list itemType='float'/>
</simpleType>
In this case, listOfFloat is the name of the new </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-user-derived">·user-derived·</rich_text><rich_text> datatype, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#float">float</rich_text><rich_text> is its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> is the derivation method.As mentioned in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#list-datatypes">List datatypes (§2.5.1.2)</rich_text><rich_text>, when a datatype is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> datatype, the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text>s can be used:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-length">·length·</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxLength">·maxLength·</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minLength">·minLength·</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-enumeration">·enumeration·</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-whiteSpace">·whiteSpace·</rich_text><rich_text>
regardless of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text>s that are applicable to the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> datatype that serves as the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text>.
For each of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-length">·length·</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxLength">·maxLength·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minLength">·minLength·</rich_text><rich_text>, the unit of length is measured in number of list items. The value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-whiteSpace">·whiteSpace·</rich_text><rich_text> is fixed to the value collapse.
4.1.2.3 Derivation by union</rich_text><rich_text foreground="#a52a2a">XML Representation Summary</rich_text><rich_text>: union Element Information Item<union
id = </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID">ID</rich_text><rich_text>
memberTypes = List of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text>
{any attributes with non-schema namespace . . .}>
Content: (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-annotation">annotation</rich_text><rich_text>?, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-simpleType">simpleType</rich_text><rich_text>*)
</union>
</rich_text><rich_text justification="left"></rich_text><rich_text>
A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype can be </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from one or more </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> or other </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatypes, known as the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-memberTypes">·memberTypes·</rich_text><rich_text> of that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype.
ExampleAs an example, taken from a typical display oriented text markup language, one might want to express font sizes as an integer between 8 and 72, or with one of the tokens "small", "medium" or "large". The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> type definition below would accomplish that.<xsd:attribute name="size">
<xsd:simpleType>
<xsd:union>
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:minInclusive value="8"/>
<xsd:maxInclusive value="72"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="small"/>
<xsd:enumeration value="medium"/>
<xsd:enumeration value="large"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:attribute>
<p>
<font size='large'>A header</font>
</p>
<p>
<font size='12'>this is a test</font>
</p>
As mentioned in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#union-datatypes">Union datatypes (§2.5.1.3)</rich_text><rich_text>, when a datatype is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype, the only following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text>s can be used:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-enumeration">·enumeration·</rich_text><rich_text>
regardless of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text>s that are applicable to the datatypes that participate in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text>
4.1.3 Constraints on XML Representation of Simple Type Definition</rich_text><rich_text weight="heavy">Schema Representation Constraint: Single Facet Value</rich_text><rich_text>
Unless otherwise specifically allowed by this specification (</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#src-multiple-patterns">Multiple patterns (§4.3.4.3)</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#src-multiple-enumerations">Multiple enumerations (§4.3.5.3)</rich_text><rich_text>) any given </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text> can only be specifed once within a single derivation step.</rich_text><rich_text weight="heavy">Schema Representation Constraint: itemType attribute or simpleType child</rich_text><rich_text>
Either the itemType </rich_text><rich_text link="webs http://www.w3.org/TR/xml-infoset/#infoitem.attribute">[attribute]</rich_text><rich_text> or the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-simpleType"><simpleType></rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/xml-infoset/#infoitem.element">[child]</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-list"><list></rich_text><rich_text> element must be present, but not both.</rich_text><rich_text weight="heavy">Schema Representation Constraint: base attribute or simpleType child</rich_text><rich_text>
Either the base </rich_text><rich_text link="webs http://www.w3.org/TR/xml-infoset/#infoitem.attribute">[attribute]</rich_text><rich_text> or the simpleType </rich_text><rich_text link="webs http://www.w3.org/TR/xml-infoset/#infoitem.element">[child]</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-restriction"><restriction></rich_text><rich_text> element must be present, but not both.</rich_text><rich_text weight="heavy">Schema Representation Constraint: memberTypes attribute or simpleType children</rich_text><rich_text>
Either the memberTypes </rich_text><rich_text link="webs http://www.w3.org/TR/xml-infoset/#infoitem.attribute">[attribute]</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#element-union"><union></rich_text><rich_text> element must be non-empty or there must be at least one simpleType </rich_text><rich_text link="webs http://www.w3.org/TR/xml-infoset/#infoitem.element">[child]</rich_text><rich_text>.4.1.4 Simple Type Definition Validation Rules</rich_text><rich_text weight="heavy">Validation Rule: Facet Valid</rich_text><rich_text>
A value in a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> is facet-valid with respect to a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text> component if:1 the value is facet-valid with respect to the particular </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text> as specified below.</rich_text><rich_text weight="heavy">Validation Rule: Datatype Valid</rich_text><rich_text>
A string is datatype-valid with respect to a datatype definition if:1 it </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text>es a literal in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of the datatype, determined as follows:1.1 if </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text> is a member of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-facets">{facets}</rich_text><rich_text>, then the string must be </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#cvc-pattern-valid">pattern valid (§4.3.4.4)</rich_text><rich_text>;1.2 if </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text> is not a member of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-facets">{facets}</rich_text><rich_text>, then1.2.1 if </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> then the string must </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> a literal in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-basetype">{base type definition}</rich_text><rich_text>1.2.2 if </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> then the string must be a sequence of space-separated tokens, each of which </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text>es a literal in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-itemType">{item type definition}</rich_text><rich_text>1.2.3 if </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-variety">{variety}</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> then the string must </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> a literal in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of at least one member of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-memberTypes">{member type definitions}</rich_text><rich_text>2 the value denoted by the literal </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text>ed in the previous step is a member of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of the datatype, as determined by it being </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#cvc-facet-valid">Facet Valid (§4.1.4)</rich_text><rich_text>with respect to each member of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#defn-facets">{facets}</rich_text><rich_text> (except for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text>).4.1.5 Constraints on Simple Type Definition Schema Components</rich_text><rich_text weight="heavy">Schema Component Constraint: applicable facets</rich_text><encoded_png char_offset="829">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACqElEQVQokSXSz28UZRwH4M+8885sp+1Su21TSgOiXEwgafSEQknwQDTRhGj0auJV/ReMF88e/BUh0YsHDhqVgwoBQqJiTKxGtNRQocF0pbTd7c7szrwz74/vxwPP3/DA1cOmLMQHCovcCGmFTfCeNjc7wkpYFcV28DWF+e4ApN3rb1PY2y1EuHl/0M9rT/aKvqd1Ug6rHmnJYMqKgZGzVQi8cWNl/Z97++cXn3/hdAjQKaxjmkQRRAEAvAt11WTZhKpr2xobf/qZZahkde3u6uoDpVAZaBXluXdBCdTIWJ0k7X2TPoSI5G4vH8+mWmM4f/670lgRzMx1Xn1lOW0BEbxFrJBqPKQGRT49M1XVzgf89POvp06d6XQOXL/2y/p6vbHhnYVOEWuUBrVhUyPypDE+a2kSH350+ciRYwcPHlAxbv55a2e3u7jYOXHiqbmZqNc3ztbtdlsVw1GWaRewV2CwN5qdnd8b2G63OHTosfn5hatXr3/x5Vfeo9v97/KlK865yJHDomm3W0J8/MG1k8vPmlqmp9WoDGNZZG1xa21l897dRw8vPLm0NPVIO3JkBEBQVfjhx43BoDl69In7W/3Zuakg5sKFzyYm1Dtvv+E8flv54/jxJbjgyzrkQ7rA115/d+02N/7l7zfDe+9//8mnVzYfsCG3+83WzkiE1lIziLe+PZnlBZ47c9o5c/Hipb9vr7380osnl49l4zCldKZThdRaeu91ksRN0wBo78OdO3/lxc5bb551craVINbwAVoLoKz1EdVElmhAEq1sE77+5tvHDy/M7V9IUyhBHKM0RkVhcmwckFaqvQ3eEb4ZeWce5jt37nNPljWbQEvXiBHWwrrX3zLViEIGRpQGjLyHThISxcjoVpIkUaxEYCGilIqhgRjUIP4HTSzK2TM8HfoAAAAASUVORK5CYII=</encoded_png><table char_offset="4628" col_max="500" col_min="40"><row><cell>{name}</cell><cell>The actual value of the name [attribute], if present, otherwise null</cell></row><row><cell>{final}</cell><cell>A set corresponding to the actual value of the final [attribute], if present, otherwise the actual value of the finalDefault [attribute] of the ancestor schema element information item, if present, otherwise the empty string, as follows:the empty stringthe empty set;#all{restriction, list, union};otherwisea set with members drawn from the set above, each being present or absent depending on whether the string contains an equivalently named space-delimited substring.Note: Although the finalDefault [attribute] of schema may include values other than restriction, list or union, those values are ignored in the determination of {final}</cell></row><row><cell>{target namespace}</cell><cell>The actual value of the targetNamespace [attribute] of the parent schema element information item.</cell></row><row><cell>{annotation}</cell><cell>The annotation corresponding to the <annotation> element information item in the [children], if present, otherwise null</cell></row><row><cell>Property</cell><cell>Representation</cell></row></table><table char_offset="5190" col_max="1000" col_min="40"><row><cell>{variety}</cell><cell>The actual value of {variety} of {base type definition}</cell></row><row><cell>{facets}</cell><cell>The union of the set of Facets (§2.4) components resolved to by the facet [children] merged with {facets} from {base type definition}, subject to the Facet Restriction Valid constraints specified in Facets (§2.4).</cell></row><row><cell>{base type definition}</cell><cell>The Simple Type Definition component resolved to by the actual value of the base [attribute] or the <simpleType> [children], whichever is present.</cell></row><row><cell>Property</cell><cell>Representation</cell></row></table><table char_offset="5854" col_max="1000" col_min="40"><row><cell>{variety}</cell><cell>list</cell></row><row><cell>{item type definition}</cell><cell>The Simple Type Definition component resolved to by the actual value of the itemType [attribute] or the <simpleType> [children], whichever is present.</cell></row><row><cell>Property</cell><cell>Representation</cell></row></table><table char_offset="7234" col_max="1000" col_min="40"><row><cell>{variety}</cell><cell>union</cell></row><row><cell>{member type definitions}</cell><cell>The sequence of Simple Type Definition components resolved to by the items in the actual value of the memberTypes [attribute], if any, in order, followed by the Simple Type Definition components resolved to by the <simpleType> [children], if any, in order. If {variety} is unionfor any Simple Type Definition components resolved to above, then the Simple Type Definition is replaced by its {member type definitions}.</cell></row><row><cell>Property</cell><cell>Representation</cell></row></table></node><node name="Facets" prog_lang="custom-colors" readonly="False" tags="" unique_id="58"><rich_text>
</rich_text><rich_text scale="h2">C Datatypes and Facets</rich_text><rich_text>
</rich_text><rich_text scale="h3">C.1 Fundamental Facets</rich_text><rich_text>
The following table shows the values of the fundamental facets for each </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatype.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h2">D ISO 8601 Date and Time Formats</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">D.1 ISO 8601 Conventions</rich_text><rich_text>
The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-primitive">·primitive·</rich_text><rich_text> datatypes </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#duration">duration</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#time">time</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonthDay">gMonthDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gDay">gDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text> use lexical formats inspired by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Following</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>, the lexical forms of these datatypes can include only the characters #20 through #7F. This appendix provides more detail on the ISO formats and discusses some deviations from them for the datatypes defined in this specification.
</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text> "specifies the representation of dates in the proleptic Gregorian calendar and times and representations of periods of time". The proleptic Gregorian calendar includes dates prior to 1582 (the year it came into use as an ecclesiastical calendar). It should be pointed out that the datatypes described in this specification do not cover all the types of data covered by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>, nor do they support all the lexical representations for those types of data.
</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text> lexical formats are described using "pictures" in which characters are used in place of decimal digits. The allowed decimal digits are (#x30-#x39). For the primitive datatypes </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#time">time</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonthDay">gMonthDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gDay">gDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text>. these characters have the following meanings:
• C -- represents a digit used in the thousands and hundreds components, the "century" component, of the time element "year". Legal values are from 0 to 9.
• Y -- represents a digit used in the tens and units components of the time element "year". Legal values are from 0 to 9.
• M -- represents a digit used in the time element "month". The two digits in a MM format can have values from 1 to 12.
• D -- represents a digit used in the time element "day". The two digits in a DD format can have values from 1 to 28 if the month value equals 2, 1 to 29 if the month value equals 2 and the year is a leap year, 1 to 30 if the month value equals 4, 6, 9 or 11, and 1 to 31 if the month value equals 1, 3, 5, 7, 8, 10 or 12.
• h -- represents a digit used in the time element "hour". The two digits in a hh format can have values from 0 to 24. If the value of the hour element is 24 then the values of the minutes element and the seconds element must be 00 and 00.
• m -- represents a digit used in the time element "minute". The two digits in a mm format can have values from 0 to 59.
• s -- represents a digit used in the time element "second". The two digits in a ss format can have values from 0 to 60. In the formats described in this specification the whole number of seconds </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-may">·may·</rich_text><rich_text> be followed by decimal seconds to an arbitrary level of precision. This is represented in the picture by "ss.sss". A value of 60 or more is allowed only in the case of leap seconds.Strictly speaking, a value of 60 or more is not sensible unless the month and day could represent March 31, June 30, September 30, or December 31 in UTC. Because the leap second is added or subtracted as the last second of the day in UTC time, the long (or short) minute could occur at other times in local time. In cases where the leap second is used with an inappropriate month and day it, and any fractional seconds, should considered as added or subtracted from the following minute.
For all the information items indicated by the above characters, leading zeros are required where indicated.
In addition to the above, certain characters are used as designators and appear as themselves in lexical formats.
• T -- is used as time designator to indicate the start of the representation of the time of day in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>.
• Z -- is used as time-zone designator, immediately (without a space) following a data element expressing the time of day in Coordinated Universal Time (UTC) in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#time">time</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonthDay">gMonthDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gDay">gDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text>, and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text>.
In the lexical format for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#duration">duration</rich_text><rich_text> the following characters are also used as designators and appear as themselves in lexical formats:
• P -- is used as the time duration designator, preceding a data element representing a given duration of time.
• Y -- follows the number of years in a time duration.
• M -- follows the number of months or minutes in a time duration.
• D -- follows the number of days in a time duration.
• H -- follows the number of hours in a time duration.
• S -- follows the number of seconds in a time duration.
The values of the Year, Month, Day, Hour and Minutes components are not restricted but allow an arbitrary integer. Similarly, the value of the Seconds component allows an arbitrary decimal. Thus, the lexical format for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#duration">duration</rich_text><rich_text> and datatypes derived from it does not follow the alternative format of § 5.5.3.2.1 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3"> </rich_text><rich_text justification="left" scale="h3"></rich_text><rich_text scale="h3">D.2 Truncated and Reduced Formats</rich_text><rich_text>
</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text> supports a variety of "truncated" formats in which some of the characters on the left of specific formats, for example, the century, can be omitted. Truncated formats are, in general, not permitted for the datatypes defined in this specification with three exceptions. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#time">time</rich_text><rich_text> datatype uses a truncated format for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> which represents an instant of time that recurs every day. Similarly, the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonthDay">gMonthDay</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gDay">gDay</rich_text><rich_text> datatypes use left-truncated formats for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>. The datatype </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text> uses a right and left truncated format for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>.
</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text> also supports a variety of "reduced" or right-truncated formats in which some of the characters to the right of specific formats, such as the time specification, can be omitted. Right truncated formats are also, in general, not permitted for the datatypes defined in this specification with the following exceptions: right-truncated representations of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> are used as lexical representations for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">D.3 Deviations from ISO 8601 Formats</rich_text><rich_text>
D.3.1 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#signallowed">Sign Allowed</rich_text><rich_text>
D.3.2 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#noYearZero">No Year Zero</rich_text><rich_text>
D.3.3 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#morethan9999years">More Than 9999 Years</rich_text><rich_text>
D.3.4 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#timeZonePermited">Time zone permitted</rich_text><rich_text>
D.3.1 Sign AllowedAn optional minus sign is allowed immediately preceding, without a space, the lexical representations for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#duration">duration</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text>.
D.3.2 No Year ZeroThe year "0000" is an illegal year value.
D.3.3 More Than 9999 YearsTo accommodate year values greater than 9999, more than four digits are allowed in the year representations of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text>. This follows </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601-2000">[ISO 8601:2000 Second Edition]</rich_text><rich_text>.
D.3.4 Time zone permittedThe lexical representations for the datatypes </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonthDay">gMonthDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gDay">gDay</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text> permit an optional trailing time zone specificiation.
</rich_text><rich_text scale="h2">E Adding durations to dateTimes</rich_text><rich_text>
Given a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> S and a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#duration">duration</rich_text><rich_text> D, this appendix specifies how to compute a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> E where E is the end of the time period with start S and duration D i.e. E = S + D. Such computations are used, for example, to determine whether a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> is within a specific time period. This appendix also addresses the addition of</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#duration">duration</rich_text><rich_text>s to the datatypes </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYearMonth">gYearMonth</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gYear">gYear</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gDay">gDay</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#gMonth">gMonth</rich_text><rich_text>, which can be viewed as a set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>s. In such cases, the addition is made to the first or starting </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> in the set.
This is a logical explanation of the process. Actual implementations are free to optimize as long as they produce the same results. The calculation uses the notation S[year] to represent the year field of S, S[month] to represent the month field, and so on. It also depends on the following functions:
• fQuotient(a, b) = the greatest integer less than or equal to a/b• fQuotient(-1,3) = -1
• fQuotient(0,3)...fQuotient(2,3) = 0
• fQuotient(3,3) = 1
• fQuotient(3.123,3) = 1
• modulo(a, b) = a - fQuotient(a,b)*b• modulo(-1,3) = 2
• modulo(0,3)...modulo(2,3) = 0...2
• modulo(3,3) = 0
• modulo(3.123,3) = 0.123
• fQuotient(a, low, high) = fQuotient(a - low, high - low)• fQuotient(0, 1, 13) = -1
• fQuotient(1, 1, 13) ... fQuotient(12, 1, 13) = 0
• fQuotient(13, 1, 13) = 1
• fQuotient(13.123, 1, 13) = 1
• modulo(a, low, high) = modulo(a - low, high - low) + low• modulo(0, 1, 13) = 12
• modulo(1, 1, 13) ... modulo(12, 1, 13) = 1...12
• modulo(13, 1, 13) = 1
• modulo(13.123, 1, 13) = 1.123
• maximumDayInMonthFor(yearValue, monthValue) =• M := modulo(monthValue, 1, 13)
• Y := yearValue + fQuotient(monthValue, 1, 13)
• Return a value based on M and Y:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">E.1 Algorithm</rich_text><rich_text>
Essentially, this calculation is equivalent to separating D into <year,month> and <day,hour,minute,second> fields. The <year,month> is added to S. If the day is out of range, it is pinned to be within range. Thus April 31 turns into April 30. Then the <day,hour,minute,second> is added. This latter addition can cause the year and month to change.
Leap seconds are handled by the computation by treating them as overflows. Essentially, a value of 60 seconds in S is treated as if it were a duration of 60 seconds added to S (with a zero seconds field). All calculations thereafter use 60 seconds per minute.
Thus the addition of either PT1M or PT60S to any dateTime will always produce the same result. This is a special definition of addition which is designed to match common practice, and -- most importantly -- be stable over time.
A definition that attempted to take leap-seconds into account would need to be constantly updated, and could not predict the results of future implementation's additions. The decision to introduce a leap second in UTC is the responsibility of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IERS">[International Earth Rotation Service (IERS)]</rich_text><rich_text>. They make periodic announcements as to when leap seconds are to be added, but this is not known more than a year in advance. For more information on leap seconds, see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#USNavy">[U.S. Naval Observatory Time Service Department]</rich_text><rich_text>.
The following is the precise specification. These steps must be followed in the same order. If a field in D is not specified, it is treated as if it were zero. If a field in S is not specified, it is treated in the calculation as if it were the minimum allowed value in that field, however, after the calculation is concluded, the corresponding field in E is removed (set to unspecified).
• Months (may be modified additionally below)• temp := S[month] + D[month]
• E[month] := modulo(temp, 1, 13)
• carry := fQuotient(temp, 1, 13)
• Years (may be modified additionally below)• E[year] := S[year] + D[year] + carry
• Zone• E[zone] := S[zone]
• Seconds• temp := S[second] + D[second]
• E[second] := modulo(temp, 60)
• carry := fQuotient(temp, 60)
• Minutes• temp := S[minute] + D[minute] + carry
• E[minute] := modulo(temp, 60)
• carry := fQuotient(temp, 60)
• Hours• temp := S[hour] + D[hour] + carry
• E[hour] := modulo(temp, 24)
• carry := fQuotient(temp, 24)
• Days• if S[day] > maximumDayInMonthFor(E[year], E[month])• tempDays := maximumDayInMonthFor(E[year], E[month])
• else if S[day] < 1• tempDays := 1
• else• tempDays := S[day]
• E[day] := tempDays + D[day] + carry
• </rich_text><rich_text weight="heavy">START LOOP</rich_text><rich_text>• </rich_text><rich_text weight="heavy">IF </rich_text><rich_text>E[day] < 1• E[day] := E[day] + maximumDayInMonthFor(E[year], E[month] - 1)
• carry := -1
• </rich_text><rich_text weight="heavy">ELSE IF </rich_text><rich_text>E[day] > maximumDayInMonthFor(E[year], E[month])• E[day] := E[day] - maximumDayInMonthFor(E[year], E[month])
• carry := 1
• </rich_text><rich_text weight="heavy">ELSE EXIT LOOP</rich_text><rich_text>
• temp := E[month] + carry
• E[month] := modulo(temp, 1, 13)
• E[year] := E[year] + fQuotient(temp, 1, 13)
• </rich_text><rich_text weight="heavy">GOTO START LOOP</rich_text><rich_text>
Examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">E.2 Commutativity and Associativity</rich_text><rich_text>
Time durations are added by simply adding each of their fields, respectively, without overflow.
The order of addition of durations to instants is significant. For example, there are cases where:
((dateTime + duration1) + duration2) != ((dateTime + duration2) + duration1)
Example:
(2000-03-30 + P1D) + P1M = 2000-03-31 + P1M = 2000-</rich_text><rich_text weight="heavy">04-30</rich_text><rich_text>
(2000-03-30 + P1M) + P1D = 2000-04-30 + P1D = 2000-</rich_text><rich_text weight="heavy">05-01</rich_text><rich_text>
</rich_text><table char_offset="141" col_max="200" col_min="40"><row><cell>primitive</cell><cell>string</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>boolean</cell><cell>false</cell><cell>false</cell><cell>finite</cell><cell>false</cell></row><row><cell></cell><cell>float</cell><cell>partial</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>double</cell><cell>partial</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>decimal</cell><cell>total</cell><cell>false</cell><cell>countably infinite</cell><cell>true</cell></row><row><cell></cell><cell>duration</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>dateTime</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>time</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>date</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>gYearMonth</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>gYear</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>gMonthDay</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>gDay</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>gMonth</cell><cell>partial</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>hexBinary</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>base64Binary</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>anyURI</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>QName</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>NOTATION</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell></cell><cell></cell><cell></cell><cell></cell><cell></cell></row><row><cell>derived</cell><cell>normalizedString</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>token</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>language</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>IDREFS</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>ENTITIES</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>NMTOKEN</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>NMTOKENS</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>Name</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>NCName</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>ID</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>IDREF</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>ENTITY</cell><cell>false</cell><cell>false</cell><cell>countably infinite</cell><cell>false</cell></row><row><cell></cell><cell>integer</cell><cell>total</cell><cell>false</cell><cell>countably infinite</cell><cell>true</cell></row><row><cell></cell><cell>nonPositiveInteger</cell><cell>total</cell><cell>false</cell><cell>countably infinite</cell><cell>true</cell></row><row><cell></cell><cell>negativeInteger</cell><cell>total</cell><cell>false</cell><cell>countably infinite</cell><cell>true</cell></row><row><cell></cell><cell>long</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>int</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>short</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>byte</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>nonNegativeInteger</cell><cell>total</cell><cell>false</cell><cell>countably infinite</cell><cell>true</cell></row><row><cell></cell><cell>unsignedLong</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>unsignedInt</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>unsignedShort</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>unsignedByte</cell><cell>total</cell><cell>true</cell><cell>finite</cell><cell>true</cell></row><row><cell></cell><cell>positiveInteger</cell><cell>total</cell><cell>false</cell><cell>countably infinite</cell><cell>true</cell></row><row><cell> </cell><cell>Datatype</cell><cell>ordered</cell><cell>bounded</cell><cell>cardinality</cell><cell>numeric</cell></row></table><encoded_png char_offset="178">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACqElEQVQokSXSz28UZRwH4M+8885sp+1Su21TSgOiXEwgafSEQknwQDTRhGj0auJV/ReMF88e/BUh0YsHDhqVgwoBQqJiTKxGtNRQocF0pbTd7c7szrwz74/vxwPP3/DA1cOmLMQHCovcCGmFTfCeNjc7wkpYFcV28DWF+e4ApN3rb1PY2y1EuHl/0M9rT/aKvqd1Ug6rHmnJYMqKgZGzVQi8cWNl/Z97++cXn3/hdAjQKaxjmkQRRAEAvAt11WTZhKpr2xobf/qZZahkde3u6uoDpVAZaBXluXdBCdTIWJ0k7X2TPoSI5G4vH8+mWmM4f/670lgRzMx1Xn1lOW0BEbxFrJBqPKQGRT49M1XVzgf89POvp06d6XQOXL/2y/p6vbHhnYVOEWuUBrVhUyPypDE+a2kSH350+ciRYwcPHlAxbv55a2e3u7jYOXHiqbmZqNc3ztbtdlsVw1GWaRewV2CwN5qdnd8b2G63OHTosfn5hatXr3/x5Vfeo9v97/KlK865yJHDomm3W0J8/MG1k8vPmlqmp9WoDGNZZG1xa21l897dRw8vPLm0NPVIO3JkBEBQVfjhx43BoDl69In7W/3Zuakg5sKFzyYm1Dtvv+E8flv54/jxJbjgyzrkQ7rA115/d+02N/7l7zfDe+9//8mnVzYfsCG3+83WzkiE1lIziLe+PZnlBZ47c9o5c/Hipb9vr7380osnl49l4zCldKZThdRaeu91ksRN0wBo78OdO3/lxc5bb551craVINbwAVoLoKz1EdVElmhAEq1sE77+5tvHDy/M7V9IUyhBHKM0RkVhcmwckFaqvQ3eEb4ZeWce5jt37nNPljWbQEvXiBHWwrrX3zLViEIGRpQGjLyHThISxcjoVpIkUaxEYCGilIqhgRjUIP4HTSzK2TM8HfoAAAAASUVORK5CYII=</encoded_png><encoded_png char_offset="4753">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACkElEQVQokQXBS48UVRgG4Pf7TtWprtt02zOjiRDHKKMSY8Qdi1ZDXBhioiMhQeP/wN/h2kQ3sJGNyYRLQhiUjYgsXOliMJoeUBimu6un61SdU3UuPg8F50AeoXehE0L0wTIJQHrIvg8yYucQMZhRr5ZlmbPVGgCYhZAARRQr3StjrPPWOiIQgRlNo8uyXFQLCt4B/riaJ1kCIilTCyJEADzQG2jtvv/u25dPbH5y/qO1smAAISCSSZLkUha6D4tF2zk0Gk8e61hiWaksL2dHc3DUdDrq+y6WMstLFwDipkFRloIhJO7de7hYzM+8+3Y5HH956SsAy3oWgSiAAejOJgmXQ6k1ZkfYu/Pg4OBwZ+ezAENs50sjYzcshuSCJ9CzZ7PNl9a7HqrB7dsPZjP1/uScMb3pWhHZ6fSPzy9MWqOzRLL3/vDw6NeHvy0qc/PGT3f2fvnn78dnz06qSq2vxzIeVNVxlhXOgyCUVszMo9Fof39/d3f37t2frbUXL16o63ptLe8M2tasjzdWq1VduzSJ00EeEWi1Wr3x+qnXTr3516PprZvXD6aH29vvFPno3/+WzGhak6YpMwNQjSKtOxZiPq82XhxrgzjB/fvTq1d+eHVr+8MPzvlgX9kaP3365Mx7J/rOxZIo+AACgACo1g9S9gHO4+vL34zHG5PJBKHrrTr91tbJky/UTU3BhefPj0ajUZxEAegdauWyQiwrBI9r1370ttvYHH5x6eNGd1kqKXQBAiAodey8L9dGHtAGiYQLEIS9vd8f7f+Z5fHOp+eHw5yCCRBo1HKQD1hwADofmGXbuiwV9TG8D7FAUVCjTF4kZJUVA9GbJk5jwDv4EIhIWs9MYMB7RIy29ZEAyP8PHzZhnQDPlrUAAAAASUVORK5CYII=</encoded_png><encoded_png char_offset="4755">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACqElEQVQokSXSz28UZRwH4M+8885sp+1Su21TSgOiXEwgafSEQknwQDTRhGj0auJV/ReMF88e/BUh0YsHDhqVgwoBQqJiTKxGtNRQocF0pbTd7c7szrwz74/vxwPP3/DA1cOmLMQHCovcCGmFTfCeNjc7wkpYFcV28DWF+e4ApN3rb1PY2y1EuHl/0M9rT/aKvqd1Ug6rHmnJYMqKgZGzVQi8cWNl/Z97++cXn3/hdAjQKaxjmkQRRAEAvAt11WTZhKpr2xobf/qZZahkde3u6uoDpVAZaBXluXdBCdTIWJ0k7X2TPoSI5G4vH8+mWmM4f/670lgRzMx1Xn1lOW0BEbxFrJBqPKQGRT49M1XVzgf89POvp06d6XQOXL/2y/p6vbHhnYVOEWuUBrVhUyPypDE+a2kSH350+ciRYwcPHlAxbv55a2e3u7jYOXHiqbmZqNc3ztbtdlsVw1GWaRewV2CwN5qdnd8b2G63OHTosfn5hatXr3/x5Vfeo9v97/KlK865yJHDomm3W0J8/MG1k8vPmlqmp9WoDGNZZG1xa21l897dRw8vPLm0NPVIO3JkBEBQVfjhx43BoDl69In7W/3Zuakg5sKFzyYm1Dtvv+E8flv54/jxJbjgyzrkQ7rA115/d+02N/7l7zfDe+9//8mnVzYfsCG3+83WzkiE1lIziLe+PZnlBZ47c9o5c/Hipb9vr7380osnl49l4zCldKZThdRaeu91ksRN0wBo78OdO3/lxc5bb551craVINbwAVoLoKz1EdVElmhAEq1sE77+5tvHDy/M7V9IUyhBHKM0RkVhcmwckFaqvQ3eEb4ZeWce5jt37nNPljWbQEvXiBHWwrrX3zLViEIGRpQGjLyHThISxcjoVpIkUaxEYCGilIqhgRjUIP4HTSzK2TM8HfoAAAAASUVORK5CYII=</encoded_png><encoded_png char_offset="5768">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACkElEQVQokQXBS48UVRgG4Pf7TtWprtt02zOjiRDHKKMSY8Qdi1ZDXBhioiMhQeP/wN/h2kQ3sJGNyYRLQhiUjYgsXOliMJoeUBimu6un61SdU3UuPg8F50AeoXehE0L0wTIJQHrIvg8yYucQMZhRr5ZlmbPVGgCYhZAARRQr3StjrPPWOiIQgRlNo8uyXFQLCt4B/riaJ1kCIilTCyJEADzQG2jtvv/u25dPbH5y/qO1smAAISCSSZLkUha6D4tF2zk0Gk8e61hiWaksL2dHc3DUdDrq+y6WMstLFwDipkFRloIhJO7de7hYzM+8+3Y5HH956SsAy3oWgSiAAejOJgmXQ6k1ZkfYu/Pg4OBwZ+ezAENs50sjYzcshuSCJ9CzZ7PNl9a7HqrB7dsPZjP1/uScMb3pWhHZ6fSPzy9MWqOzRLL3/vDw6NeHvy0qc/PGT3f2fvnn78dnz06qSq2vxzIeVNVxlhXOgyCUVszMo9Fof39/d3f37t2frbUXL16o63ptLe8M2tasjzdWq1VduzSJ00EeEWi1Wr3x+qnXTr3516PprZvXD6aH29vvFPno3/+WzGhak6YpMwNQjSKtOxZiPq82XhxrgzjB/fvTq1d+eHVr+8MPzvlgX9kaP3365Mx7J/rOxZIo+AACgACo1g9S9gHO4+vL34zHG5PJBKHrrTr91tbJky/UTU3BhefPj0ajUZxEAegdauWyQiwrBI9r1370ttvYHH5x6eNGd1kqKXQBAiAodey8L9dGHtAGiYQLEIS9vd8f7f+Z5fHOp+eHw5yCCRBo1HKQD1hwADofmGXbuiwV9TG8D7FAUVCjTF4kZJUVA9GbJk5jwDv4EIhIWs9MYMB7RIy29ZEAyP8PHzZhnQDPlrUAAAAASUVORK5CYII=</encoded_png><table char_offset="8267" col_max="500" col_min="40"><row><cell>31</cell><cell>M = January, March, May, July, August, October, or December</cell></row><row><cell>30</cell><cell>M = April, June, September, or November</cell></row><row><cell>29</cell><cell>M = February AND (modulo(Y, 400) = 0 OR (modulo(Y, 100) != 0) AND modulo(Y, 4) = 0)</cell></row><row><cell>28</cell><cell>Otherwise</cell></row><row><cell>click me</cell><cell>click me</cell></row></table><encoded_png char_offset="8271">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACqElEQVQokSXSz28UZRwH4M+8885sp+1Su21TSgOiXEwgafSEQknwQDTRhGj0auJV/ReMF88e/BUh0YsHDhqVgwoBQqJiTKxGtNRQocF0pbTd7c7szrwz74/vxwPP3/DA1cOmLMQHCovcCGmFTfCeNjc7wkpYFcV28DWF+e4ApN3rb1PY2y1EuHl/0M9rT/aKvqd1Ug6rHmnJYMqKgZGzVQi8cWNl/Z97++cXn3/hdAjQKaxjmkQRRAEAvAt11WTZhKpr2xobf/qZZahkde3u6uoDpVAZaBXluXdBCdTIWJ0k7X2TPoSI5G4vH8+mWmM4f/670lgRzMx1Xn1lOW0BEbxFrJBqPKQGRT49M1XVzgf89POvp06d6XQOXL/2y/p6vbHhnYVOEWuUBrVhUyPypDE+a2kSH350+ciRYwcPHlAxbv55a2e3u7jYOXHiqbmZqNc3ztbtdlsVw1GWaRewV2CwN5qdnd8b2G63OHTosfn5hatXr3/x5Vfeo9v97/KlK865yJHDomm3W0J8/MG1k8vPmlqmp9WoDGNZZG1xa21l897dRw8vPLm0NPVIO3JkBEBQVfjhx43BoDl69In7W/3Zuakg5sKFzyYm1Dtvv+E8flv54/jxJbjgyzrkQ7rA115/d+02N/7l7zfDe+9//8mnVzYfsCG3+83WzkiE1lIziLe+PZnlBZ47c9o5c/Hipb9vr7380osnl49l4zCldKZThdRaeu91ksRN0wBo78OdO3/lxc5bb551craVINbwAVoLoKz1EdVElmhAEq1sE77+5tvHDy/M7V9IUyhBHKM0RkVhcmwckFaqvQ3eEb4ZeWce5jt37nNPljWbQEvXiBHWwrrX3zLViEIGRpQGjLyHThISxcjoVpIkUaxEYCGilIqhgRjUIP4HTSzK2TM8HfoAAAAASUVORK5CYII=</encoded_png><table char_offset="11212" col_max="500" col_min="40"><row><cell>2000-01-12T12:13:14Z</cell><cell>P1Y3M5DT7H10M3.3S</cell><cell>2001-04-17T19:23:17.3Z</cell></row><row><cell>2000-01</cell><cell>-P3M</cell><cell>1999-10</cell></row><row><cell>2000-01-12</cell><cell>PT33H</cell><cell>2000-01-13</cell></row><row><cell>dateTime</cell><cell>duration</cell><cell>result</cell></row></table><encoded_png char_offset="11215">iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACkElEQVQokQXBS48UVRgG4Pf7TtWprtt02zOjiRDHKKMSY8Qdi1ZDXBhioiMhQeP/wN/h2kQ3sJGNyYRLQhiUjYgsXOliMJoeUBimu6un61SdU3UuPg8F50AeoXehE0L0wTIJQHrIvg8yYucQMZhRr5ZlmbPVGgCYhZAARRQr3StjrPPWOiIQgRlNo8uyXFQLCt4B/riaJ1kCIilTCyJEADzQG2jtvv/u25dPbH5y/qO1smAAISCSSZLkUha6D4tF2zk0Gk8e61hiWaksL2dHc3DUdDrq+y6WMstLFwDipkFRloIhJO7de7hYzM+8+3Y5HH956SsAy3oWgSiAAejOJgmXQ6k1ZkfYu/Pg4OBwZ+ezAENs50sjYzcshuSCJ9CzZ7PNl9a7HqrB7dsPZjP1/uScMb3pWhHZ6fSPzy9MWqOzRLL3/vDw6NeHvy0qc/PGT3f2fvnn78dnz06qSq2vxzIeVNVxlhXOgyCUVszMo9Fof39/d3f37t2frbUXL16o63ptLe8M2tasjzdWq1VduzSJ00EeEWi1Wr3x+qnXTr3516PprZvXD6aH29vvFPno3/+WzGhak6YpMwNQjSKtOxZiPq82XhxrgzjB/fvTq1d+eHVr+8MPzvlgX9kaP3365Mx7J/rOxZIo+AACgACo1g9S9gHO4+vL34zHG5PJBKHrrTr91tbJky/UTU3BhefPj0ajUZxEAegdauWyQiwrBI9r1370ttvYHH5x6eNGd1kqKXQBAiAodey8L9dGHtAGiYQLEIS9vd8f7f+Z5fHOp+eHw5yCCRBo1HKQD1hwADofmGXbuiwV9TG8D7FAUVCjTF4kZJUVA9GbJk5jwDv4EIhIWs9MYMB7RIy29ZEAyP8PHzZhnQDPlrUAAAAASUVORK5CYII=</encoded_png></node><node name="Regular Expressions" prog_lang="custom-colors" readonly="False" tags="" unique_id="59"><rich_text>
</rich_text><rich_text scale="h2">Regular Expressions</rich_text><rich_text>
A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">·regular expression·</rich_text><rich_text> R is a sequence of characters that denote a </rich_text><rich_text weight="heavy">set of strings</rich_text><rich_text> L(R). When used to constrain a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text>, a </rich_text><rich_text weight="heavy">regular expression</rich_text><rich_text> Rasserts that only strings in L(R) are valid literals for values of that type.
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> Unlike some popular regular expression languages (including those defined by Perl and standard Unix utilities), the regular expression language defined here implicitly anchors all regular expressions at the head and tail, as the most common use of regular expressions in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-pattern">·pattern·</rich_text><rich_text> is to match entire literals. For example, a datatype </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string">string</rich_text><rich_text> such that all values must begin with the character A (#x41) and end with the character Z (#x5a) would be defined as follows:<simpleType name='myString'>
<restriction base='string'>
<pattern value='A.*Z'/>
</restriction>
</simpleType>
In regular expression languages that are not implicitly anchored at the head and tail, it is customary to write the equivalent regular expression as:
^A.*Z$
where "^" anchors the pattern at the head and "$" anchors at the tail.
In those rare cases where an unanchored match is desired, including .* at the beginning and ending of the regular expression will achieve the desired results. For example, a datatype </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from string such that all values must contain at least 3 consecutive A (#x41) characters somewhere within the value could be defined as follows:
<simpleType name='myString'>
<restriction base='string'>
<pattern value='.*AAA.*'/>
</restriction>
</simpleType>
</rich_text><rich_text foreground="#850021">[Definition:] A </rich_text><rich_text weight="heavy">regular expression</rich_text><rich_text> is composed from zero or more </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-branch">·branch·</rich_text><rich_text>es, separated by | characters.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">branch</rich_text><rich_text> consists of zero or more </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-piece">·piece·</rich_text><rich_text>s, concatenated together.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">piece</rich_text><rich_text> is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atom">·atom·</rich_text><rich_text>, possibly followed by a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-quantifier">·quantifier·</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The regular expression language in the Perl Programming Language </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#Perl">[Perl]</rich_text><rich_text> does not include a quantifier of the form S{,m}, since it is logically equivalent to S{0,m}. We have, therefore, left this logical possibility out of the regular expression language defined by this specification.</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">quantifier</rich_text><rich_text> is one of ?, *, +, {n,m} or {n,}, which have the meanings defined in the table above.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>An </rich_text><rich_text weight="heavy">atom</rich_text><rich_text> is either a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-normalc">·normal character·</rich_text><rich_text>, a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charclass">·character class·</rich_text><rich_text>, or a parenthesized </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">·regular expression·</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">metacharacter</rich_text><rich_text> is either ., \, ?, *, +, {, } (, ), [ or ]. These characters have special meanings in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">·regular expression·</rich_text><rich_text>s, but can be escaped to form</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atom">·atom·</rich_text><rich_text>s that denote the sets of strings containing only themselves, i.e., an escaped </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-metac">·metacharacter·</rich_text><rich_text> behaves like a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-normalc">·normal character·</rich_text><rich_text>.
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">normal character</rich_text><rich_text> is any XML character that is not a metacharacter. In </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">·regular expression·</rich_text><rich_text>s, a normal character is an atom that denotes the singleton set of strings containing only itself.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note that a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-normalc">·normal character·</rich_text><rich_text> can be represented either as itself, or with a </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-charref">character reference</rich_text><rich_text>.
</rich_text><rich_text scale="h3">F.1 Character Classes</rich_text><rich_text>
[Definition:] A </rich_text><rich_text weight="heavy">character class</rich_text><rich_text> is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atom">·atom·</rich_text><rich_text> R that identifies a </rich_text><rich_text weight="heavy">set of characters</rich_text><rich_text> C(R). The set of strings L(R) denoted by a character class R contains one single-character string "c" for each character c in C(R).
</rich_text><rich_text justification="left"></rich_text><rich_text>
A character class is either a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cces">·character class escape·</rich_text><rich_text> or a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charexpr">·character class expression·</rich_text><rich_text>.
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">character class expression</rich_text><rich_text> is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-chargroup">·character group·</rich_text><rich_text> surrounded by [ and ] characters. For all character groups G, [G] is a valid </rich_text><rich_text weight="heavy">character class expression</rich_text><rich_text>, identifying the set of characters C([G]) = C(G).
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">character group</rich_text><rich_text> is either a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text>, a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-negchargroup">·negative character group·</rich_text><rich_text>, or a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-subchargroup">·character class subtraction·</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">positive character group</rich_text><rich_text> consists of one or more </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charrange">·character range·</rich_text><rich_text>s or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cces">·character class escape·</rich_text><rich_text>s, concatenated together. A </rich_text><rich_text weight="heavy">positive character group</rich_text><rich_text> identifies the set of characters containing all of the characters in all of the sets identified by its constituent ranges or escapes.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">negative character group</rich_text><rich_text> is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text> preceded by the ^ character. For all </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text>s P, ^P is a valid</rich_text><rich_text weight="heavy">negative character group</rich_text><rich_text>, and C(^P) contains all XML characters that are not in C(P).
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">character class subtraction</rich_text><rich_text> is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charexpr">·character class expression·</rich_text><rich_text> subtracted from a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-negchargroup">·negative character group·</rich_text><rich_text>, using the - character.
</rich_text><rich_text justification="left"></rich_text><rich_text>
For any </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-negchargroup">·negative character group·</rich_text><rich_text> G, and any </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charexpr">·character class expression·</rich_text><rich_text> C, G-C is a valid </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-subchargroup">·character class subtraction·</rich_text><rich_text>, identifying the set of all characters in C(G) that are not also in C(C).
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">character range</rich_text><rich_text> R identifies a set of characters C(R) containing all XML characters with UCS code points in a specified range.
</rich_text><rich_text justification="left"></rich_text><rich_text>
A single XML character is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charrange">·character range·</rich_text><rich_text> that identifies the set of characters containing only itself. All XML characters are valid character ranges, except as follows:
• The [, ], - and \ characters are not valid character ranges;
• The ^ character is only valid at the beginning of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text> if it is part of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-negchargroup">·negative character group·</rich_text><rich_text>
• The - character is a valid character range only at the beginning or end of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-poschargroup">·positive character group·</rich_text><rich_text>.
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text>The grammar for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charrange">·character range·</rich_text><rich_text> as given above is ambiguous, but the second and third bullets above together remove the ambiguity.A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charrange">·character range·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-may">·may·</rich_text><rich_text> also be written in the form s-e, identifying the set that contains all XML characters with UCS code points greater than or equal to the code point of s, but not greater than the code point of e.
s-e is a valid character range iff:
• s is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cces1">·single character escape·</rich_text><rich_text>, or an XML character;
• s is not \
• If s is the first character in a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-charexpr">·character class expression·</rich_text><rich_text>, then s is not ^
• e is a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cces1">·single character escape·</rich_text><rich_text>, or an XML character;
• e is not \ or [; and
• The code point of e is greater than or equal to the code point of s;
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The code point of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cces1">·single character escape·</rich_text><rich_text> is the code point of the single character in the set of characters that it identifies.F.1.1 Character Class Escapes[Definition:] A </rich_text><rich_text weight="heavy">character class escape</rich_text><rich_text> is a short sequence of characters that identifies predefined character class. The valid character class escapes are the</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cces1">·single character escape·</rich_text><rich_text>s, the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ccesN">·multi-character escape·</rich_text><rich_text>s, and the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ccescat">·category escape·</rich_text><rich_text>s (including the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ccesblock">·block escape·</rich_text><rich_text>s).
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">single character escape</rich_text><rich_text> identifies a set containing a only one character -- usually because that character is difficult or impossible to write directly into a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">·regular expression·</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text> specifies a number of possible values for the "General Category" property and provides mappings from code points to specific character properties. The set containing all characters that have property X, can be identified with a </rich_text><rich_text weight="heavy">category escape</rich_text><rich_text> \p{X}. The complement of this set is specified with the </rich_text><rich_text weight="heavy">category escape</rich_text><rich_text> \P{X}. ([\P{X}] = [^\p{X}]).
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text> is subject to future revision. For example, the mapping from code points to character properties might be updated. All </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minimally-conforming">·minimally conforming·</rich_text><rich_text> processors </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">·must·</rich_text><rich_text> support the character properties defined in the version of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text> that is current at the time this specification became a W3C Recommendation. However, implementors are encouraged to support the character properties defined in any future version.The following table specifies the recognized values of the "General Category" property.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The properties mentioned above exclude the Cs property. The Cs property identifies "surrogate" characters, which do not occur at the level of the "character abstraction" that XML instance documents operate on.</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text> groups code points into a number of blocks such as Basic Latin (i.e., ASCII), Latin-1 Supplement, Hangul Jamo, CJK Compatibility, etc. The set containing all characters that have block name X (with all white space stripped out), can be identified with a </rich_text><rich_text weight="heavy">block escape</rich_text><rich_text> \p{IsX}. The complement of this set is specified with the </rich_text><rich_text weight="heavy">block escape</rich_text><rich_text> \P{IsX}. ([\P{IsX}] = [^\p{IsX}]).
</rich_text><rich_text justification="left"></rich_text><rich_text>
The following table specifies the recognized block names (for more information, see the "Blocks.txt" file in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text>).
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The blocks mentioned above exclude the HighSurrogates, LowSurrogates and HighPrivateUseSurrogates blocks. These blocks identify "surrogate" characters, which do not occur at the level of the "character abstraction" that XML instance documents operate on.</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text> is subject to future revision. For example, the grouping of code points into blocks might be updated. All </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minimally-conforming">·minimally conforming·</rich_text><rich_text>processors </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">·must·</rich_text><rich_text> support the blocks defined in the version of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#UnicodeDB">[Unicode Database]</rich_text><rich_text> that is current at the time this specification became a W3C Recommendation. However, implementors are encouraged to support the blocks defined in any future version of the Unicode Standard.For example, the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ccesblock">·block escape·</rich_text><rich_text> for identifying the ASCII characters is \p{IsBasicLatin}.
</rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>A </rich_text><rich_text weight="heavy">multi-character escape</rich_text><rich_text> provides a simple way to identify a commonly used set of characters:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">·regular expression·</rich_text><rich_text> language defined here does not attempt to provide a general solution to "regular expressions" over UCS character sequences. In particular, it does not easily provide for matching sequences of base characters and combining marks. The language is targeted at support of "Level 1" features as defined in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unicodeRegEx">[Unicode Regular Expression Guidelines]</rich_text><rich_text>. It is hoped that future versions of this specification will provide support for "Level 2" features.</rich_text><table char_offset="1649" col_max="300" col_min="40"><row><cell>[1] </cell><cell>regExp</cell><cell> ::= </cell><cell>branch ( '|' branch )*</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="1652" col_max="1000" col_min="40"><row><cell>(empty string)</cell><cell>the set containing just the empty string</cell></row><row><cell>S</cell><cell>all strings in L(S)</cell></row><row><cell>S|T</cell><cell>all strings in L(S) and all strings in L(T)</cell></row><row><cell>For all ·branch·es S, and for all ·regular expression·s T, valid ·regular expression·s R are:</cell><cell>Denoting the set of strings L(R) containing:</cell></row></table><table char_offset="1737" col_max="300" col_min="40"><row><cell>[2] </cell><cell>branch</cell><cell> ::= </cell><cell>piece*</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="1740" col_max="1000" col_min="40"><row><cell>S</cell><cell>all strings in L(S)</cell></row><row><cell>ST</cell><cell>all strings st with s in L(S) and t in L(T)</cell></row><row><cell>For all ·piece·s S, and for all ·branch·es T, valid ·branch·es R are:</cell><cell>Denoting the set of strings L(R) containing:</cell></row></table><table char_offset="1817" col_max="300" col_min="40"><row><cell>[3] </cell><cell>piece</cell><cell> ::= </cell><cell>atom quantifier?</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="1820" col_max="1000" col_min="40"><row><cell>S</cell><cell>all strings in L(S)</cell></row><row><cell>S?</cell><cell>the empty string, and all strings in L(S).</cell></row><row><cell>S*</cell><cell>All strings in L(S?) and all strings st with s in L(S*) and t in L(S). ( all concatenations of zero or more strings from L(S) )</cell></row><row><cell>S+</cell><cell>All strings st with s in L(S) and t in L(S*). ( all concatenations of one or more strings from L(S) )</cell></row><row><cell>S{n,m}</cell><cell>All strings st with s in L(S) and t in L(S{n-1,m-1}). ( All sequences of at least n, and at most m, strings from L(S) )</cell></row><row><cell>S{n}</cell><cell>All strings in L(S{n,n}). ( All sequences of exactly n strings from L(S) )</cell></row><row><cell>S{n,}</cell><cell>All strings in L(S{n}S*) ( All sequences of at least n, strings from L(S) )</cell></row><row><cell>S{0,m}</cell><cell>All strings st with s in L(S?) and t in L(S{0,m-1}). ( All sequences of at most m, strings from L(S) )</cell></row><row><cell>S{0,0}</cell><cell>The set containing only the empty string</cell></row><row><cell>For all ·atom·s S and non-negative integers n, m such that n <= m, valid ·piece·s R are:</cell><cell>Denoting the set of strings L(R) containing:</cell></row></table><table char_offset="2228" col_max="1000" col_min="40"><row><cell>[4] </cell><cell>quantifier</cell><cell> ::= </cell><cell>[?*+] | ( '{' quantity '}' )</cell></row><row><cell>[5] </cell><cell>quantity</cell><cell> ::= </cell><cell>quantRange | quantMin | QuantExact</cell></row><row><cell>[6] </cell><cell>quantRange</cell><cell> ::= </cell><cell>QuantExact ',' QuantExact</cell></row><row><cell>[7] </cell><cell>quantMin</cell><cell> ::= </cell><cell>QuantExact ','</cell></row><row><cell>[8] </cell><cell>QuantExact</cell><cell> ::= </cell><cell>[0-9]+</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="2348" col_max="1000" col_min="40"><row><cell>[9] </cell><cell>atom</cell><cell> ::= </cell><cell>Char | charClass | ( '(' regExp ')' )</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="2351" col_max="1000" col_min="40"><row><cell>c</cell><cell>the single string consisting only of c</cell></row><row><cell>C</cell><cell>all strings in L(C)</cell></row><row><cell>(S)</cell><cell>all strings in L(S)</cell></row><row><cell>For all ·normal character·s c, ·character class·es C, and ·regular expression·s S, valid ·atom·s R are:</cell><cell>Denoting the set of strings L(R) containing:</cell></row></table><table char_offset="2863" col_max="1000" col_min="40"><row><cell>[10] </cell><cell>Char</cell><cell> ::= </cell><cell>[^.\?*+()|#x5B#x5D]</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="3206" col_max="1000" col_min="40"><row><cell>[11] </cell><cell>charClass</cell><cell> ::= </cell><cell>charClassEsc | charClassExpr | WildcardEsc</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="3520" col_max="1000" col_min="40"><row><cell>[12] </cell><cell>charClassExpr</cell><cell> ::= </cell><cell>'[' charGroup ']'</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="3662" col_max="1000" col_min="40"><row><cell>[13] </cell><cell>charGroup</cell><cell> ::= </cell><cell>posCharGroup | negCharGroup | charClassSub</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="3964" col_max="1000" col_min="40"><row><cell>[14] </cell><cell>posCharGroup</cell><cell> ::= </cell><cell>( charRange | charClassEsc )+</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="3967" col_max="1000" col_min="40"><row><cell>R</cell><cell>all characters in C(R).</cell></row><row><cell>E</cell><cell>all characters in C(E).</cell></row><row><cell>RP</cell><cell>all characters in C(R) and all characters in C(P).</cell></row><row><cell>EP</cell><cell>all characters in C(E) and all characters in C(P).</cell></row><row><cell>For all ·character range·s R, all ·character class escape·s E, and all·positive character group·s P, valid ·positive character group·s G are:</cell><cell>Identifying the set of characters C(G) containing:</cell></row></table><table char_offset="4211" col_max="1000" col_min="40"><row><cell>[15] </cell><cell>negCharGroup</cell><cell> ::= </cell><cell>'^' posCharGroup</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="4392" col_max="1000" col_min="40"><row><cell>[16] </cell><cell>charClassSub</cell><cell> ::= </cell><cell>( posCharGroup | negCharGroup ) '-' charClassExpr</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="4766" col_max="1000" col_min="40"><row><cell>[17] </cell><cell>charRange</cell><cell> ::= </cell><cell>seRange | XmlCharIncDash</cell></row><row><cell>[18] </cell><cell>seRange</cell><cell> ::= </cell><cell>charOrEsc '-' charOrEsc</cell></row><row><cell>[20] </cell><cell>charOrEsc</cell><cell> ::= </cell><cell>XmlChar | SingleCharEsc</cell></row><row><cell>[21] </cell><cell>XmlChar</cell><cell> ::= </cell><cell>[^\#x2D#x5B#x5D]</cell></row><row><cell>[22] </cell><cell>XmlCharIncDash</cell><cell> ::= </cell><cell>[^\#x5B#x5D]</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="6383" col_max="1000" col_min="40"><row><cell>[23] </cell><cell>charClassEsc</cell><cell> ::= </cell><cell>( SingleCharEsc | MultiCharEsc | catEsc | complEsc )</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="6584" col_max="1000" col_min="40"><row><cell>[24] </cell><cell>SingleCharEsc</cell><cell> ::= </cell><cell>'\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="6587" col_max="1000" col_min="40"><row><cell>\n</cell><cell>the newline character (#xA)</cell></row><row><cell>\r</cell><cell>the return character (#xD)</cell></row><row><cell>\t</cell><cell>the tab character (#x9)</cell></row><row><cell>\\</cell><cell>\</cell></row><row><cell>\|</cell><cell>|</cell></row><row><cell>\.</cell><cell>.</cell></row><row><cell>\-</cell><cell>-</cell></row><row><cell>\^</cell><cell>^</cell></row><row><cell>\?</cell><cell>?</cell></row><row><cell>\*</cell><cell>*</cell></row><row><cell>\+</cell><cell>+</cell></row><row><cell>\{</cell><cell>{</cell></row><row><cell>\}</cell><cell>}</cell></row><row><cell>\(</cell><cell>(</cell></row><row><cell>\)</cell><cell>)</cell></row><row><cell>\[</cell><cell>[</cell></row><row><cell>\]</cell><cell>]</cell></row><row><cell>The valid ·single character escape·s are:</cell><cell>Identifying the set of characters C(R) containing:</cell></row></table><table char_offset="6969" col_max="1000" col_min="40"><row><cell>[25] </cell><cell>catEsc</cell><cell> ::= </cell><cell>'\p{' charProp '}'</cell></row><row><cell>[26] </cell><cell>complEsc</cell><cell> ::= </cell><cell>'\P{' charProp '}'</cell></row><row><cell>[27] </cell><cell>charProp</cell><cell> ::= </cell><cell>IsCategory | IsBlock</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="7502" col_max="1000" col_min="40"><row><cell>Letters</cell><cell>L</cell><cell>All Letters</cell></row><row><cell></cell><cell>Lu</cell><cell>uppercase</cell></row><row><cell></cell><cell>Ll</cell><cell>lowercase</cell></row><row><cell></cell><cell>Lt</cell><cell>titlecase</cell></row><row><cell></cell><cell>Lm</cell><cell>modifier</cell></row><row><cell></cell><cell>Lo</cell><cell>other</cell></row><row><cell> </cell><cell></cell><cell></cell></row><row><cell>Marks</cell><cell>M</cell><cell>All Marks</cell></row><row><cell></cell><cell>Mn</cell><cell>nonspacing</cell></row><row><cell></cell><cell>Mc</cell><cell>spacing combining</cell></row><row><cell></cell><cell>Me</cell><cell>enclosing</cell></row><row><cell> </cell><cell></cell><cell></cell></row><row><cell>Numbers</cell><cell>N</cell><cell>All Numbers</cell></row><row><cell></cell><cell>Nd</cell><cell>decimal digit</cell></row><row><cell></cell><cell>Nl</cell><cell>letter</cell></row><row><cell></cell><cell>No</cell><cell>other</cell></row><row><cell> </cell><cell></cell><cell></cell></row><row><cell>Punctuation</cell><cell>P</cell><cell>All Punctuation</cell></row><row><cell></cell><cell>Pc</cell><cell>connector</cell></row><row><cell></cell><cell>Pd</cell><cell>dash</cell></row><row><cell></cell><cell>Ps</cell><cell>open</cell></row><row><cell></cell><cell>Pe</cell><cell>close</cell></row><row><cell></cell><cell>Pi</cell><cell>initial quote (may behave like Ps or Pe depending on usage)</cell></row><row><cell></cell><cell>Pf</cell><cell>final quote (may behave like Ps or Pe depending on usage)</cell></row><row><cell></cell><cell>Po</cell><cell>other</cell></row><row><cell> </cell><cell></cell><cell></cell></row><row><cell>Separators</cell><cell>Z</cell><cell>All Separators</cell></row><row><cell></cell><cell>Zs</cell><cell>space</cell></row><row><cell></cell><cell>Zl</cell><cell>line</cell></row><row><cell></cell><cell>Zp</cell><cell>paragraph</cell></row><row><cell> </cell><cell></cell><cell></cell></row><row><cell>Symbols</cell><cell>S</cell><cell>All Symbols</cell></row><row><cell></cell><cell>Sm</cell><cell>math</cell></row><row><cell></cell><cell>Sc</cell><cell>currency</cell></row><row><cell></cell><cell>Sk</cell><cell>modifier</cell></row><row><cell></cell><cell>So</cell><cell>other</cell></row><row><cell> </cell><cell></cell><cell></cell></row><row><cell>Other</cell><cell>C</cell><cell>All Others</cell></row><row><cell></cell><cell>Cc</cell><cell>control</cell></row><row><cell></cell><cell>Cf</cell><cell>format</cell></row><row><cell></cell><cell>Co</cell><cell>private use</cell></row><row><cell></cell><cell>Cn</cell><cell>not assigned</cell></row><row><cell>Category</cell><cell>Property</cell><cell>Meaning</cell></row></table><table char_offset="7504" col_max="1000" col_min="40"><row><cell>[28] </cell><cell>IsCategory</cell><cell> ::= </cell><cell>Letters | Marks | Numbers | Punctuation | Separators | Symbols | Others</cell></row><row><cell>[29] </cell><cell>Letters</cell><cell> ::= </cell><cell>'L' [ultmo]?</cell></row><row><cell>[30] </cell><cell>Marks</cell><cell> ::= </cell><cell>'M' [nce]?</cell></row><row><cell>[31] </cell><cell>Numbers</cell><cell> ::= </cell><cell>'N' [dlo]?</cell></row><row><cell>[32] </cell><cell>Punctuation</cell><cell> ::= </cell><cell>'P' [cdseifo]?</cell></row><row><cell>[33] </cell><cell>Separators</cell><cell> ::= </cell><cell>'Z' [slp]?</cell></row><row><cell>[34] </cell><cell>Symbols</cell><cell> ::= </cell><cell>'S' [mcko]?</cell></row><row><cell>[35] </cell><cell>Others</cell><cell> ::= </cell><cell>'C' [cfon]?</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="8130" col_max="1000" col_min="40"><row><cell>[36] </cell><cell>IsBlock</cell><cell> ::= </cell><cell>'Is' [a-zA-Z0-9#x2D]+</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="8262" col_max="1000" col_min="40"><row><cell>#x0000</cell><cell>#x007F</cell><cell>BasicLatin</cell><cell> </cell><cell>#x0080</cell><cell>#x00FF</cell><cell>Latin-1Supplement</cell></row><row><cell>#x0100</cell><cell>#x017F</cell><cell>LatinExtended-A</cell><cell> </cell><cell>#x0180</cell><cell>#x024F</cell><cell>LatinExtended-B</cell></row><row><cell>#x0250</cell><cell>#x02AF</cell><cell>IPAExtensions</cell><cell> </cell><cell>#x02B0</cell><cell>#x02FF</cell><cell>SpacingModifierLetters</cell></row><row><cell>#x0300</cell><cell>#x036F</cell><cell>CombiningDiacriticalMarks</cell><cell> </cell><cell>#x0370</cell><cell>#x03FF</cell><cell>Greek</cell></row><row><cell>#x0400</cell><cell>#x04FF</cell><cell>Cyrillic</cell><cell> </cell><cell>#x0530</cell><cell>#x058F</cell><cell>Armenian</cell></row><row><cell>#x0590</cell><cell>#x05FF</cell><cell>Hebrew</cell><cell> </cell><cell>#x0600</cell><cell>#x06FF</cell><cell>Arabic</cell></row><row><cell>#x0700</cell><cell>#x074F</cell><cell>Syriac</cell><cell> </cell><cell>#x0780</cell><cell>#x07BF</cell><cell>Thaana</cell></row><row><cell>#x0900</cell><cell>#x097F</cell><cell>Devanagari</cell><cell> </cell><cell>#x0980</cell><cell>#x09FF</cell><cell>Bengali</cell></row><row><cell>#x0A00</cell><cell>#x0A7F</cell><cell>Gurmukhi</cell><cell> </cell><cell>#x0A80</cell><cell>#x0AFF</cell><cell>Gujarati</cell></row><row><cell>#x0B00</cell><cell>#x0B7F</cell><cell>Oriya</cell><cell> </cell><cell>#x0B80</cell><cell>#x0BFF</cell><cell>Tamil</cell></row><row><cell>#x0C00</cell><cell>#x0C7F</cell><cell>Telugu</cell><cell> </cell><cell>#x0C80</cell><cell>#x0CFF</cell><cell>Kannada</cell></row><row><cell>#x0D00</cell><cell>#x0D7F</cell><cell>Malayalam</cell><cell> </cell><cell>#x0D80</cell><cell>#x0DFF</cell><cell>Sinhala</cell></row><row><cell>#x0E00</cell><cell>#x0E7F</cell><cell>Thai</cell><cell> </cell><cell>#x0E80</cell><cell>#x0EFF</cell><cell>Lao</cell></row><row><cell>#x0F00</cell><cell>#x0FFF</cell><cell>Tibetan</cell><cell> </cell><cell>#x1000</cell><cell>#x109F</cell><cell>Myanmar</cell></row><row><cell>#x10A0</cell><cell>#x10FF</cell><cell>Georgian</cell><cell> </cell><cell>#x1100</cell><cell>#x11FF</cell><cell>HangulJamo</cell></row><row><cell>#x1200</cell><cell>#x137F</cell><cell>Ethiopic</cell><cell> </cell><cell>#x13A0</cell><cell>#x13FF</cell><cell>Cherokee</cell></row><row><cell>#x1400</cell><cell>#x167F</cell><cell>UnifiedCanadianAboriginalSyllabics</cell><cell> </cell><cell>#x1680</cell><cell>#x169F</cell><cell>Ogham</cell></row><row><cell>#x16A0</cell><cell>#x16FF</cell><cell>Runic</cell><cell> </cell><cell>#x1780</cell><cell>#x17FF</cell><cell>Khmer</cell></row><row><cell>#x1800</cell><cell>#x18AF</cell><cell>Mongolian</cell><cell> </cell><cell>#x1E00</cell><cell>#x1EFF</cell><cell>LatinExtendedAdditional</cell></row><row><cell>#x1F00</cell><cell>#x1FFF</cell><cell>GreekExtended</cell><cell> </cell><cell>#x2000</cell><cell>#x206F</cell><cell>GeneralPunctuation</cell></row><row><cell>#x2070</cell><cell>#x209F</cell><cell>SuperscriptsandSubscripts</cell><cell> </cell><cell>#x20A0</cell><cell>#x20CF</cell><cell>CurrencySymbols</cell></row><row><cell>#x20D0</cell><cell>#x20FF</cell><cell>CombiningMarksforSymbols</cell><cell> </cell><cell>#x2100</cell><cell>#x214F</cell><cell>LetterlikeSymbols</cell></row><row><cell>#x2150</cell><cell>#x218F</cell><cell>NumberForms</cell><cell> </cell><cell>#x2190</cell><cell>#x21FF</cell><cell>Arrows</cell></row><row><cell>#x2200</cell><cell>#x22FF</cell><cell>MathematicalOperators</cell><cell> </cell><cell>#x2300</cell><cell>#x23FF</cell><cell>MiscellaneousTechnical</cell></row><row><cell>#x2400</cell><cell>#x243F</cell><cell>ControlPictures</cell><cell> </cell><cell>#x2440</cell><cell>#x245F</cell><cell>OpticalCharacterRecognition</cell></row><row><cell>#x2460</cell><cell>#x24FF</cell><cell>EnclosedAlphanumerics</cell><cell> </cell><cell>#x2500</cell><cell>#x257F</cell><cell>BoxDrawing</cell></row><row><cell>#x2580</cell><cell>#x259F</cell><cell>BlockElements</cell><cell> </cell><cell>#x25A0</cell><cell>#x25FF</cell><cell>GeometricShapes</cell></row><row><cell>#x2600</cell><cell>#x26FF</cell><cell>MiscellaneousSymbols</cell><cell> </cell><cell>#x2700</cell><cell>#x27BF</cell><cell>Dingbats</cell></row><row><cell>#x2800</cell><cell>#x28FF</cell><cell>BraillePatterns</cell><cell> </cell><cell>#x2E80</cell><cell>#x2EFF</cell><cell>CJKRadicalsSupplement</cell></row><row><cell>#x2F00</cell><cell>#x2FDF</cell><cell>KangxiRadicals</cell><cell> </cell><cell>#x2FF0</cell><cell>#x2FFF</cell><cell>IdeographicDescriptionCharacters</cell></row><row><cell>#x3000</cell><cell>#x303F</cell><cell>CJKSymbolsandPunctuation</cell><cell> </cell><cell>#x3040</cell><cell>#x309F</cell><cell>Hiragana</cell></row><row><cell>#x30A0</cell><cell>#x30FF</cell><cell>Katakana</cell><cell> </cell><cell>#x3100</cell><cell>#x312F</cell><cell>Bopomofo</cell></row><row><cell>#x3130</cell><cell>#x318F</cell><cell>HangulCompatibilityJamo</cell><cell> </cell><cell>#x3190</cell><cell>#x319F</cell><cell>Kanbun</cell></row><row><cell>#x31A0</cell><cell>#x31BF</cell><cell>BopomofoExtended</cell><cell> </cell><cell>#x3200</cell><cell>#x32FF</cell><cell>EnclosedCJKLettersandMonths</cell></row><row><cell>#x3300</cell><cell>#x33FF</cell><cell>CJKCompatibility</cell><cell> </cell><cell>#x3400</cell><cell>#x4DB5</cell><cell>CJKUnifiedIdeographsExtensionA</cell></row><row><cell>#x4E00</cell><cell>#x9FFF</cell><cell>CJKUnifiedIdeographs</cell><cell> </cell><cell>#xA000</cell><cell>#xA48F</cell><cell>YiSyllables</cell></row><row><cell>#xA490</cell><cell>#xA4CF</cell><cell>YiRadicals</cell><cell> </cell><cell>#xAC00</cell><cell>#xD7A3</cell><cell>HangulSyllables</cell></row><row><cell></cell><cell></cell><cell></cell><cell> </cell><cell></cell><cell></cell><cell></cell></row><row><cell></cell><cell></cell><cell></cell><cell> </cell><cell>#xE000</cell><cell>#xF8FF</cell><cell>PrivateUse</cell></row><row><cell>#xF900</cell><cell>#xFAFF</cell><cell>CJKCompatibilityIdeographs</cell><cell> </cell><cell>#xFB00</cell><cell>#xFB4F</cell><cell>AlphabeticPresentationForms</cell></row><row><cell>#xFB50</cell><cell>#xFDFF</cell><cell>ArabicPresentationForms-A</cell><cell> </cell><cell>#xFE20</cell><cell>#xFE2F</cell><cell>CombiningHalfMarks</cell></row><row><cell>#xFE30</cell><cell>#xFE4F</cell><cell>CJKCompatibilityForms</cell><cell> </cell><cell>#xFE50</cell><cell>#xFE6F</cell><cell>SmallFormVariants</cell></row><row><cell>#xFE70</cell><cell>#xFEFE</cell><cell>ArabicPresentationForms-B</cell><cell> </cell><cell>#xFEFF</cell><cell>#xFEFF</cell><cell>Specials</cell></row><row><cell>#xFF00</cell><cell>#xFFEF</cell><cell>HalfwidthandFullwidthForms</cell><cell> </cell><cell>#xFFF0</cell><cell>#xFFFD</cell><cell>Specials</cell></row><row><cell>Start Code</cell><cell>End Code</cell><cell>Block Name</cell><cell> </cell><cell>Start Code</cell><cell>End Code</cell><cell>Block Name</cell></row></table><table char_offset="9150" col_max="1000" col_min="40"><row><cell>[37] </cell><cell>MultiCharEsc</cell><cell> ::= </cell><cell>'\' [sSiIcCdDwW]</cell></row><row><cell>[37a] </cell><cell>WildcardEsc</cell><cell> ::= </cell><cell>'.'</cell></row><row><cell>click me</cell><cell>click me</cell><cell>click me</cell><cell>click me</cell></row></table><table char_offset="9153" col_max="1000" col_min="40"><row><cell>.</cell><cell>[^\n\r]</cell></row><row><cell>\s</cell><cell>[#x20\t\n\r]</cell></row><row><cell>\S</cell><cell>[^\s]</cell></row><row><cell>\i</cell><cell>the set of initial name characters, those ·match·ed by Letter | '_' | ':'</cell></row><row><cell>\I</cell><cell>[^\i]</cell></row><row><cell>\c</cell><cell>the set of name characters, those ·match·ed by NameChar</cell></row><row><cell>\C</cell><cell>[^\c]</cell></row><row><cell>\d</cell><cell>\p{Nd}</cell></row><row><cell>\D</cell><cell>[^\d]</cell></row><row><cell>\w</cell><cell>[#x0000-#x10FFFF]-[\p{P}\p{Z}\p{C}] (all characters except the set of "punctuation", "separator" and "other" characters)</cell></row><row><cell>\W</cell><cell>[^\w]</cell></row><row><cell>Character sequence</cell><cell>Equivalent ·character class·</cell></row></table></node><node name="Glossary" prog_lang="custom-colors" readonly="False" tags="" unique_id="60"><rich_text>
</rich_text><rich_text scale="h2">Glossary (non-normative)</rich_text><rich_text>
The listing below is for the benefit of readers of a printed version of this document: it collects together all the definitions which appear in the document above.
</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">atomic</rich_text><rich_text weight="heavy">Atomic</rich_text><rich_text> datatypes are those having values which are regarded by this specification as being indivisible.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">base type</rich_text><rich_text>Every datatype that is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> by </rich_text><rich_text weight="heavy">restriction</rich_text><rich_text> is defined in terms of an existing datatype, referred to as its </rich_text><rich_text weight="heavy">base type</rich_text><rich_text>. </rich_text><rich_text weight="heavy">base type</rich_text><rich_text>s can be either </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-primitive">·primitive·</rich_text><rich_text>or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-bounded">bounded</rich_text><rich_text>A datatype is </rich_text><rich_text weight="heavy">bounded</rich_text><rich_text> if its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> has either an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-inclusive-upper-bound">·inclusive upper bound·</rich_text><rich_text> or an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-exclusive-upper-bound">·exclusive upper bound·</rich_text><rich_text> and either an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-inclusive-lower-bound">·inclusive lower bound·</rich_text><rich_text> or an</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-exclusive-lower-bound">·exclusive lower bound·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">built-in</rich_text><rich_text weight="heavy">Built-in</rich_text><rich_text> datatypes are those which are defined in this specification, and can be either </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-primitive">·primitive·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text>;</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-canonical-representation">canonical lexical representation</rich_text><rich_text>A </rich_text><rich_text weight="heavy">canonical lexical representation</rich_text><rich_text> is a set of literals from among the valid set of literals for a datatype such that there is a one-to-one mapping between literals in the </rich_text><rich_text weight="heavy">canonical lexical representation</rich_text><rich_text> and values in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cardinality">cardinality</rich_text><rich_text>Every </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> has associated with it the concept of </rich_text><rich_text weight="heavy">cardinality</rich_text><rich_text>. Some </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>s are finite, some are countably infinite while still others could conceivably be uncountably infinite (although no </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> defined by this specification is uncountable infinite). A datatype is said to have the cardinality of its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-comparable">comparable</rich_text><rich_text>otherwise they are </rich_text><rich_text weight="heavy">comparable</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-interchange">conformance to the XML Representation of Schemas</rich_text><rich_text>Processors which accept schemas in the form of XML documents as described in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#xr-defn">XML Representation of Simple Type Definition Schema Components (§4.1.2)</rich_text><rich_text> (and other relevant portions of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#datatype-components">Datatype components (§4)</rich_text><rich_text>) are additionally said to provide </rich_text><rich_text weight="heavy">conformance to the XML Representation of Schemas</rich_text><rich_text>, and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">·must·</rich_text><rich_text>, when processing schema documents, completely and correctly implement all </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-src">·Schema Representation Constraint·</rich_text><rich_text>s in this specification, and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">·must·</rich_text><rich_text> adhere exactly to the specifications in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#xr-defn">XML Representation of Simple Type Definition Schema Components (§4.1.2)</rich_text><rich_text> (and other relevant portions of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#datatype-components">Datatype components (§4)</rich_text><rich_text>) for mapping the contents of such documents to </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#key-component">schema components</rich_text><rich_text> for use in validation.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">constraining facet</rich_text><rich_text>A </rich_text><rich_text weight="heavy">constraining facet</rich_text><rich_text> is an optional property that can be applied to a datatype to constrain its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cos">Constraint on Schemas</rich_text><rich_text weight="heavy">Constraint on Schemas</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-datatype">datatype</rich_text><rich_text>In this specification, a </rich_text><rich_text weight="heavy">datatype</rich_text><rich_text> is a 3-tuple, consisting of a) a set of distinct values, called its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>, b) a set of lexical representations, called its</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text>, and c) a set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-facet">·facet·</rich_text><rich_text>s that characterize properties of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>, individual values or lexical items.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">derived</rich_text><rich_text weight="heavy">Derived</rich_text><rich_text> datatypes are those that are defined in terms of other datatypes.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-error">error</rich_text><rich_text weight="heavy">error</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-exclusive-lower-bound">exclusive lower bound</rich_text><rich_text>A value l in an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ordered">·ordered·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> L is said to be an </rich_text><rich_text weight="heavy">exclusive lower bound</rich_text><rich_text> of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> V (where V is a subset of L) if for all v in V, l < v.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-exclusive-upper-bound">exclusive upper bound</rich_text><rich_text>A value u in an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ordered">·ordered·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> U is said to be an </rich_text><rich_text weight="heavy">exclusive upper bound</rich_text><rich_text> of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> V (where V is a subset of U) if for all v in V, u > v.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-facet">facet</rich_text><rich_text>A </rich_text><rich_text weight="heavy">facet</rich_text><rich_text> is a single defining aspect of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>. Generally speaking, each facet characterizes a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> along independent axes or dimensions.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-compatibility">for compatibility</rich_text><rich_text>for compatibility</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-fundamental-facet">fundamental facet</rich_text><rich_text>A </rich_text><rich_text weight="heavy">fundamental facet</rich_text><rich_text> is an abstract property which serves to semantically characterize the values in a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-inclusive-lower-bound">inclusive lower bound</rich_text><rich_text>A value l in an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ordered">·ordered·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> L is said to be an </rich_text><rich_text weight="heavy">inclusive lower bound</rich_text><rich_text> of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> V (where V is a subset of L) if for all v in V, l <= v.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-inclusive-upper-bound">inclusive upper bound</rich_text><rich_text>A value u in an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ordered">·ordered·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> U is said to be an </rich_text><rich_text weight="heavy">inclusive upper bound</rich_text><rich_text> of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> V (where V is a subset of U) if for all v in V, u >= v.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-incomparable">incomparable</rich_text><rich_text>When a <> b, a and b are </rich_text><rich_text weight="heavy">incomparable</rich_text><rich_text>,</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">itemType</rich_text><rich_text>The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype that participates in the definition of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> datatype is known as the </rich_text><rich_text weight="heavy">itemType</rich_text><rich_text> of that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">·list·</rich_text><rich_text> datatype.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">lexical space</rich_text><rich_text>A </rich_text><rich_text weight="heavy">lexical space</rich_text><rich_text> is the set of valid literals for a datatype.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-list">list</rich_text><rich_text weight="heavy">List</rich_text><rich_text> datatypes are those having values each of which consists of a finite-length (possibly empty) sequence of values of an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-atomic">·atomic·</rich_text><rich_text> datatype.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">match</rich_text><rich_text weight="heavy">match</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-may">may</rich_text><rich_text weight="heavy">may</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-memberTypes">memberTypes</rich_text><rich_text>The datatypes that participate in the definition of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype are known as the </rich_text><rich_text weight="heavy">memberTypes</rich_text><rich_text> of that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">·union·</rich_text><rich_text> datatype.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minimally-conforming">minimally conforming</rich_text><rich_text weight="heavy">Minimally conforming</rich_text><rich_text> processors </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">·must·</rich_text><rich_text> completely and correctly implement the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cos">·Constraint on Schemas·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cvc">·Validation Rule·</rich_text><rich_text> .</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-must">must</rich_text><rich_text weight="heavy">must</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-non-numeric">non-numeric</rich_text><rich_text>A datatype whose values are not </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-numeric">·numeric·</rich_text><rich_text> is said to be </rich_text><rich_text weight="heavy">non-numeric</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-numeric">numeric</rich_text><rich_text>A datatype is said to be </rich_text><rich_text weight="heavy">numeric</rich_text><rich_text> if its values are conceptually quantities (in some mathematical number system).</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-order-relation">order-relation</rich_text><rich_text>An </rich_text><rich_text weight="heavy">order relation</rich_text><rich_text> on a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> is a mathematical relation that imposes a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-total-order">·total order·</rich_text><rich_text> or a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-partial-order">·partial order·</rich_text><rich_text> on the members of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ordered">ordered</rich_text><rich_text>A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>, and hence a datatype, is said to be </rich_text><rich_text weight="heavy">ordered</rich_text><rich_text> if there exists an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-order-relation">·order-relation·</rich_text><rich_text> defined for that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-partial-order">partial order</rich_text><rich_text>A </rich_text><rich_text weight="heavy">partial order</rich_text><rich_text> is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-order-relation">·order-relation·</rich_text><rich_text> that is </rich_text><rich_text weight="heavy">irreflexive</rich_text><rich_text>, </rich_text><rich_text weight="heavy">asymmetric</rich_text><rich_text> and </rich_text><rich_text weight="heavy">transitive</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-primitive">primitive</rich_text><rich_text weight="heavy">Primitive</rich_text><rich_text> datatypes are those that are not defined in terms of other datatypes; they exist ab initio.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-regex">regular expression</rich_text><rich_text>A </rich_text><rich_text weight="heavy">regular expression</rich_text><rich_text> is composed from zero or more </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-branch">·branch·</rich_text><rich_text>es, separated by | characters.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-restriction">restriction</rich_text><rich_text>A datatype is said to be </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> by </rich_text><rich_text weight="heavy">restriction</rich_text><rich_text> from another datatype when values for zero or more </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facet·</rich_text><rich_text>s are specified that serve to constrain its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> and/or its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> to a subset of those of its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text>.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-src">Schema Representation Constraint</rich_text><rich_text weight="heavy">Schema Representation Constraint</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-total-order">total order</rich_text><rich_text>A </rich_text><rich_text weight="heavy">total order</rich_text><rich_text> is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-partial-order">·partial order·</rich_text><rich_text> such that for no a and b is it the case that a <> b.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-union">union</rich_text><rich_text weight="heavy">Union</rich_text><rich_text> datatypes are those whose </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>s and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text>s are the union of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>s and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text>s of one or more other datatypes.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-user-derived">user-derived</rich_text><rich_text weight="heavy">User-derived</rich_text><rich_text> datatypes are those </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> datatypes that are defined by individual schema designers.</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-cvc">Validation Rule</rich_text><rich_text weight="heavy">Validation Rule</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">value space</rich_text><rich_text>A </rich_text><rich_text weight="heavy">value space</rich_text><rich_text> is the set of values for a given datatype. Each value in the </rich_text><rich_text weight="heavy">value space</rich_text><rich_text> of a datatype is denoted by one or more literals in its </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text>.</rich_text></node></node><node name="Case Study: Python" prog_lang="custom-colors" readonly="False" tags="" unique_id="23"><rich_text>My language is going to be a verbal high-level language with emphasis on simplicity and readability. I think many concepts of Python philosophy match my guidelines, so I decided to examine Python as a case study before I start working.
Also, it will open my mind to new worlds, since the serious languages I ever used are assembly, C, C++ and Java, and I know some basics of HTML, CSS, VB, Vala and C#
And there more, I already decided I want to learn Python as my high-level application programming language. It would probably speed up the development process. Low-level tools and algorithms will still use be written in C++ though.
So let's examine Python:
• </rich_text><rich_text link="node 28">Some Basics</rich_text><rich_text>
• </rich_text><rich_text link="node 24">Container Syntax</rich_text><rich_text>
• </rich_text><rich_text link="node 25">Operators</rich_text><rich_text>
• </rich_text><rich_text link="node 26">Functional Programming</rich_text><rich_text>
• </rich_text><rich_text link="node 27">Objects</rich_text><rich_text>
• </rich_text><rich_text link="node 29">Comments, docstrings and Annotations</rich_text><rich_text>
• </rich_text><rich_text link="node 30">Decorators</rich_text><node name="From Wikipedia" prog_lang="custom-colors" readonly="False" tags="" unique_id="64"><rich_text></rich_text><node name="Some Basics" prog_lang="custom-colors" readonly="False" tags="" unique_id="28"><rich_text>Python has a broad range of basic types, and I'd like to be aware of its unique types and take them into account when planning my datatypes. According to Wikipedia, Python has some unique types, such as:
• arbitrary-precision arithmetic
• complex numbers
• decimal floating point numbers
Ordered sequential types are:
• lists
• tuples
• strings
Strings are immutable sequences of characters. Tuples are immutable too, while lists are mutable and items may be inserted and removed. Tuples and lists can contain any type of item, including multiple types in the same sequence.
Unordered collections are:
• sets
• dictionaries
Dictionaries are like a mathematical function: they contain pairs of keys and values. Sets are unordered containers which don't allow duplicates, and implement set operations such as:
• union
• intersection
• difference
• symmetric difference
• subset testing
Python also provides extensive collection manipulating abilities such as built in containment checking and a generic iteration protocol.
Python has arbitrary-length integers and automatically increases the storage size as necessary.
Python supports normal floating point numbers, which are created when a dot is used in a literal (e.g. 1.1), when an integer and a floating point number are used in an expression, or as a result of some mathematical operations ("true division" via the / operator, or exponentiation with a negative exponent).
Python also supports complex numbers natively. Complex numbers are indicated with the J or j suffix, e.g. 3 + 4j.
</rich_text><rich_text weight="heavy">Easter Eggs</rich_text><rich_text>:
Users of curly bracket programming languages, such as C or Java, sometimes expect or wish Python to follow a block-delimiter convention. Brace-delimited block syntax has been repeatedly requested, and consistently rejected by core developers. The Python interpreter contains an easter egg that summarizes its developers' feelings on this issue. The code from __future__ import braces raises the exception SyntaxError: not a chance. The __future__ module is normally used to provide features from future versions of Python.
Another hidden message, The Zen of Python (a summary of Python philosophy), is displayed when trying to import this.
The message Hello world! is printed when the import statement import __hello__ is used. In Python 2.7, instead of Hello world! it prints Hello world....
An antigravity module was added to Python 2.7 and 3.0. Importing it opens a web browser to an xkcd comic that portrays a humorous fictional use for such a module, intended to demonstrate the ease with which Python modules enable additional functionality.</rich_text></node><node name="Container Syntax" prog_lang="custom-colors" readonly="False" tags="" unique_id="24"><rich_text>(From Wikipedia: </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/Python_syntax_and_semantics">http://en.wikipedia.org/wiki/Python_syntax_and_semantics</rich_text><rich_text>)
Python has syntactic support for the creation of container types.
</rich_text><rich_text weight="heavy">Lists</rich_text><rich_text> (class list) are mutable sequences of items of arbitrary types, and can be created either with the special
syntax
</rich_text><rich_text justification="left"></rich_text><rich_text>
or using normal object creation
</rich_text><rich_text justification="left"></rich_text><rich_text>
Tuples (class tuple) are immutable sequences of items of arbitrary types. There is also a special syntax to create tuples
</rich_text><rich_text justification="left"></rich_text><rich_text>
Although tuples are created by separating items with commas, the whole construct is usually wrapped in parentheses to increase readability. An empty tuple is denoted by ().
Sets (class set) are mutable containers of items of arbitrary types. The items are not ordered, but sets support iteration over the items. A syntax for set creation appeared in Python 2.7/3.0
</rich_text><rich_text justification="left"></rich_text><rich_text>
In earlier Python versions, sets would be created by calling initializing the set class with a list argument. Python sets are very much like mathematical sets, and support operations like set intersection and union.
Python also features a frozenset class for immutable sets.
Dictionaries (class dict) are mutable mappings tying keys and corresponding values. Python has special syntax to create dictionaries ({key: value})
</rich_text><rich_text justification="left"></rich_text><rich_text>
The dictionary syntax is similar to the set syntax, the difference is the presence of colons. The empty literal {} results in an empty dictionary rather than an empty set, which is instead created using the non-literal constructor: set().</rich_text><codebox char_offset="264" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">a_list = [1, 2, 3, "a dog"]</codebox><codebox char_offset="300" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">a_second_list = list()
a_second_list.append(4)
a_second_list.append(5)</codebox><codebox char_offset="426" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">a_tuple = 1, 2, 3, "four"</codebox><codebox char_offset="796" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">some_set = {0, (), False}</codebox><codebox char_offset="1225" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">a_dictionary = {"key 1":"value 1", 2:3, 4:[]}</codebox></node><node name="Operators" prog_lang="custom-colors" readonly="False" tags="" unique_id="25"><rich_text justification="left"></rich_text><rich_text scale="h3">Arithmetic</rich_text><rich_text>
Python includes the +, -, *, /, % (modulus), and ** (exponentiation) operators, with their usual mathematical precedence.
Traditionally, x / y performed integer division if both x and y were integers (returning the floor of the quotient), and returned a float if either was a float. However, because Python is a dynamically-typed language, it was not always possible to tell which operation was being performed, which often led to subtle bugs.
To avoid this issue, a proposal was made to change the behavior of the Python division operator. In Python 2.2, a new operator // was introduced for floor division, both for integer and floating-point arguments. The / operator was changed so that the quotient of two integers returned a float, but for backwards compatibility, this behavior had to be explicitly requested until Python 3.0.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Comparison</rich_text><rich_text>
The basic comparison operators such as ==, <, >=, and so forth are used on all manner of values.
Chained comparison expressions such as a < b < c have roughly the meaning that they have in mathematics, rather than the unusual meaning found in C and similar languages. The terms are evaluated and compared in order.
The operation has short-circuit semantics, meaning that evaluation is guaranteed to stop as soon as a verdict is clear: if a < b is false, c is never evaluated as the expression cannot possibly be true anymore.
For expressions without side effects, a < b < c is equivalent to a < b and b < c. However, there is a substantial difference when the expressions have side effects. a < f(x) < bwill evaluate f(x) exactly once, whereas a < f(x) and f(x) < b will evaluate it twice if the value of a is less than f(x) and once otherwise.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Logical</rich_text><rich_text>
Python 2.2 and earlier does not have an explicit boolean type. In all versions of Python, boolean operators treat zero values or empty values such as "", 0, None, 0.0, [], and {}as false, while in general treating non-empty, non-zero values as true.
In Python 2.2.1 the boolean constants True and False were added to the language (subclassed from 1 and 0). The binary comparison operators such as == and > return either True or False.
The boolean operators and and or use minimal evaluation. For example, y == 0 or x/y > 100 will never raise a divide-by-zero exception. Note that these operators return the value of the last operand evaluated, rather than True or False. Thus the expression (4 and 5) evaluates to 5, and (4 or 5) evaluates to 4.</rich_text><encoded_png anchor="h3-1" char_offset="0">anchor</encoded_png><encoded_png anchor="h3-2" char_offset="850">anchor</encoded_png><encoded_png anchor="h3-3" char_offset="1712">anchor</encoded_png></node><node name="Functional Programming" prog_lang="custom-colors" readonly="False" tags="" unique_id="26"><rich_text>I haven't studied this topic in detail, but here are some interesting examples from Wikipedia.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">List Comprehension</rich_text><rich_text>
A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical set-builder notation (set comprehension) as distinct from the use of map and filter functions.
I'd paste the whole Wikipedia article here, but instead of manually changing the style and code boxes, I'll just refer you to the article itself: </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/List_comprehension">http://en.wikipedia.org/wiki/List_comprehension</rich_text><rich_text>.
Here's an example for Python:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Generator Expressions</rich_text><rich_text>
Introduced in Python 2.4, generator expressions are the lazy evaluation equivalent of list comprehensions. Using the prime number generator provided in the above section, we might define a lazy, but not quite infinite collection.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Most of the memory and time needed to generate this many primes will not be used until the needed element is actually accessed. Unfortunately, you cannot perform simple indexing and slicing of generators, but must use the itertools modules or "roll your own" loops. In contrast, a list comprehension is functionally equivalent, but is greedy in performing all the work:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The list comprehension will immediately create a large list (with 78498 items, in the example, but transiently creating a list of primes under two million), even if most elements are never accessed. The generator comprehension is more parsimonious.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Dictionary and set comprehensions</rich_text><rich_text>
While lists and generators had comprehensions/expressions, in Python versions older than 2.7 the other Python built-in collection types (dicts and sets) had to be kludged in using lists or generators:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Python 2.7 and 3.0 unify all collection types by introducing dict and set comprehensions, similar to list comprehensions:
</rich_text><rich_text justification="left"></rich_text><encoded_png anchor="h3-1" char_offset="96">anchor</encoded_png><codebox char_offset="611" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">powers_of_two = [2**n for n in range(1, 6)]</codebox><encoded_png anchor="h3-2" char_offset="614">anchor</encoded_png><codebox char_offset="869" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">from itertools import islice
primes_under_million = (i for i in generate_primes() if i < 1000000)
two_thousandth_prime = islice(primes_under_million, 1999, 2000).next()</codebox><codebox char_offset="1243" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">primes_under_million = [i for i in generate_primes(2000000) if i < 1000000]
two_thousandth_prime = primes_under_million[1999]</codebox><encoded_png anchor="h3-3" char_offset="1496">anchor</encoded_png><codebox char_offset="1734" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">>>> dict((n, n*n) for n in range(5))
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}</codebox><codebox char_offset="1860" frame_height="154" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">>>> [ n*n for n in range(5) ] # regular list comprehension
[0, 1, 4, 9, 16]
>>>
>>> { n*n for n in range(5) } # set comprehension
{0, 1, 4, 16, 9}
>>>
>>> { n: n*n for n in range(5) } # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}</codebox></node><node name="Objects" prog_lang="custom-colors" readonly="False" tags="" unique_id="27"><rich_text>Python supports most object oriented programming techniques. It allows polymorphism, not only within a class hierarchy but also by duck typing. Any object can be used for any type, and it will work so long as it has the proper methods and attributes. And everything in Python is an object, including classes, functions, numbers and modules.
Python also has support for metaclasses, an advanced tool for enhancing classes' functionality.
Naturally, inheritance, including multiple inheritance, is supported. It has limited support for private variables using name mangling. See the "Classes" section of the tutorial for details.
Many Python users don't feel the need for private variables, though. The slogan "We're all consenting adults here" is used to describe this attitude. Some consider information hiding to be unpythonic, in that it suggests that the class in question contains unaesthetic or ill-planned internals. However, the strongest argument for name mangling is prevention of unpredictable breakage of programs: introducing a new public variable in a superclass can break subclasses if they don't use "private" variables.
From the tutorial: </rich_text><rich_text style="italic">As is true for modules, classes in Python do not put an absolute barrier between definition and user, but rather rely on the politeness of the user not to "break into the definition."</rich_text><rich_text>
OOP doctrines such as the use of accessor methods to read data members are not enforced in Python. Just as Python offers functional-programming constructs but does not attempt to demand referential transparency, it offers an object system but does not demand OOP behavior.
Moreover, it is always possible to redefine the class using </rich_text><rich_text weight="heavy">properties</rich_text><rich_text> so that when a certain variable is set or retrieved in calling code, it really invokes a function call, so that </rich_text><rich_text weight="heavy">spam.eggs = toast</rich_text><rich_text> might really invoke </rich_text><rich_text weight="heavy">spam.set_eggs(toast)</rich_text><rich_text>. This nullifies the practical advantage of accessor functions, and it remains OOP because the property eggs becomes a legitimate part of the object's interface: it need not reflect an implementation detail.
In version 2.2 of Python, "new-style" classes were introduced. With new-style classes, objects and types were unified, allowing the subclassing of types. Even entirely new types can be defined, complete with custom behavior for infix operators. This allows for many radical things to be done syntactically within Python. A new method resolution order formultiple inheritance was also adopted with Python 2.3. It is also possible to run custom code while accessing or setting attributes, though the details of those techniques have evolved between Python versions.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">With Statements</rich_text><rich_text>
The "with" statement handles resources. One function is called when entering scope and another when leaving. This prevents forgetting to remove the resource and also handles more complicated situations such as exceptions.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Properties</rich_text><rich_text>
Properties allow specially defined methods to be invoked on an object instance by using the same syntax as used for attribute access. An example of a class defining some properties is:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Descriptors</rich_text><rich_text>
A class that defines one or more of the special methods __get__(self,instance,owner), __set__(self,instance,value), __delete__(self,instance) can be used as a descriptor. Creating an instance of a descriptor as a class member of a second class makes the instance a property of the second class.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Class and Static Methods</rich_text><rich_text>
Python allows the creation of class methods and static method via the use of the @classmethod and @staticmethod decorators. The first argument to a class method is the class object instead of the self reference to the instance. A static method has no special first argument. Neither the instance, nor the class object is passed to a static method.</rich_text><encoded_png anchor="h3-1" char_offset="2634">anchor</encoded_png><encoded_png anchor="h3-2" char_offset="2875">anchor</encoded_png><codebox char_offset="3074" frame_height="276" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">class MyClass(object):
def get_a(self):
return self._a
def set_a(self, value):
self._a = value - 1
a = property(get_a, set_a, doc="Off by one a")
# Python 2.6 style
class MyClass(object):
@property
def a(self):
return self._a
@a.setter # makes the property writable
def a(self, value):
self._a = value - 1</codebox><encoded_png anchor="h3-3" char_offset="3077">anchor</encoded_png><encoded_png anchor="h3-4" char_offset="3387">anchor</encoded_png></node><node name="Comments, docstring and Annotations" prog_lang="custom-colors" readonly="False" tags="" unique_id="29"><rich_text scale="h3">Comments and docstrings</rich_text><rich_text>
Python has two ways to annotate Python code. One is by using comments to indicate what some part of the code does. Single-line comments begin with the hash character ("#") and are terminated by the end of line. Comments spanning more than one line are achieved by inserting a multi-line string (with """ as the delimiter one each end) that is not used in assignment or otherwise evaluated, but sits in between other statements.
Commenting a piece of code:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Commenting a piece of code with multiple lines:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Docstrings (documentation string), that is, strings that is located alone without assignment as the first indented line within a module, class, method or function automatically set their contents as an attribute named __doc__, which is intended to store a human-readable description of the object's purpose, behavior, and usage. The built-in help function generates its output based on __doc__ attributes. Such strings can be delimited with " or ' for single line strings, or may span multiple lines if delimited with either """ or ''' which is Python's notation for specifying multi-line strings. However, the style guide for the language specifies that triple double quotes (""") are preferred for both single and multi-line docstrings.
Single line docstring:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Multi-line docstring:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Docstrings can be as large as the programmer wants and contain line breaks. In contrast with comments, docstrings are themselves Python objects and are part of the interpreted code that Python runs. That means that a running program can retrieve its own docstrings and manipulate that information. But the normal usage is to give other programmers information about how to invoke the object being documented in the docstring.
There are tools available that can extract the docstrings to generate an API documentation from the code. Docstring documentation can also be accessed from the interpreter with the help() function, or from the shell with the pydoc command </rich_text><rich_text style="italic">pydoc</rich_text><rich_text>.
The </rich_text><rich_text style="italic">doctest</rich_text><rich_text> standard module uses interactions copied from Python shell sessions into docstrings, to create tests.
</rich_text><rich_text scale="h3">Function Annotations</rich_text><rich_text>
Function annotations are defined in </rich_text><rich_text link="webs http://www.python.org/dev/peps/pep-3107/">PEP 3107</rich_text><rich_text>. They allow attaching data to the arguments and return of a function. The behaviour of annotations is not defined by the language - and left to third party frameworks. For example, a library could be written to handle static typing:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="483" frame_height="44" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def getline():
return sys.stdin.readline() # Get one line and return it</codebox><codebox char_offset="535" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def getline():
return sys.stdin.readline() """this function
gets one line
and returns it""" </codebox><codebox char_offset="1302" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def getline():
"""Get one line from stdin and return it."""
return sys.stdin.readline()</codebox><codebox char_offset="1328" frame_height="100" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def getline():
"""Get one line
from stdin
and return it."""
return sys.stdin.readline()</codebox><codebox char_offset="2425" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def haul(item: Haulable, *vargs: PackAnimal) -> Distance</codebox></node><node name="Decorators" prog_lang="custom-colors" readonly="False" tags="" unique_id="30"><rich_text>A decorator is any callable Python object that is used to modify a function, method or class definition. A decorator is passed the original object being defined and returns a modified object, which is then bound to the name in the definition. Python decorators were inspired in part by Java annotations, and have a similar syntax; the decorator syntax is pure syntactic sugar, using @ as the keyword:
</rich_text><rich_text justification="left"></rich_text><rich_text>
is equivalent to
</rich_text><rich_text justification="left"></rich_text><rich_text>
Decorators are a form of metaprogramming; they enhance the action of the function or method they decorate. For example, in the above sample, viking_chorus might causemenu_item to be run 8 times (see Spam sketch) for each time it is called:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Canonical uses of function decorators are for creating class methods or static methods, adding function attributes, tracing, setting pre- and postconditions, andsynchronisation,[14] but can be used for far more besides, including tail recursion elimination, memoization and even improving the writing of decorators.
Decorators can be chained by placing several on adjacent lines:
</rich_text><rich_text justification="left"></rich_text><rich_text>
is equivalent to
</rich_text><rich_text justification="left"></rich_text><rich_text>
or, using intermediate variables
</rich_text><rich_text justification="left"></rich_text><rich_text>
In the above example, the favorite_color decorator factory takes an argument. Decorator factories must return a decorator, which is then called with the object to be decorated as its argument:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This would then decorate the black_knight function such that the color, "Blue", would be printed prior to the black_knight function running.
In Python prior to version 2.6, decorators apply to functions and methods, but not to classes. Decorating a (dummy) __new__ method can modify a class, however. Class decorators are supported starting with Python 2.6.
Despite the name, Python decorators are not an implementation of the decorator pattern. The decorator pattern is a design pattern used in statically typed object-oriented programming languages to allow functionality to be added to objects at run time; Python decorators add functionality to functions and methods at definition time, and thus are a higher-level construct than decorator-pattern classes. The decorator pattern itself is trivially implementable in Python, because the language is duck typed, and so is not usually considered as such.</rich_text><codebox char_offset="402" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">@viking_chorus
def menu_item():
print("spam")</codebox><codebox char_offset="427" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)</codebox><codebox char_offset="671" frame_height="100" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def viking_chorus(myfunc):
def inner_func(*args, **kwargs):
for i in range(8):
myfunc(*args, **kwargs)
return inner_func</codebox><codebox char_offset="1060" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">@invincible
@favorite_color("Blue")
def black_knight():
pass</codebox><codebox char_offset="1081" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def black_knight():
pass
black_knight = invincible(favorite_color("Blue")(black_knight))</codebox><codebox char_offset="1118" frame_height="100" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def black_knight():
pass
blue_decorator = favorite_color("Blue")
decorated_by_blue = blue_decorator(black_knight)
black_knight = invincible(decorated_by_blue)</codebox><codebox char_offset="1315" frame_height="140" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">def favorite_color(color):
def decorator(func):
def wrapper():
print(color)
func()
return wrapper
return decorator</codebox></node></node><node name="From Tutorial" prog_lang="custom-colors" readonly="False" tags="" unique_id="65"><rich_text>I'm using the Python 3 tutorial from python.org: </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/">http://docs.python.org/3/tutorial/</rich_text><rich_text>.</rich_text><node name="Arithmetic Operators" prog_lang="custom-colors" readonly="False" tags="" unique_id="66"><rich_text>Python has the familiar +, -, *, / also used in many other languages, but I'd like to mention some special things it has:
• The / operator does real division and returns a float, even if two integers are divided, e.i. 8/5 returns 1.66666
• The // operator is a "floor division" operator, and does what C and C++ do when dividing integers: 8/5 = 1
• For float numbers, // does floor division but returns a float, e.g. 9 // 4.2 = 2.0
• The ** operator is a power operator, which doesn't exist in C/C++ (a math library function is needed for that)
• For example, 3 ** 4 = 81
• The % operator (division remainder, aka modulo) works with both ints and floats
Since ** has higher precedence than -, -3**2 will be interpreted as -(3**2) and thus result in -9. To avoid this and get 9, you can use (-3)**2.</rich_text></node><node name="Strings" prog_lang="custom-colors" readonly="False" tags="" unique_id="67"><rich_text>Strings in Python may be enclosed in single quotes or double quotes. Escaping quotes inside strings can be done with a backslash or by using double quotes for a string containing a single quote character and vice versa (of course it's impossible if a string contains both a double and a single quote, in which case escaping must be used anyway).
</rich_text><rich_text justification="left"></rich_text><rich_text>
There's also the common \n escape sequence, which means </rich_text><rich_text style="italic">newline</rich_text><rich_text>.
The print() function prints a readable form of strings, e.g. it omits the enclosing quotes and translates escape characters into their actual meaning. For example, \n would translate into an actual line break:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Raw strings also exist. If you prepend </rich_text><rich_text style="italic">r</rich_text><rich_text> before the first quote, the string is considered a raw string and escape sequences like \n are treated like normal characters, e.g. r"\n" means \n while "\n" means </rich_text><rich_text style="italic">newline</rich_text><rich_text>.
Multi-line strings can be defined by enclosing them with triple quotes, either ''' or """. Line endings are included in the string, unless the line ends with \.
Strings can be concatenated with the + operator, and repeated with the * operator by "multiplying" by an integer. For example, </rich_text><rich_text style="italic">3 * "repeat-"</rich_text><rich_text> will result in the string </rich_text><rich_text style="italic">"repeat-repeat-repeat-"</rich_text><rich_text>.
Strings literals (only literals, not variables or expressions) can be concatenated simply by being next to each other. C++ has this behavior too. For example, </rich_text><rich_text style="italic">"hello" 'world'</rich_text><rich_text> will result in the string </rich_text><rich_text style="italic">"helloworld"</rich_text><rich_text>. This feature is particularly useful when you want to break long strings:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Strings can be subscripted. Using an index inside [] gives a character, starting from index 0. There's no character type, thus characters are just strings of length 1. Negative numbers can be used too, if you want to start counting from the right. -1 refers to the last character in the string, -2 refers to the one before it, etc. For example, after defining x</rich_text><rich_text style="italic"> = "world"</rich_text><rich_text>, x[2] is "r" and x[-2] is "l".
Substrings can be used by the slicing syntax. This is only possible in C, C++ and Java using a library function. Slicing is done by specifying two indices inside the [], with the first index included and the other excluded, i.e. x[a:b] denotes the substring of x with the first character being x[a] and the last one being x[b-1]. It's also possible to omit one of indices. x[a:] means "from a to the end" and x[:b] means "from the beginning to b-1". In other words, the first index defaults to 0 and the second defauls to the string length. Negative indices can be used to for pointing to characters.
Strings in Python are immutable, thus their characters cannot be changed after definition.
The built-in function </rich_text><rich_text style="italic">len()</rich_text><rich_text> returns the size of a string.
Unlike other languages, special characters such as \n have the same meaning with both single ('...') and double ("...") quotes. The only difference between the two is that within single quotes you don’t need to escape " (but you have to escape \') and vice versa.</rich_text><codebox char_offset="347" frame_height="225" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> 'spam eggs' # single quotes
'spam eggs'
>>> 'doesn\'t' # use \' to escape the single quote...
"doesn't"
>>> "doesn't" # ...or use double quotes instead
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'</codebox><codebox char_offset="627" frame_height="190" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'
>>> print('"Isn\'t," she said.')
"Isn't," she said.
>>> s = 'First line.\nSecond line.' # \n means newline
>>> s # without print(), \n is included in the output
'First line.\nSecond line.'
>>> print(s) # with print(), \n produces a new line
First line.
Second line.</codebox><codebox char_offset="1489" frame_height="84" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> text = ('Put several strings within parentheses '
'to have them joined together.')
>>> text
'Put several strings within parentheses to have them joined together.'</codebox></node><node name="Lists" prog_lang="custom-colors" readonly="False" tags="" unique_id="68"><rich_text>Python knows a number of compound data types, used to group together other values. The most versatile is the list, which can be written as a list of comma-separated values (items) between square brackets. Lists might contain items of different types, but usually the items all have the same type.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Like strings (and all other built-in </rich_text><rich_text link="webs http://docs.python.org/3/glossary.html#term-sequence">sequence</rich_text><rich_text> type), lists can be indexed and sliced:
</rich_text><rich_text justification="left"></rich_text><rich_text>
All slice operations return a new list containing the requested elements. This means that the following slice returns a new (shallow) copy of the list:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Unlike strings, which are </rich_text><rich_text link="webs http://docs.python.org/3/glossary.html#term-immutable">immutable</rich_text><rich_text>, lists are a </rich_text><rich_text link="webs http://docs.python.org/3/glossary.html#term-mutable">mutable</rich_text><rich_text> type, i.e. it is possible to change their content:
</rich_text><rich_text justification="left"></rich_text><rich_text>
You can also add new items at the end of the list, by using the append() method (we will see more about methods later):
</rich_text><rich_text justification="left"></rich_text><rich_text>
Assignment to slices is also possible, and this can even change the size of the list or clear it entirely:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The built-in function </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#len">len()</rich_text><rich_text> also applies to lists:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is possible to nest lists (create lists containing other lists), for example:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="298" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> squares = [1, 2, 4, 9, 16, 25]
>>> squares
[1, 2, 4, 9, 16, 25]</codebox><codebox char_offset="388" frame_height="116" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> squares[0] # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:] # slicing returns a new list
[9, 16, 25]</codebox><codebox char_offset="544" frame_height="100" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> squares[:]
[1, 2, 4, 9, 16, 25]
Lists also supports operations like concatenation:
>>>>>> squares + [36, 49, 64, 81, 100]
[1, 2, 4, 9, 16, 25, 36, 49, 64, 81, 100]</codebox><codebox char_offset="656" frame_height="116" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]</codebox><codebox char_offset="780" frame_height="84" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> cubes.append(216) # add the cube of 6
>>> cubes.append(7 ** 3) # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]</codebox><codebox char_offset="891" frame_height="276" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]</codebox><codebox char_offset="946" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4</codebox><codebox char_offset="1031" frame_height="174" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'</codebox></node><node name="Simple Program Example" prog_lang="custom-colors" readonly="False" tags="" unique_id="69"><rich_text>Of course, we can use Python for more complicated tasks than adding two and two together. For instance, we can write an initial sub-sequence of the Fibonacci series as follows:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This example introduces several new features.
• The first line contains a multiple assignment: the variables a and b simultaneously get the new values 0 and 1. On the last line this is used again, demonstrating that the expressions on the right-hand side are all evaluated first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right.
• The </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#while">while</rich_text><rich_text> loop executes as long as the condition (here: b < 10) remains true. In Python, like in C, any non-zero integer value is true; zero is false. The condition may also be a string or list value, in fact any sequence; anything with a non-zero length is true, empty sequences are false. The test used in the example is a simple comparison. The standard comparison operators are written the same as in C: < (less than), > (greater than), == (equal to), <= (less than or equal to), >= (greater than or equal to) and != (not equal to).
• The body of the loop is indented: indentation is Python’s way of grouping statements. At the interactive prompt, you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; all decent text editors have an auto-indent facility. When a compound statement is entered interactively, it must be followed by a blank line to indicate completion (since the parser cannot guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount.
• The </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#print">print()</rich_text><rich_text> function writes the value of the argument(s) it is given. It differs from just writing the expression you want to write (as we did earlier in the calculator examples) in the way it handles multiple arguments, floating point quantities, and strings. Strings are printed without quotes, and a space is inserted between items, so you can format things nicely, like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The keyword argument end can be used to avoid the newline after the output, or end the output with a different string:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="178" frame_height="250" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
... print(b)
... a, b = b, a+b
...
1
1
2
3
5
8</codebox><codebox char_offset="2069" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> i = 256*256
>>> print('The value of i is', i)
The value of i is 65536</codebox><codebox char_offset="2192" frame_height="124" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> a, b = 0, 1
>>> while b < 1000:
... print(b, end=',')
... a, b = b, a+b
...
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,</codebox></node><node name="Control Flow" prog_lang="custom-colors" readonly="False" tags="" unique_id="70"><rich_text>I won't mention all features because some of them are not relevant to a data definition language. Actually, control flow in general is not relevant at all.
I mention here things which may be useful if adapted to data definitions, or just interesting features which can help me get new creative ideas.</rich_text><node name="For" prog_lang="custom-colors" readonly="False" tags="" unique_id="73"><rich_text>The </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):
</rich_text><rich_text justification="left"></rich_text><rich_text>
If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="435" frame_height="160" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12</codebox><codebox char_offset="720" frame_height="120" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']</codebox></node><node name="Range" prog_lang="custom-colors" readonly="False" tags="" unique_id="74"><rich_text>If you do need to iterate over a sequence of numbers, the built-in function </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#range">range()</rich_text><rich_text> comes in handy. It generates arithmetic progressions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The given end point is never part of the generated sequence; range(10) generates 10 values, the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the ‘step’):
</rich_text><rich_text justification="left"></rich_text><rich_text>
To iterate over the indices of a sequence, you can combine </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#range">range()</rich_text><rich_text> and </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#len">len()</rich_text><rich_text> as follows:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In most such cases, however, it is convenient to use the </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#enumerate">enumerate()</rich_text><rich_text> function, see </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/datastructures.html#tut-loopidioms">Looping Techniques</rich_text><rich_text>.
A strange thing happens if you just print a range:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In many ways the object returned by </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#range">range()</rich_text><rich_text> behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.
We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> statement is such an iterator. The function </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#list">list()</rich_text><rich_text> is another; it creates lists from iterables:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Later we will see more functions that return iterables and take iterables as argument.</rich_text><codebox char_offset="139" frame_height="160" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> for i in range(5):
... print(i)
...
0
1
2
3
4</codebox><codebox char_offset="438" frame_height="160" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">range(5, 10)
5 through 9
range(0, 10, 3)
0, 3, 6, 9
range(-10, -100, -30)
-10, -40, -70</codebox><codebox char_offset="531" frame_height="180" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb</codebox><codebox char_offset="689" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> print(range(10))
range(0, 10)</codebox><codebox char_offset="1257" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> list(range(5))
[0, 1, 2, 3, 4]</codebox></node><node name="Pass" prog_lang="custom-colors" readonly="False" tags="" unique_id="72"><rich_text>The </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#pass">pass</rich_text><rich_text> statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is commonly used for creating minimal classes:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Another place </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#pass">pass</rich_text><rich_text> can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#pass">pass</rich_text><rich_text> is silently ignored:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="141" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> while True:
... pass # Busy-wait for keyboard interrupt (Ctrl+C)
...</codebox><codebox char_offset="197" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> class MyEmptyClass:
... pass
...</codebox><codebox char_offset="408" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> def initlog(*args):
... pass # Remember to implement this!
...</codebox></node><node name="Functions" prog_lang="custom-colors" readonly="False" tags="" unique_id="71"><rich_text>We can create a function that writes the Fibonacci series to an arbitrary boundary:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The keyword </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#def">def</rich_text><rich_text> introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.
The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, ordocstring. (More about docstrings can be found in the section </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/controlflow.html#tut-docstrings">Documentation Strings</rich_text><rich_text>.) There are tools which use docstrings to automatically produce online or printed documentation, or to let the user interactively browse through code; it’s good practice to include docstrings in code that you write, so make a habit of it.
The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#global">global</rich_text><rich_text> statement), although they may be referenced.
The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/controlflow.html#id2">[1]</rich_text><rich_text> When a function calls another function, a new local symbol table is created for that call.
A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function. This serves as a general renaming mechanism:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Coming from other languages, you might object that fib is not a function but a procedure since it doesn’t return a value. In fact, even functions without a </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#return">return</rich_text><rich_text> statement do return a value, albeit a rather boring one. This value is called None (it’s a built-in name). Writing the value None is normally suppressed by the interpreter if it would be the only value written. You can see it if you really want to using </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#print">print()</rich_text><rich_text>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is simple to write a function that returns a list of the numbers of the Fibonacci series, instead of printing it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This example, as usual, demonstrates some new Python features:
• The </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#return">return</rich_text><rich_text> statement returns with a value from a function. </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#return">return</rich_text><rich_text> without an expression argument returns None. Falling off the end of a function also returns None.
• The statement result.append(a) calls a method of the list object result. A method is a function that ‘belongs’ to an object and is named obj.methodname, where obj is some object (this may be an expression), and methodname is the name of a method that is defined by the object’s type. Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using classes, see </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/classes.html#tut-classes">Classes</rich_text><rich_text>) The method append()shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to result =result + [a], but more efficient.</rich_text><codebox char_offset="85" frame_height="300" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> def fib(n): # write Fibonacci series up to n
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while a < n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597</codebox><codebox char_offset="2014" frame_height="120" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> fib
<function fib at 10042ed0>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89</codebox><codebox char_offset="2444" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> fib(0)
>>> print(fib(0))
None</codebox><codebox char_offset="2565" frame_height="260" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">>>> def fib2(n): # return Fibonacci series up to n
... """Return a list containing the Fibonacci series up to n."""
... result = []
... a, b = 0, 1
... while a < n:
... result.append(a) # see below
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]</codebox><node name="Keyword Arguments" prog_lang="custom-colors" readonly="False" tags="" unique_id="75"><rich_text>Functions can also be called using </rich_text><rich_text link="webs http://docs.python.org/3/glossary.html#term-keyword-argument">keyword arguments</rich_text><rich_text> of the form kwarg=value. For instance, the following function:
</rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">parrot</rich_text><rich_text>(voltage, state</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'a stiff'</rich_text><rich_text>, action</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'voom'</rich_text><rich_text>, </rich_text><rich_text foreground="#007020">type</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'Norwegian Blue'</rich_text><rich_text>):
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-- This parrot wouldn't"</rich_text><rich_text>, action, end</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">' '</rich_text><rich_text>)
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"if you put"</rich_text><rich_text>, voltage, </rich_text><rich_text foreground="#4070a0">"volts through it."</rich_text><rich_text>)
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-- Lovely plumage, the"</rich_text><rich_text>, </rich_text><rich_text foreground="#007020">type</rich_text><rich_text>)
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-- It's"</rich_text><rich_text>, state, </rich_text><rich_text foreground="#4070a0">"!"</rich_text><rich_text>)
accepts one required argument (voltage) and three optional arguments (state, action, and type). This function can be called in any of the following ways:
parrot(</rich_text><rich_text foreground="#208050">1000</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># 1 positional argument</rich_text><rich_text>
parrot(voltage</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">1000</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># 1 keyword argument</rich_text><rich_text>
parrot(voltage</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">1000000</rich_text><rich_text>, action</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'VOOOOOM'</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># 2 keyword arguments</rich_text><rich_text>
parrot(action</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'VOOOOOM'</rich_text><rich_text>, voltage</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">1000000</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># 2 keyword arguments</rich_text><rich_text>
parrot(</rich_text><rich_text foreground="#4070a0">'a million'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'bereft of life'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'jump'</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># 3 positional arguments</rich_text><rich_text>
parrot(</rich_text><rich_text foreground="#4070a0">'a thousand'</rich_text><rich_text>, state</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'pushing up the daisies'</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># 1 positional, 1 keyword</rich_text><rich_text>
but all the following calls would be invalid:
parrot() </rich_text><rich_text foreground="#408090"># required argument missing</rich_text><rich_text>
parrot(voltage</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">5.0</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'dead'</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># non-keyword argument after a keyword argument</rich_text><rich_text>
parrot(</rich_text><rich_text foreground="#208050">110</rich_text><rich_text>, voltage</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">220</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># duplicate value for the same argument</rich_text><rich_text>
parrot(actor</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'John Cleese'</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># unknown keyword argument</rich_text><rich_text>
In a function call, keyword arguments must follow positional arguments. All the keyword arguments passed must match one of the arguments accepted by the function (e.g. actor is not a valid argument for the parrot function), and their order is not important. This also includes non-optional arguments (e.g. parrot(voltage=1000) is valid too). No argument may receive a value more than once. Here’s an example that fails due to this restriction:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">function</rich_text><rich_text>(a):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">pass</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>function(</rich_text><rich_text foreground="#208050">0</rich_text><rich_text>, a</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">0</rich_text><rich_text>)
</rich_text><rich_text foreground="#0044dd">Traceback (most recent call last):</rich_text><rich_text>
File </rich_text><rich_text foreground="#007020">"<stdin>"</rich_text><rich_text>, line </rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, in ?
</rich_text><rich_text foreground="#ff0000">TypeError</rich_text><rich_text>: function() got multiple values for keyword argument 'a'
When a final formal parameter of the form **name is present, it receives a dictionary (see </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#typesmapping">Mapping Types — dict</rich_text><rich_text>) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form *name(described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*namemust occur before **name.) For example, if we define a function like this:
</rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">cheeseshop</rich_text><rich_text>(kind, </rich_text><rich_text foreground="#666666">*</rich_text><rich_text>arguments, </rich_text><rich_text foreground="#666666">**</rich_text><rich_text>keywords):
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-- Do you have any"</rich_text><rich_text>, kind, </rich_text><rich_text foreground="#4070a0">"?"</rich_text><rich_text>)
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-- I'm sorry, we're all out of"</rich_text><rich_text>, kind)
</rich_text><rich_text foreground="#007020">for</rich_text><rich_text> arg </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> arguments:
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(arg)
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-"</rich_text><rich_text> </rich_text><rich_text foreground="#666666">*</rich_text><rich_text> </rich_text><rich_text foreground="#208050">40</rich_text><rich_text>)
keys </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#007020">sorted</rich_text><rich_text>(keywords</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>keys())
</rich_text><rich_text foreground="#007020">for</rich_text><rich_text> kw </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> keys:
</rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(kw, </rich_text><rich_text foreground="#4070a0">":"</rich_text><rich_text>, keywords[kw])
It could be called like this:
cheeseshop(</rich_text><rich_text foreground="#4070a0">"Limburger"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"It's very runny, sir."</rich_text><rich_text>,
</rich_text><rich_text foreground="#4070a0">"It's really very, VERY runny, sir."</rich_text><rich_text>,
shopkeeper</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">"Michael Palin"</rich_text><rich_text>,
client</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">"John Cleese"</rich_text><rich_text>,
sketch</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">"Cheese Shop Sketch"</rich_text><rich_text>)
and of course it would print:
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop SketchNote that the list of keyword argument names is created by sorting the result of the keywords dictionary’s keys() method before printing its contents; if this is not done, the order in which the arguments are printed is undefined.
</rich_text></node><node name="Arbitrary Argument Lists" prog_lang="custom-colors" readonly="False" tags="" unique_id="76"><rich_text>Finally, the least frequently used option is to specify that a function can be called with an arbitrary number of arguments. These arguments will be wrapped up in a tuple (see </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/datastructures.html#tut-tuples">Tuples and Sequences</rich_text><rich_text>). Before the variable number of arguments, zero or more normal arguments may occur.
</rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">write_multiple_items</rich_text><rich_text>(file, separator, </rich_text><rich_text foreground="#666666">*</rich_text><rich_text>args):
file</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>write(separator</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>join(args))
Normally, these variadic arguments will be last in the list of formal parameters, because they scoop up all remaining input arguments that are passed to the function. Any formal parameters which occur after the *args parameter are ‘keyword-only’ arguments, meaning that they can only be used as keywords rather than positional arguments.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">concat</rich_text><rich_text>(</rich_text><rich_text foreground="#666666">*</rich_text><rich_text>args, sep</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">"/"</rich_text><rich_text>):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">return</rich_text><rich_text> sep</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>join(args)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>concat(</rich_text><rich_text foreground="#4070a0">"earth"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"mars"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"venus"</rich_text><rich_text>)
</rich_text><rich_text foreground="#333333">'earth/mars/venus'</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>concat(</rich_text><rich_text foreground="#4070a0">"earth"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"mars"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"venus"</rich_text><rich_text>, sep</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">"."</rich_text><rich_text>)
</rich_text><rich_text foreground="#333333">'earth.mars.venus'</rich_text></node><node name="Unpacking Argument Lists" prog_lang="custom-colors" readonly="False" tags="" unique_id="77"><rich_text>The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#range">range()</rich_text><rich_text> function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">list</rich_text><rich_text>(</rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">6</rich_text><rich_text>)) </rich_text><rich_text foreground="#408090"># normal call with separate arguments</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">[3, 4, 5]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>args </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">6</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">list</rich_text><rich_text>(</rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#666666">*</rich_text><rich_text>args)) </rich_text><rich_text foreground="#408090"># call with arguments unpacked from a list</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">[3, 4, 5]</rich_text><rich_text>
In the same fashion, dictionaries can deliver keyword arguments with the **-operator:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">parrot</rich_text><rich_text>(voltage, state</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'a stiff'</rich_text><rich_text>, action</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">'voom'</rich_text><rich_text>):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"-- This parrot wouldn't"</rich_text><rich_text>, action, end</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">' '</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"if you put"</rich_text><rich_text>, voltage, </rich_text><rich_text foreground="#4070a0">"volts through it."</rich_text><rich_text>, end</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#4070a0">' '</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"E's"</rich_text><rich_text>, state, </rich_text><rich_text foreground="#4070a0">"!"</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>d </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> {</rich_text><rich_text foreground="#4070a0">"voltage"</rich_text><rich_text>: </rich_text><rich_text foreground="#4070a0">"four million"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"state"</rich_text><rich_text>: </rich_text><rich_text foreground="#4070a0">"bleedin' demised"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"action"</rich_text><rich_text>: </rich_text><rich_text foreground="#4070a0">"VOOM"</rich_text><rich_text>}
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>parrot(</rich_text><rich_text foreground="#666666">**</rich_text><rich_text>d)
</rich_text><rich_text foreground="#333333">-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !</rich_text></node><node name="Documentation Strings" prog_lang="custom-colors" readonly="False" tags="" unique_id="78"><rich_text>Here are some conventions about the content and formatting of documentation strings.
The first line should always be a short, concise summary of the object’s purpose. For brevity, it should not explicitly state the object’s name or type, since these are available by other means (except if the name happens to be a verb describing a function’s operation). This line should begin with a capital letter and end with a period.
If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. The following lines should be one or more paragraphs describing the object’s calling conventions, its side effects, etc.
The Python parser does not strip indentation from multi-line string literals in Python, so tools that process documentation have to strip indentation if desired. This is done using the following convention. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string. (We can’t use the first line since it is generally adjacent to the string’s opening quotes so its indentation is not apparent in the string literal.) Whitespace “equivalent” to this indentation is then stripped from the start of all lines of the string. Lines that are indented less should not occur, but if they occur all their leading whitespace should be stripped. Equivalence of whitespace should be tested after expansion of tabs (to 8 spaces, normally).
Here is an example of a multi-line docstring:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">my_function</rich_text><rich_text>():
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">"""Do nothing, but document it.</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text foreground="#4070a0"> No, really, it doesn't do anything.</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text foreground="#4070a0"> """</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">pass</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(my_function</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>__doc__)
</rich_text><rich_text foreground="#333333">Do nothing, but document it.</rich_text><rich_text>
</rich_text><rich_text foreground="#333333"> No, really, it doesn't do anything.</rich_text></node><node name="Annotations" prog_lang="custom-colors" readonly="False" tags="" unique_id="79"><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#function">Function annotations</rich_text><rich_text> are completely optional, arbitrary metadata information about user-defined functions. Neither Python itself nor the standard library use function annotations in any way; this section just shows the syntax. Third-party projects are free to use function annotations for documentation, type checking, and other uses.
Annotations are stored in the __annotations__ attribute of the function as a dictionary and have no effect on any other part of the function. Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating to the value of the annotation. Return annotations are defined by a literal ->, followed by an expression, between the parameter list and the colon denoting the end of the </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#def">def</rich_text><rich_text> statement. The following example has a positional argument, a keyword argument, and the return value annotated with nonsense:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">def</rich_text><rich_text> </rich_text><rich_text foreground="#06287e">f</rich_text><rich_text>(ham: </rich_text><rich_text foreground="#208050">42</rich_text><rich_text>, eggs: </rich_text><rich_text foreground="#007020">int</rich_text><rich_text> </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'spam'</rich_text><rich_text>) </rich_text><rich_text foreground="#666666">-></rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">"Nothing to see here"</rich_text><rich_text>:
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"Annotations:"</rich_text><rich_text>, f</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>__annotations__)
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">"Arguments:"</rich_text><rich_text>, ham, eggs)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>f(</rich_text><rich_text foreground="#4070a0">'wonderful'</rich_text><rich_text>)
</rich_text><rich_text foreground="#333333">Annotations: {'eggs': <class 'int'>, 'return': 'Nothing to see here', 'ham': 42}</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">Arguments: wonderful spam</rich_text></node></node></node><node name="Coding Style" prog_lang="custom-colors" readonly="False" tags="" unique_id="80"><rich_text>Now that you are about to write longer, more complex pieces of Python, it is a good time to talk about coding style. Most languages can be written (or more concise, formatted) in different styles; some are more readable than others. Making it easy for others to read your code is always a good idea, and adopting a nice coding style helps tremendously for that.
For Python, </rich_text><rich_text link="webs http://www.python.org/dev/peps/pep-0008">PEP 8</rich_text><rich_text> has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; here are the most important points extracted for you:
• Use 4-space indentation, and no tabs.
4 spaces are a good compromise between small indentation (allows greater nesting depth) and large indentation (easier to read). Tabs introduce confusion, and are best left out.
• Wrap lines so that they don’t exceed 79 characters.
This helps users with small displays and makes it possible to have several code files side-by-side on larger displays.
• Use blank lines to separate functions and classes, and larger blocks of code inside functions.
• When possible, put comments on a line of their own.
• Use docstrings.
• Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4).
• Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/classes.html#tut-firstclasses">A First Look at Classes</rich_text><rich_text> for more on classes and methods).
• Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case.
• Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.
</rich_text></node><node name="Data Structures" prog_lang="custom-colors" readonly="False" tags="" unique_id="81"><rich_text></rich_text><node name="Lists" prog_lang="custom-colors" readonly="False" tags="" unique_id="82"><rich_text></rich_text><node name="Methods" prog_lang="custom-colors" readonly="False" tags="" unique_id="83"><rich_text>list.append(x)Add an item to the end of the list. Equivalent to a[len(a):] = [x].
list.extend(L)Extend the list by appending all the items in the given list. Equivalent to a[len(a):] = L.
list.insert(i, x)Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
list.remove(x)Remove the first item from the list whose value is x. It is an error if there is no such item.
list.pop([i])Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)
list.index(x)Return the index in the list of the first item whose value is x. It is an error if there is no such item.
list.count(x)Return the number of times x appears in the list.
list.sort()Sort the items of the list in place.
list.reverse()Reverse the elements of the list in place.
An example that uses most of the list methods:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">66.25</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">333</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">333</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">1234.5</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>count(</rich_text><rich_text foreground="#208050">333</rich_text><rich_text>), a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>count(</rich_text><rich_text foreground="#208050">66.25</rich_text><rich_text>), a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>count(</rich_text><rich_text foreground="#4070a0">'x'</rich_text><rich_text>))
</rich_text><rich_text foreground="#333333">2 1 0</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>insert(</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#666666">-</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(</rich_text><rich_text foreground="#208050">333</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[66.25, 333, -1, 333, 1, 1234.5, 333]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>index(</rich_text><rich_text foreground="#208050">333</rich_text><rich_text>)
</rich_text><rich_text foreground="#333333">1</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>remove(</rich_text><rich_text foreground="#208050">333</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[66.25, -1, 333, 1, 1234.5, 333]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>reverse()
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[333, 1234.5, 1, 333, -1, 66.25]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>sort()
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[-1, 1, 66.25, 333, 333, 1234.5]</rich_text><rich_text>
You might have noticed that methods like insert, remove or sort that modify the list have no return value printed – they return None. </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/datastructures.html#id3">[1]</rich_text><rich_text>This is a design principle for all mutable data structures in Python.
</rich_text></node><node name="Using Lists as Stacks and Queues" prog_lang="custom-colors" readonly="False" tags="" unique_id="84"><rich_text>The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack, use pop() without an explicit index. For example:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">5</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(</rich_text><rich_text foreground="#208050">6</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(</rich_text><rich_text foreground="#208050">7</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack
</rich_text><rich_text foreground="#333333">[3, 4, 5, 6, 7]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>pop()
</rich_text><rich_text foreground="#333333">7</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack
</rich_text><rich_text foreground="#333333">[3, 4, 5, 6]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>pop()
</rich_text><rich_text foreground="#333333">6</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>pop()
</rich_text><rich_text foreground="#333333">5</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>stack
</rich_text><rich_text foreground="#333333">[3, 4]</rich_text><rich_text>
</rich_text><rich_text scale="h3">5.1.2. Using Lists as Queues</rich_text><rich_text>
It is also possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).
To implement a queue, use </rich_text><rich_text link="webs http://docs.python.org/3/library/collections.html#collections.deque">collections.deque</rich_text><rich_text> which was designed to have fast appends and pops from both ends. For example:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">from</rich_text><rich_text> </rich_text><rich_text foreground="#0e84b5">collections</rich_text><rich_text> </rich_text><rich_text foreground="#007020">import</rich_text><rich_text> deque
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>queue </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> deque([</rich_text><rich_text foreground="#4070a0">"Eric"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"John"</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">"Michael"</rich_text><rich_text>])
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>queue</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(</rich_text><rich_text foreground="#4070a0">"Terry"</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># Terry arrives</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>queue</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(</rich_text><rich_text foreground="#4070a0">"Graham"</rich_text><rich_text>) </rich_text><rich_text foreground="#408090"># Graham arrives</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>queue</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>popleft() </rich_text><rich_text foreground="#408090"># The first to arrive now leaves</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">'Eric'</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>queue</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>popleft() </rich_text><rich_text foreground="#408090"># The second to arrive now leaves</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">'John'</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>queue </rich_text><rich_text foreground="#408090"># Remaining queue in order of arrival</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">deque(['Michael', 'Terry', 'Graham'])</rich_text></node><node name="List Comprehensions" prog_lang="custom-colors" readonly="False" tags="" unique_id="85"><rich_text>List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.
For example, assume we want to create a list of squares, like:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>squares </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> []
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">10</rich_text><rich_text>):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> squares</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(x</rich_text><rich_text foreground="#666666">**</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>squares
</rich_text><rich_text foreground="#333333">[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]</rich_text><rich_text>
We can obtain the same result with:
squares </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [x</rich_text><rich_text foreground="#666666">**</rich_text><rich_text foreground="#208050">2</rich_text><rich_text> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">10</rich_text><rich_text>)]
This is also equivalent to squares = list(map(lambda x: x**2, range(10))), but it’s more concise and readable.
A list comprehension consists of brackets containing an expression followed by a </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> clause, then zero or more </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> or </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#if">if</rich_text><rich_text> clauses. The result will be a new list resulting from evaluating the expression in the context of the </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> and </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#if">if</rich_text><rich_text> clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[(x, y) </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>] </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> y </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>] </rich_text><rich_text foreground="#007020">if</rich_text><rich_text> x </rich_text><rich_text foreground="#666666">!=</rich_text><rich_text> y]
</rich_text><rich_text foreground="#333333">[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]</rich_text><rich_text>
and it’s equivalent to:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>combs </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> []
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>]:
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> y </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>]:
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">if</rich_text><rich_text> x </rich_text><rich_text foreground="#666666">!=</rich_text><rich_text> y:
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> combs</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append((x, y))
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>combs
</rich_text><rich_text foreground="#333333">[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]</rich_text><rich_text>
Note how the order of the </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> and </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#if">if</rich_text><rich_text> statements is the same in both these snippets.
If the expression is a tuple (e.g. the (x, y) in the previous example), it must be parenthesized.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>vec </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#666666">-</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>, </rich_text><rich_text foreground="#666666">-</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">0</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># create a new list with the values doubled</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[x</rich_text><rich_text foreground="#666666">*</rich_text><rich_text foreground="#208050">2</rich_text><rich_text> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> vec]
</rich_text><rich_text foreground="#333333">[-8, -4, 0, 4, 8]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># filter the list to exclude negative numbers</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[x </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> vec </rich_text><rich_text foreground="#007020">if</rich_text><rich_text> x </rich_text><rich_text foreground="#666666">>=</rich_text><rich_text> </rich_text><rich_text foreground="#208050">0</rich_text><rich_text>]
</rich_text><rich_text foreground="#333333">[0, 2, 4]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># apply a function to all the elements</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[</rich_text><rich_text foreground="#007020">abs</rich_text><rich_text>(x) </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> vec]
</rich_text><rich_text foreground="#333333">[4, 2, 0, 2, 4]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># call a method on each element</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>freshfruit </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#4070a0">' banana'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">' loganberry '</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'passion fruit '</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[weapon</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>strip() </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> weapon </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> freshfruit]
</rich_text><rich_text foreground="#333333">['banana', 'loganberry', 'passion fruit']</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># create a list of 2-tuples like (number, square)</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[(x, x</rich_text><rich_text foreground="#666666">**</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>) </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">6</rich_text><rich_text>)]
</rich_text><rich_text foreground="#333333">[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># the tuple must be parenthesized, otherwise an error is raised</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[x, x</rich_text><rich_text foreground="#666666">**</rich_text><rich_text foreground="#208050">2</rich_text><rich_text> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">6</rich_text><rich_text>)]
</rich_text><rich_text foreground="#333333"> File "<stdin>", line 1, in ?</rich_text><rich_text>
</rich_text><rich_text foreground="#333333"> [x, x**2 for x in range(6)]</rich_text><rich_text>
</rich_text><rich_text foreground="#333333"> ^</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">SyntaxError: invalid syntax</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># flatten a list using a listcomp with two 'for'</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>vec </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [[</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>], [</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">5</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">6</rich_text><rich_text>], [</rich_text><rich_text foreground="#208050">7</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">8</rich_text><rich_text>,</rich_text><rich_text foreground="#208050">9</rich_text><rich_text>]]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[num </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> elem </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> vec </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> num </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> elem]
</rich_text><rich_text foreground="#333333">[1, 2, 3, 4, 5, 6, 7, 8, 9]</rich_text><rich_text>
List comprehensions can contain complex expressions and nested functions:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">from</rich_text><rich_text> </rich_text><rich_text foreground="#0e84b5">math</rich_text><rich_text> </rich_text><rich_text foreground="#007020">import</rich_text><rich_text> pi
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[</rich_text><rich_text foreground="#007020">str</rich_text><rich_text>(</rich_text><rich_text foreground="#007020">round</rich_text><rich_text>(pi, i)) </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> i </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">6</rich_text><rich_text>)]
</rich_text><rich_text foreground="#333333">['3.1', '3.14', '3.142', '3.1416', '3.14159']</rich_text></node><node name="Nested List Comprehensions" prog_lang="custom-colors" readonly="False" tags="" unique_id="86"><rich_text>The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension.
Consider the following example of a 3x4 matrix implemented as a list of 3 lists of length 4:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>matrix </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> [</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>],
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> [</rich_text><rich_text foreground="#208050">5</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">6</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">7</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">8</rich_text><rich_text>],
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> [</rich_text><rich_text foreground="#208050">9</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">10</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">11</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">12</rich_text><rich_text>],
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text>]
The following list comprehension will transpose rows and columns:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>[[row[i] </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> row </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> matrix] </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> i </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>)]
</rich_text><rich_text foreground="#333333">[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]</rich_text><rich_text>
As we saw in the previous section, the nested listcomp is evaluated in the context of the </rich_text><rich_text link="webs http://docs.python.org/3/reference/compound_stmts.html#for">for</rich_text><rich_text> that follows it, so this example is equivalent to:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>transposed </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> []
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> i </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> transposed</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append([row[i] </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> row </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> matrix])
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>transposed
</rich_text><rich_text foreground="#333333">[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]</rich_text><rich_text>
which, in turn, is the same as:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>transposed </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> []
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> i </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#408090"># the following 3 lines implement the nested listcomp</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> transposed_row </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> []
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> row </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> matrix:
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> transposed_row</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(row[i])
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> transposed</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>append(transposed_row)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>transposed
</rich_text><rich_text foreground="#333333">[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]</rich_text><rich_text>
In the real world, you should prefer built-in functions to complex flow statements. The </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#zip">zip()</rich_text><rich_text> function would do a great job for this use case:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">list</rich_text><rich_text>(</rich_text><rich_text foreground="#007020">zip</rich_text><rich_text>(</rich_text><rich_text foreground="#666666">*</rich_text><rich_text>matrix))
</rich_text><rich_text foreground="#333333">[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]</rich_text><rich_text>
See </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/controlflow.html#tut-unpacking-arguments">Unpacking Argument Lists</rich_text><rich_text> for details on the asterisk in this line.
</rich_text></node></node><node name="Del Statement" prog_lang="custom-colors" readonly="False" tags="" unique_id="87"><rich_text>There is a way to remove an item from a list given its index instead of its value: the </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#del">del</rich_text><rich_text> statement. This differs from the pop() method which returns a value. The </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#del">del</rich_text><rich_text> statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#666666">-</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">66.25</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">333</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">333</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">1234.5</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">del</rich_text><rich_text> a[</rich_text><rich_text foreground="#208050">0</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[1, 66.25, 333, 333, 1234.5]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">del</rich_text><rich_text> a[</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>:</rich_text><rich_text foreground="#208050">4</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[1, 66.25, 1234.5]</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">del</rich_text><rich_text> a[:]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">[]</rich_text><rich_text>
</rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#del">del</rich_text><rich_text> can also be used to delete entire variables:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">del</rich_text><rich_text> a
Referencing the name a hereafter is an error (at least until another value is assigned to it). We’ll find other uses for </rich_text><rich_text link="webs http://docs.python.org/3/reference/simple_stmts.html#del">del</rich_text><rich_text> later.
</rich_text></node><node name="Tuples and Sequences" prog_lang="custom-colors" readonly="False" tags="" unique_id="88"><rich_text>We saw that lists and strings have many common properties, such as indexing and slicing operations. They are two examples ofsequence data types (see </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#typesseq">Sequence Types — list, tuple, range</rich_text><rich_text>). Since Python is an evolving language, other sequence data types may be added. There is also another standard sequence data type: the tuple.
A tuple consists of a number of values separated by commas, for instance:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>t </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#208050">12345</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">54321</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'hello!'</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>t[</rich_text><rich_text foreground="#208050">0</rich_text><rich_text>]
</rich_text><rich_text foreground="#333333">12345</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>t
</rich_text><rich_text foreground="#333333">(12345, 54321, 'hello!')</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># Tuples may be nested:</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text>u </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> t, (</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">5</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>u
</rich_text><rich_text foreground="#333333">((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># Tuples are immutable:</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text>t[</rich_text><rich_text foreground="#208050">0</rich_text><rich_text>] </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#208050">88888</rich_text><rich_text>
</rich_text><rich_text foreground="#0044dd">Traceback (most recent call last):</rich_text><rich_text>
File </rich_text><rich_text foreground="#007020">"<stdin>"</rich_text><rich_text>, line </rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, in <module>
</rich_text><rich_text foreground="#ff0000">TypeError</rich_text><rich_text>: 'tuple' object does not support item assignment
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># but they can contain mutable objects:</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text>v </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> ([</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>], [</rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">1</rich_text><rich_text>])
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>v
</rich_text><rich_text foreground="#333333">([1, 2, 3], [3, 2, 1])</rich_text><rich_text>
As you see, on output tuples are always enclosed in parentheses, so that nested tuples are interpreted correctly; they may be input with or without surrounding parentheses, although often parentheses are necessary anyway (if the tuple is part of a larger expression). It is not possible to assign to the individual items of a tuple, however it is possible to create tuples which contain mutable objects, such as lists.
Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples are </rich_text><rich_text link="webs http://docs.python.org/3/glossary.html#term-immutable">immutable</rich_text><rich_text>, and usually contain an heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of </rich_text><rich_text link="webs http://docs.python.org/3/library/collections.html#collections.namedtuple">namedtuples</rich_text><rich_text>). Lists are </rich_text><rich_text link="webs http://docs.python.org/3/glossary.html#term-mutable">mutable</rich_text><rich_text>, and their elements are usually homogeneous and are accessed by iterating over the list.
A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For example:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>empty </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> ()
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>singleton </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'hello'</rich_text><rich_text>, </rich_text><rich_text foreground="#408090"># <-- note trailing comma</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">len</rich_text><rich_text>(empty)
</rich_text><rich_text foreground="#333333">0</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">len</rich_text><rich_text>(singleton)
</rich_text><rich_text foreground="#333333">1</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>singleton
</rich_text><rich_text foreground="#333333">('hello',)</rich_text><rich_text>
The statement t = 12345, 54321, 'hello!' is an example of tuple packing: the values 12345, 54321 and 'hello!' are packed together in a tuple. The reverse operation is also possible:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>x, y, z </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> t
This is called, appropriately enough, sequence unpacking and works for any sequence on the right-hand side. Sequence unpacking requires that there are as many variables on the left side of the equals sign as there are elements in the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking.
</rich_text></node><node name="Sets" prog_lang="custom-colors" readonly="False" tags="" unique_id="89"><rich_text>Python also includes a data type for sets. A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.
Curly braces or the </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#set">set()</rich_text><rich_text> function can be used to create sets. Note: to create an empty set you have to use set(), not {}; the latter creates an empty dictionary, a data structure that we discuss in the next section.
Here is a brief demonstration:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>basket </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> {</rich_text><rich_text foreground="#4070a0">'apple'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'orange'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'apple'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'pear'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'orange'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'banana'</rich_text><rich_text>}
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(basket) </rich_text><rich_text foreground="#408090"># show that duplicates have been removed</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">{'orange', 'banana', 'pear', 'apple'}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#4070a0">'orange'</rich_text><rich_text> </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> basket </rich_text><rich_text foreground="#408090"># fast membership testing</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">True</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#4070a0">'crabgrass'</rich_text><rich_text> </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> basket
</rich_text><rich_text foreground="#333333">False</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#408090"># Demonstrate set operations on unique letters from two words</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#007020">set</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">'abracadabra'</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>b </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#007020">set</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">'alacazam'</rich_text><rich_text>)
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#408090"># unique letters in a</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">{'a', 'r', 'b', 'c', 'd'}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">-</rich_text><rich_text> b </rich_text><rich_text foreground="#408090"># letters in a but not in b</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">{'r', 'd', 'b'}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">|</rich_text><rich_text> b </rich_text><rich_text foreground="#408090"># letters in either a or b</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">&</rich_text><rich_text> b </rich_text><rich_text foreground="#408090"># letters in both a and b</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">{'a', 'c'}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">^</rich_text><rich_text> b </rich_text><rich_text foreground="#408090"># letters in a or b but not both</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">{'r', 'd', 'b', 'm', 'z', 'l'}</rich_text><rich_text>
Similarly to </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/datastructures.html#tut-listcomps">list comprehensions</rich_text><rich_text>, set comprehensions are also supported:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> {x </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'abracadabra'</rich_text><rich_text> </rich_text><rich_text foreground="#007020">if</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">not</rich_text><rich_text> </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'abc'</rich_text><rich_text>}
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>a
</rich_text><rich_text foreground="#333333">{'r', 'd'}</rich_text></node><node name="Dictionaries" prog_lang="custom-colors" readonly="False" tags="" unique_id="90"><rich_text>Another useful data type built into Python is the dictionary (see </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#typesmapping">Mapping Types — dict</rich_text><rich_text>). Dictionaries are sometimes found in other languages as “associative memories” or “associative arrays”. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can’t use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like append() andextend().
It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: {}. Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to the dictionary; this is also the way dictionaries are written on output.
The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.
Performing list(d.keys()) on a dictionary returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just use sorted(d.keys()) instead). </rich_text><rich_text link="webs http://docs.python.org/3/tutorial/datastructures.html#id4">[2]</rich_text><rich_text> To check whether a single key is in the dictionary, use the </rich_text><rich_text link="webs http://docs.python.org/3/reference/expressions.html#in">in</rich_text><rich_text> keyword.
Here is a small example using a dictionary:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>tel </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> {</rich_text><rich_text foreground="#4070a0">'jack'</rich_text><rich_text>: </rich_text><rich_text foreground="#208050">4098</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'sape'</rich_text><rich_text>: </rich_text><rich_text foreground="#208050">4139</rich_text><rich_text>}
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>tel[</rich_text><rich_text foreground="#4070a0">'guido'</rich_text><rich_text>] </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#208050">4127</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>tel
</rich_text><rich_text foreground="#333333">{'sape': 4139, 'guido': 4127, 'jack': 4098}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>tel[</rich_text><rich_text foreground="#4070a0">'jack'</rich_text><rich_text>]
</rich_text><rich_text foreground="#333333">4098</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">del</rich_text><rich_text> tel[</rich_text><rich_text foreground="#4070a0">'sape'</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>tel[</rich_text><rich_text foreground="#4070a0">'irv'</rich_text><rich_text>] </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#208050">4127</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>tel
</rich_text><rich_text foreground="#333333">{'guido': 4127, 'irv': 4127, 'jack': 4098}</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">list</rich_text><rich_text>(tel</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>keys())
</rich_text><rich_text foreground="#333333">['irv', 'guido', 'jack']</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">sorted</rich_text><rich_text>(tel</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>keys())
</rich_text><rich_text foreground="#333333">['guido', 'irv', 'jack']</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#4070a0">'guido'</rich_text><rich_text> </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> tel
</rich_text><rich_text foreground="#333333">True</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#4070a0">'jack'</rich_text><rich_text> </rich_text><rich_text foreground="#007020">not</rich_text><rich_text> </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> tel
</rich_text><rich_text foreground="#333333">False</rich_text><rich_text>
The </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html#dict">dict()</rich_text><rich_text> constructor builds dictionaries directly from sequences of key-value pairs:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">dict</rich_text><rich_text>([(</rich_text><rich_text foreground="#4070a0">'sape'</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4139</rich_text><rich_text>), (</rich_text><rich_text foreground="#4070a0">'guido'</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4127</rich_text><rich_text>), (</rich_text><rich_text foreground="#4070a0">'jack'</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4098</rich_text><rich_text>)])
</rich_text><rich_text foreground="#333333">{'sape': 4139, 'jack': 4098, 'guido': 4127}</rich_text><rich_text>
In addition, dict comprehensions can be used to create dictionaries from arbitrary key and value expressions:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>{x: x</rich_text><rich_text foreground="#666666">**</rich_text><rich_text foreground="#208050">2</rich_text><rich_text> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> x </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> (</rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">6</rich_text><rich_text>)}
</rich_text><rich_text foreground="#333333">{2: 4, 4: 16, 6: 36}</rich_text><rich_text>
When the keys are simple strings, it is sometimes easier to specify pairs using keyword arguments:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">dict</rich_text><rich_text>(sape</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">4139</rich_text><rich_text>, guido</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">4127</rich_text><rich_text>, jack</rich_text><rich_text foreground="#666666">=</rich_text><rich_text foreground="#208050">4098</rich_text><rich_text>)
</rich_text><rich_text foreground="#333333">{'sape': 4139, 'jack': 4098, 'guido': 4127}</rich_text></node><node name="Loop Techniques" prog_lang="custom-colors" readonly="False" tags="" unique_id="91"><rich_text>When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the items() method.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>knights </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> {</rich_text><rich_text foreground="#4070a0">'gallahad'</rich_text><rich_text>: </rich_text><rich_text foreground="#4070a0">'the pure'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'robin'</rich_text><rich_text>: </rich_text><rich_text foreground="#4070a0">'the brave'</rich_text><rich_text>}
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> k, v </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> knights</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>items():
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(k, v)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">gallahad the pure</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">robin the brave</rich_text><rich_text>
When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#enumerate">enumerate()</rich_text><rich_text>function.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> i, v </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">enumerate</rich_text><rich_text>([</rich_text><rich_text foreground="#4070a0">'tic'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'tac'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'toe'</rich_text><rich_text>]):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(i, v)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">0 tic</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">1 tac</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">2 toe</rich_text><rich_text>
To loop over two or more sequences at the same time, the entries can be paired with the </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#zip">zip()</rich_text><rich_text> function.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>questions </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#4070a0">'name'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'quest'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'favorite color'</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>answers </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#4070a0">'lancelot'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'the holy grail'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'blue'</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> q, a </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">zip</rich_text><rich_text>(questions, answers):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(</rich_text><rich_text foreground="#4070a0">'What is your {0}? It is {1}.'</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>format(q, a))
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">What is your name? It is lancelot.</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">What is your quest? It is the holy grail.</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">What is your favorite color? It is blue.</rich_text><rich_text>
To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#reversed">reversed()</rich_text><rich_text> function.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> i </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">reversed</rich_text><rich_text>(</rich_text><rich_text foreground="#007020">range</rich_text><rich_text>(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">10</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>)):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(i)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">9</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">7</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">5</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">3</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">1</rich_text><rich_text>
To loop over a sequence in sorted order, use the </rich_text><rich_text link="webs http://docs.python.org/3/library/functions.html#sorted">sorted()</rich_text><rich_text> function which returns a new sorted list while leaving the source unaltered.
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>basket </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#4070a0">'apple'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'orange'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'apple'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'pear'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'orange'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'banana'</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> f </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> </rich_text><rich_text foreground="#007020">sorted</rich_text><rich_text>(</rich_text><rich_text foreground="#007020">set</rich_text><rich_text>(basket)):
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">print</rich_text><rich_text>(f)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">apple</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">banana</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">orange</rich_text><rich_text>
</rich_text><rich_text foreground="#333333">pear</rich_text><rich_text>
To change a sequence you are iterating over while inside the loop (for example to duplicate certain items), it is recommended that you first make a copy. Looping over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>words </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> [</rich_text><rich_text foreground="#4070a0">'cat'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'window'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'defenestrate'</rich_text><rich_text>]
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text foreground="#007020">for</rich_text><rich_text> w </rich_text><rich_text foreground="#007020">in</rich_text><rich_text> words[:]: </rich_text><rich_text foreground="#408090"># Loop over a slice copy of the entire list.</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> </rich_text><rich_text foreground="#007020">if</rich_text><rich_text> </rich_text><rich_text foreground="#007020">len</rich_text><rich_text>(w) </rich_text><rich_text foreground="#666666">></rich_text><rich_text> </rich_text><rich_text foreground="#208050">6</rich_text><rich_text>:
</rich_text><rich_text foreground="#c65d09">... </rich_text><rich_text> words</rich_text><rich_text foreground="#666666">.</rich_text><rich_text>insert(</rich_text><rich_text foreground="#208050">0</rich_text><rich_text>, w)
</rich_text><rich_text foreground="#c65d09">...</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>words
</rich_text><rich_text foreground="#333333">['defenestrate', 'cat', 'window', 'defenestrate']</rich_text></node><node name="Conditions" prog_lang="custom-colors" readonly="False" tags="" unique_id="92"><rich_text>The conditions used in while and if statements can contain any operators, not just comparisons.
The comparison operators in and not in check whether a value occurs (does not occur) in a sequence. The operators is and is notcompare whether two objects are really the same object; this only matters for mutable objects like lists. All comparison operators have the same priority, which is lower than that of all numerical operators.
Comparisons can be chained. For example, a < b == c tests whether a is less than b and moreover b equals c.
Comparisons may be combined using the Boolean operators and and or, and the outcome of a comparison (or of any other Boolean expression) may be negated with not. These have lower priorities than comparison operators; between them, not has the highest priority and or the lowest, so that A and not B or C is equivalent to (A and (not B)) or C. As always, parentheses can be used to express the desired composition.
The Boolean operators and and or are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A and C are true but B is false, A and B and C does not evaluate the expression C. When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.
It is possible to assign the result of a comparison or other Boolean expression to a variable. For example,
>>></rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>string1, string2, string3 </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">''</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'Trondheim'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'Hammer Dance'</rich_text><rich_text>
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>non_null </rich_text><rich_text foreground="#666666">=</rich_text><rich_text> string1 </rich_text><rich_text foreground="#007020">or</rich_text><rich_text> string2 </rich_text><rich_text foreground="#007020">or</rich_text><rich_text> string3
</rich_text><rich_text foreground="#c65d09">>>> </rich_text><rich_text>non_null
</rich_text><rich_text foreground="#333333">'Trondheim'</rich_text><rich_text>
Note that in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.
</rich_text></node><node name="Comparing Sequences and Other Types" prog_lang="custom-colors" readonly="False" tags="" unique_id="93"><rich_text>Sequence objects may be compared to other objects with the same sequence type. The comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted. If two items to be compared are themselves sequences of the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode codepoint number to order individual characters. Some examples of comparisons between sequences of the same type:
(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>) </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> (</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>)
[</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>] </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> [</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>]
</rich_text><rich_text foreground="#4070a0">'ABC'</rich_text><rich_text> </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'C'</rich_text><rich_text> </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'Pascal'</rich_text><rich_text> </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> </rich_text><rich_text foreground="#4070a0">'Python'</rich_text><rich_text>
(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>) </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> (</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>)
(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>) </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> (</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#666666">-</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>)
(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3</rich_text><rich_text>) </rich_text><rich_text foreground="#666666">==</rich_text><rich_text> (</rich_text><rich_text foreground="#208050">1.0</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2.0</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">3.0</rich_text><rich_text>)
(</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, (</rich_text><rich_text foreground="#4070a0">'aa'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'ab'</rich_text><rich_text>)) </rich_text><rich_text foreground="#666666"><</rich_text><rich_text> (</rich_text><rich_text foreground="#208050">1</rich_text><rich_text>, </rich_text><rich_text foreground="#208050">2</rich_text><rich_text>, (</rich_text><rich_text foreground="#4070a0">'abc'</rich_text><rich_text>, </rich_text><rich_text foreground="#4070a0">'a'</rich_text><rich_text>), </rich_text><rich_text foreground="#208050">4</rich_text><rich_text>)
Note that comparing objects of different types with < or > is legal provided that the objects have appropriate comparison methods. For example, mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc. Otherwise, rather than providing an arbitrary ordering, the interpreter will raise a </rich_text><rich_text link="webs http://docs.python.org/3/library/exceptions.html#TypeError">TypeError</rich_text><rich_text> exception.</rich_text></node></node></node></node><node name="Case Study: C++11" prog_lang="custom-colors" readonly="False" tags="" unique_id="32"><rich_text>I already know C++ well enough, so I won't explain all aspects here. I'm going to go through the Wikipedia article about C++11, </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11">http://en.wikipedia.org/wiki/C%2B%2B11</rich_text><rich_text>, and write here about features which may be relevant to my language.
Here's the table of contents of the article:
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Core_language_runtime_performance_enhancements">3 Core language runtime performance enhancements</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Rvalue_references_and_move_constructors">3.1 Rvalue references and move constructors</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#constexpr_.E2.80.93_Generalized_constant_expressions">3.2 constexpr – Generalized constant expressions</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Modification_to_the_definition_of_plain_old_data">3.3 Modification to the definition of plain old data</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Core_language_build_time_performance_enhancements">4 Core language build time performance enhancements</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Extern_template">4.1 Extern template</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Core_language_usability_enhancements">5 Core language usability enhancements</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Initializer_lists">5.1 Initializer lists</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization">5.2 Uniform initialization</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Type_inference">5.3 Type inference</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Range-based_for_loop">5.4 Range-based for loop</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions">5.5 Lambda functions and expressions</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Alternative_function_syntax">5.6 Alternative function syntax</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Object_construction_improvement">5.7 Object construction improvement</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final">5.8 Explicit overrides and final</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Null_pointer_constant">5.9 Null pointer constant</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations">5.10 Strongly typed enumerations</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Right_angle_bracket">5.11 Right angle bracket</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_conversion_operators">5.12 Explicit conversion operators</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Alias_templates">5.13 Alias templates</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Unrestricted_unions">5.14 Unrestricted unions</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Core_language_functionality_improvements">6 Core language functionality improvements</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Variadic_templates">6.1 Variadic templates</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals">6.2 New string literals</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals">6.3 User-defined literals</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Multithreading_memory_model">6.4 Multithreading memory model</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Thread-local_storage">6.5 Thread-local storage</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Explicitly_defaulted_and_deleted_special_member_functions">6.6 Explicitly defaulted and deleted special member functions</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Type_long_long_int">6.7 Type long long int</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Static_assertions">6.8 Static assertions</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Allow_sizeof_to_work_on_members_of_classes_without_an_explicit_object">6.9 Allow sizeof to work on members of classes without an explicit object</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Control_and_query_object_alignment">6.10 Control and query object alignment</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Allow_garbage_collected_implementations">6.11 Allow garbage collected implementations</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Attributes">6.12 Attributes</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#C.2B.2B_standard_library_changes">7 C++ standard library changes</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Upgrades_to_standard_library_components">7.1 Upgrades to standard library components</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Threading_facilities">7.2 Threading facilities</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Tuple_types">7.3 Tuple types</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Hash_tables">7.4 Hash tables</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Regular_expressions">7.5 Regular expressions</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#General-purpose_smart_pointers">7.6 General-purpose smart pointers</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Extensible_random_number_facility">7.7 Extensible random number facility</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Wrapper_reference">7.8 Wrapper reference</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Polymorphic_wrappers_for_function_objects">7.9 Polymorphic wrappers for function objects</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Type_traits_for_metaprogramming">7.10 Type traits for metaprogramming</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_method_for_computing_the_return_type_of_function_objects">7.11 Uniform method for computing the return type of function objects</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Features_originally_planned_but_removed_or_not_included">8 Features originally planned but removed or not included</rich_text><rich_text>
• </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/C%2B%2B11#Features_removed_or_deprecated">9 Features removed or deprecated</rich_text><rich_text>
Now here's a list of things I'd like to note as being interesting and relevant:
• Initializer lists
• Uniform initialization
• Alternative function syntax
• Null pointer constant
• Strongly typed enumerations
• New string literals
• User defined literals
• Type long long int
• Static assertions
• Attributes
• Tuple types
• Hash tables (unordered containers)
• Regular expressions (regex)
• Extensible random number facility
For now I won't explain them here. Instead, I'll use them as a list for reference. Later, if the need arises, I'll go into detail.</rich_text></node></node><node name="Primitive Types" prog_lang="custom-colors" readonly="False" tags="" unique_id="1"><rich_text></rich_text><node name="Primitive Types Draft" prog_lang="custom-colors" readonly="False" tags="" unique_id="33"><rich_text>Here I'm going to make a modified list of XSD primitive datatypes. It has 19 in total, but I may omit some of them, if they are not relevant to my language.
I'll also add types, change names, etc.
I haven't made all decisions related to type names, so I'll just use the same names used by XSD, and later I'll adapt them to my needs.
Here's a format to use for each type:
x. type
value space:
lexical space:
matching function:
constraining facets:
other info:
Python types: </rich_text><rich_text link="webs http://docs.python.org/3/library/stdtypes.html">http://docs.python.org/3/library/stdtypes.html</rich_text><rich_text>
C++11 types: </rich_text><rich_text link="webs http://en.cppreference.com/w/cpp/language/types">http://en.cppreference.com/w/cpp/language/types</rich_text><rich_text>
XSD types: </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string">http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string</rich_text><rich_text>
and also </rich_text><rich_text link="node 13">XSD Primitive Types</rich_text><rich_text>
Let's start.
</rich_text><rich_text link="node 49">Strings</rich_text><rich_text>
</rich_text><rich_text link="node 50">Boolean</rich_text><rich_text>
</rich_text><rich_text link="node 51">Numbers</rich_text><rich_text>
</rich_text><rich_text link="node 52">Date and Time</rich_text><rich_text>
</rich_text><rich_text link="node 53">Binary Data</rich_text><rich_text>
</rich_text><rich_text link="node 54">Identifiers</rich_text><node name="Strings" prog_lang="custom-colors" readonly="False" tags="" unique_id="49"><rich_text weight="heavy">1. </rich_text><rich_text underline="single" weight="heavy">string
</rich_text><rich_text>value space: the set of finite-length sequences of characters in UTF-8
lexical space: the set of finite-length sequences of characters in UTF-8
matching function: Id (the identity function)
constraining facets: length, minLength, maxLength, pattern, enumeration, whiteSpace
other info: This type maps the computer representation directly to characters
A. </rich_text><rich_text underline="single">text
</rich_text><rich_text>A type derived from </rich_text><rich_text style="italic">string</rich_text><rich_text>, which uses combinations like \n, \t, etc. for special characters, maybe also things like \0xFA4E. Also, maybe it will allow "inserting" formatted numbers/variables like printf(), if such a feature proves to be useful and meaningful to the language</rich_text></node><node name="Boolean" prog_lang="custom-colors" readonly="False" tags="" unique_id="50"><rich_text>2. </rich_text><rich_text weight="heavy">boolean</rich_text><rich_text>
value space: {true, false}
lexical space: {true, false, 1, 0}
matching function: true and 1 mean true, while false and 0 mean false
constraining facets: pattern, whiteSpace
other info:</rich_text></node><node name="Numbers" prog_lang="custom-colors" readonly="False" tags="" unique_id="51"><rich_text>3. </rich_text><rich_text weight="heavy">decimal</rich_text><rich_text>
value space: decimal represents a subset of the real numbers, which can be represented by decimal numerals. The value space of decimal is the set of numbers that can be obtained by multiplying an integer by a non-positive power of ten, i.e., expressible as i × 10^-n where i and n are integers and n >= 0. Precision is not reflected in this value space; the number 2.0 is not distinct from the number 2.00. The order-relation on decimal is the order relation on real numbers, restricted to this subset.
</rich_text><rich_text underline="single">lexical space</rich_text><rich_text>: decimal has a lexical representation consisting of a finite-length sequence of decimal digits (#x30-#x39) separated by a period as a decimal indicator. An optional leading sign is allowed. If the sign is omitted, "+" is assumed. Leading and trailing zeroes are optional. If the fractional part is zero, the period and following zero(es) can be omitted. For example: -1.23, 12678967.543233, +100000.00, 210.
</rich_text><rich_text underline="single">matching function</rich_text><rich_text>: Obvious
</rich_text><rich_text underline="single">constraining facets</rich_text><rich_text>: totalDigits, fractionDigits, pattern, whiteSpace, enumeration, maxInclusive, maxExclusive, minInclusive ,minExclusive
</rich_text><rich_text underline="single">other info</rich_text><rich_text>: Note: All minimally conforming processors must support decimal numbers with a minimum of 18 decimal digits (i.e., with a totalDigits of 18). However, minimally conforming processors may set an application-defined limit on the maximum number of decimal digits they are prepared to support, in which case that application-defined maximum number must be clearly documented.</rich_text><rich_text underline="single" weight="heavy">
4. float
</rich_text><rich_text underline="single">value space</rich_text><rich_text>: float is patterned after the IEEE single-precision 32-bit floating point type [IEEE 754-1985]. The basic ·value space· of float consists of the values m × 2^e, where m is an integer whose absolute value is less than 2^24, and e is an integer between -149 and 104, inclusive. In addition to the basic ·value space· described above, the ·value space· of float also contains the following three special values: positive and negative infinity and not-a-number (NaN). The ·order-relation· on float is: x < y iff y - x is positive for x and y in the value space. Positive infinity is greater than all other non-NaN values. NaN equals itself but is ·incomparable· with (neither greater than nor less than) any other value in the ·value space·.
</rich_text><rich_text underline="single">lexical space</rich_text><rich_text>: float values have a lexical representation consisting of a mantissa followed, optionally, by the character "E" or "e", followed by an exponent. The exponent ·must· be an integer. The mantissa must be a decimal number. The representations for exponent and mantissa must follow the lexical rules for integer and decimal. If the "E" or "e" and the following exponent are omitted, an exponent value of 0 is assumed.
The special values positive and negative infinity and not-a-number have lexical representations INF, -INF and NaN, respectively. Lexical representations for zero may take a positive or negative sign.
For example, -1E4, 1267.43233E12, 12.78e-2, 12 , -0, 0 and INF are all legal literals for float.
</rich_text><rich_text underline="single">matching function</rich_text><rich_text>: Obvious
</rich_text><rich_text underline="single">constraining facets</rich_text><rich_text>: pattern, enumeration, whiteSpace, maxInclusive, maxExclusive, minInclusive, minExclusive
</rich_text><rich_text underline="single">other info</rich_text><rich_text>: This datatype differs from that of [IEEE 754-1985] in that there is only one NaN and only one zero. This makes the equality and ordering of values in the data space differ from that of [IEEE 754-1985] only in that for schema purposes NaN = NaN.</rich_text><rich_text underline="single" weight="heavy">
5. double
</rich_text><rich_text underline="single">value space</rich_text><rich_text>: The double datatype is patterned after the IEEE double-precision 64-bit floating point type [IEEE 754-1985]. The basic ·value space· of double consists of the values m × 2^e, where m is an integer whose absolute value is less than 2^53, and e is an integer between -1075 and 970, inclusive. In addition to the basic ·value space· described above, the ·value space· of double also contains the following three special values: positive and negative infinity and not-a-number (NaN). The ·order-relation· on double is: x < y iff y - x is positive for x and y in the value space. Positive infinity is greater than all other non-NaN values. NaN equals itself but is ·incomparable· with (neither greater than nor less than) any other value in the ·value space·.
</rich_text><rich_text underline="single">lexical space</rich_text><rich_text>: double values have a lexical representation consisting of a mantissa followed, optionally, by the character "E" or "e", followed by an exponent. The exponent ·must· be an integer. The mantissa must be a decimal number. The representations for exponent and mantissa must follow the lexical rules for integer and decimal. If the "E" or "e" and the following exponent are omitted, an exponent value of 0 is assumed.
The special values positive and negative infinity and not-a-number have lexical representations INF, -INF and NaN, respectively. Lexical representations for zero may take a positive or negative sign.
For example, -1E4, 1267.43233E12, 12.78e-2, 12 , -0, 0 and INF are all legal literals for double.
</rich_text><rich_text underline="single">matching function</rich_text><rich_text>: Obvious
</rich_text><rich_text underline="single">constraining facets</rich_text><rich_text>: pattern, enumeration, whiteSpace, maxInclusive, maxExclusive, minInclusive, minExclusive
</rich_text><rich_text underline="single">other info</rich_text><rich_text>: This datatype differs from that of [IEEE 754-1985] in that there is only one NaN and only one zero. This makes the equality and ordering of values in the data space differ from that of [IEEE 754-1985] only in that for schema purposes NaN = NaN.</rich_text></node><node name="Date and Time" prog_lang="custom-colors" readonly="False" tags="" unique_id="52"><rich_text>6. </rich_text><rich_text weight="heavy">duration</rich_text><rich_text>
value space: duration represents a duration of time. The ·value space· of duration is a six-dimensional space where the coordinates designate the Gregorian year, month, day, hour, minute, and second components defined in § 5.5.3.2 of [ISO 8601], respectively. These components are ordered in their significance by their order of appearance i.e. as year, month, day, hour, minute, and second.
</rich_text><rich_text underline="single">lexical space</rich_text><rich_text>: The lexical representation for duration is the [ISO 8601] extended format PnYn MnDTnH nMnS, where nY represents the number of years, nM the number of months, nD the number of days, 'T' is the date/time separator, nH the number of hours, nM the number of minutes and nS the number of seconds. The number of seconds can include decimal digits to arbitrary precision.
The values of the Year, Month, Day, Hour and Minutes components are not restricted but allow an arbitrary unsigned integer, i.e., an integer that conforms to the pattern [0-9]+.. Similarly, the value of the Seconds component allows an arbitrary unsigned decimal. Following [ISO 8601], at least one digit must follow the decimal point if it appears. That is, the value of the Seconds component must conform to the pattern [0-9]+(\.[0-9]+)?. Thus, the lexical representation of duration does not follow the alternative format of § 5.5.3.2.1 of [ISO 8601].
An optional preceding minus sign ('-') is allowed, to indicate a negative duration. If the sign is omitted a positive duration is indicated. See also ISO 8601 Date and Time Formats (§D).
For example, to indicate a duration of 1 year, 2 months, 3 days, 10 hours, and 30 minutes, one would write: P1Y2M3DT10H30M. One could also indicate a duration of minus 120 days as: -P120D.
Reduced precision and truncated representations of this format are allowed provided they conform to the following:
If the number of years, months, days, hours, minutes, or seconds in any expression equals zero, the number and its corresponding designator ·may· be omitted. However, at least one number and its designator ·must· be present.
The seconds part ·may· have a decimal fraction.
The designator 'T' must be absent if and only if all of the time items are absent. The designator 'P' must always be present.
For example, P1347Y, P1347M and P1Y2MT2H are all allowed; P0Y1347M and P0Y1347M0D are allowed. P-1347M is not allowed although -P1347M is allowed. P1Y2MT is not allowed.
</rich_text><rich_text underline="single">matching function</rich_text><rich_text>: obvious
</rich_text><rich_text underline="single">constraining facets</rich_text><rich_text>: pattern
enumeration
whiteSpace
maxInclusive
maxExclusive
minInclusive
minExclusive
</rich_text><rich_text underline="single">other info</rich_text><rich_text>: All ·minimally conforming· processors ·must· support year values with a minimum of 4 digits (i.e., YYYY) and a minimum fractional second precision of milliseconds or three decimal digits (i.e. s.sss). However, ·minimally conforming· processors ·may· set an application-defined limit on the maximum number of digits they are prepared to support in these two cases, in which case that application-defined maximum number ·must· be clearly documented.
Order relation on duration
In general, the ·order-relation· on duration is a partial order since there is no determinate relationship between certain durations such as one month (P1M) and 30 days (P30D). The ·order-relation· of two duration values x and y is x < y iff s+x < s+y for each qualified dateTime s in the list below. These values for s cause the greatest deviations in the addition of dateTimes and durations. Addition of durations to time instants is defined in Adding durations to dateTimes (§E).
1696-09-01T00:00:00Z
1697-02-01T00:00:00Z
1903-03-01T00:00:00Z
1903-07-01T00:00:00Z
The following table shows the strongest relationship that can be determined between example durations. The symbol <> means that the order relation is indeterminate. Note that because of leap-seconds, a seconds field can vary from 59 to 60. However, because of the way that addition is defined in Adding durations to dateTimes (§E), they are still totally ordered.
Relation
P1Y > P364D <> P365D <> P366D < P367D
P1M > P27D <> P28D <> P29D <> P30D <> P31D < P32D
P5M > P149D <> P150D <> P151D <> P152D <> P153D < P154D
Implementations are free to optimize the computation of the ordering relationship. For example, the following table can be used to compare durations of a small number of months against days.
Months 1 2 3 4 5 6 7 8 9 10 11 12 13 ...
Days Minimum 28 59 89 120 150 181 212 242 273 303 334 365 393 ...
Maximum 31 62 92 123 153 184 215 245 276 306 337 366 397 ...
Facet Comparison for durations
In comparing duration values with minInclusive, minExclusive, maxInclusive and maxExclusive facet values indeterminate comparisons should be considered as "false".
Totally ordered durations
Certain derived datatypes of durations can be guaranteed have a total order. For this, they must have fields from only one row in the list below and the time zone must either be required or prohibited.
• year, month
• day, hour, minute, second
For example, a datatype could be defined to correspond to the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#SQL">[SQL]</rich_text><rich_text> datatype Year-Month interval that required a four digit year field and a two digit month field but required all other fields to be unspecified. This datatype could be defined as below and would have a total order.
<simpleType name='SQL-Year-Month-Interval'>
<restriction base='duration'>
<pattern value='P\p{Nd}{4}Y\p{Nd}{2}M'/>
</restriction>
</simpleType>
</rich_text><rich_text underline="single" weight="heavy">
7. dateTime
</rich_text><rich_text>dateTime values may be viewed as objects with integer-valued year, month, day, hour and minute properties, a decimal-valued second property, and a boolean timezoned property. Each such object also has one decimal-valued method or computed property, timeOnTimeline, whose value is always a decimal number; the values are dimensioned in seconds, the integer 0 is 0001-01-01T00:00:00 and the value of timeOnTimeline for other dateTime values is computed using the Gregorian algorithm as modified for leap-seconds. The timeOnTimeline values form two related "timelines", one for timezoned values and one for non-timezoned values. Each timeline is a copy of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#decimal">decimal</rich_text><rich_text>, with integers given units of seconds.
The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of dateTime is closely related to the dates and times described in ISO 8601. For clarity, the text above specifies a particular origin point for the timeline. It should be noted, however, that schema processors need not expose the timeOnTimeline value to schema users, and there is no requirement that a timeline-based implementation use the particular origin described here in its internal representation. Other interpretations of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> which lead to the same results (i.e., are isomorphic) are of course acceptable.
All timezoned times are Coordinated Universal Time (UTC, sometimes called "Greenwich Mean Time"). Other timezones indicated in lexical representations are converted to UTC during conversion of literals to values. "Local" or untimezoned times are presumed to be the time in the timezone of some unspecified locality as prescribed by the appropriate legal authority; currently there are no legally prescribed timezones which are durations whose magnitude is greater than 14 hours. The value of each numeric-valued property (other than timeOnTimeline) is limited to the maximum value within the interval determined by the next-higher property. For example, the day value can never be 32, and cannot even be 29 for month 02 and year 2002 (February 2002).
Note:
The date and time datatypes described in this recommendation were inspired by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. '0001' is the lexical representation of the year 1 of the Common Era (1 CE, sometimes written "AD 1" or "1 AD"). There is no year 0, and '0000' is not a valid lexical representation. '-0001' is the lexical representation of the year 1 Before Common Era (1 BCE, sometimes written "1 BC").Those using this (1.0) version of this Recommendation to represent negative years should be aware that the interpretation of lexical representations beginning with a '-' is likely to change in subsequent versions.
</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text> makes no mention of the year 0; in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601-1998">[ISO 8601:1998 Draft Revision]</rich_text><rich_text> the form '0000' was disallowed and this recommendation disallows it as well. However, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601-2000">[ISO 8601:2000 Second Edition]</rich_text><rich_text>, which became available just as we were completing version 1.0, allows the form '0000', representing the year 1 BCE. A number of external commentators have also suggested that '0000' be allowed, as the lexical representation for 1 BCE, which is the normal usage in astronomical contexts. It is the intention of the XML Schema Working Group to allow '0000' as a lexical representation in the dateTime, date, gYear, andgYearMonth datatypes in a subsequent version of this Recommendation. '0000' will be the lexical representation of 1 BCE (which is a leap year), '-0001' will become the lexical representation of 2 BCE (not 1 BCE as in this (1.0) version), '-0002' of 3 BCE, etc.
Note: See the conformance note in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#year-sec-conformance">(§3.2.6)</rich_text><rich_text> which applies to this datatype as well.3.2.7.1 Lexical representationThe </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of dateTime consists of finite-length sequences of characters of the form: '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?, where
• '-'? yyyy is a four-or-more digit optionally negative-signed numeral that represents the year; if more than four digits, leading zeros are prohibited, and '0000' is prohibited (see the Note above </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#year-zero">(§3.2.7)</rich_text><rich_text>; also note that a plus sign is not permitted);
• the remaining '-'s are separators between parts of the date portion;
• the first mm is a two-digit numeral that represents the month;
• dd is a two-digit numeral that represents the day;
• 'T' is a separator indicating that time-of-day follows;
• hh is a two-digit numeral that represents the hour; '24' is permitted if the minutes and seconds represented are zero, and the dateTime value so represented is the first instant of the following day (the hour property of a dateTime object in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> cannot have a value greater than 23);
• ':' is a separator between parts of the time-of-day portion;
• the second mm is a two-digit numeral that represents the minute;
• ss is a two-integer-digit numeral that represents the whole seconds;
• '.' s+ (if present) represents the fractional seconds;
• zzzzzz (if present) represents the timezone (as described below).
For example, 2002-10-10T12:00:00-05:00 (noon on 10 October 2002, Central Daylight Savings Time as well as Eastern Standard Time in the U.S.) is 2002-10-10T17:00:00Z, five hours later than 2002-10-10T12:00:00Z.
For further guidance on arithmetic with dateTimes and durations, see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>.
3.2.7.2 Canonical representationExcept for trailing fractional zero digits in the seconds representation, '24:00:00' time representations, and timezone (for timezoned values), the mapping from literals to values is one-to-one. Where there is more than one possible representation, the canonical representation is as follows:
• The 2-digit numeral representing the hour must not be '24';
• The fractional second string, if present, must not end in '0';
• for timezoned values, the timezone must be represented with 'Z' (All timezoned dateTime values are UTC.).
3.2.7.3 TimezonesTimezones are durations with (integer-valued) hour and minute properties (with the hour magnitude limited to at most 14, and the minute magnitude limited to at most 59, except that if the hour magnitude is 14, the minute value must be 0); they may be both positive or both negative.
The lexical representation of a timezone is a string of the form: (('+' | '-') hh ':' mm) | 'Z', where
• hh is a two-digit numeral (with leading zeros as required) that represents the hours,
• mm is a two-digit numeral that represents the minutes,
• '+' indicates a nonnegative duration,
• '-' indicates a nonpositive duration.
The mapping so defined is one-to-one, except that '+00:00', '-00:00', and 'Z' all represent the same zero-length duration timezone, UTC; 'Z' is its canonical representation.
When a timezone is added to a UTC dateTime, the result is the date and time "in that timezone". For example, 2002-10-10T12:00:00+05:00 is 2002-10-10T07:00:00Z and 2002-10-10T00:00:00+05:00 is 2002-10-09T19:00:00Z.
3.2.7.4 Order relation on dateTimedateTime value objects on either timeline are totally ordered by their timeOnTimeline values; between the two timelines, dateTime value objects are ordered by their timeOnTimeline values when their timeOnTimeline values differ by more than fourteen hours, with those whose difference is a duration of 14 hours or less being </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-incomparable">·incomparable·</rich_text><rich_text>.
In general, the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-order-relation">·order-relation·</rich_text><rich_text> on dateTime is a partial order since there is no determinate relationship between certain instants. For example, there is no determinate ordering between (a) 2000-01-20T12:00:00 and (b) 2000-01-20T12:00:00Z. Based on timezones currently in use, (c) could vary from 2000-01-20T12:00:00+12:00 to 2000-01-20T12:00:00-13:00. It is, however, possible for this range to expand or contract in the future, based on local laws. Because of this, the following definition uses a somewhat broader range of indeterminate values: +14:00..-14:00.
The following definition uses the notation S[year] to represent the year field of S, S[month] to represent the month field, and so on. The notation (Q & "-14:00") means adding the timezone -14:00 to Q, where Q did not already have a timezone. This is a logical explanation of the process. Actual implementations are free to optimize as long as they produce the same results.
The ordering between two dateTimes P and Q is defined by the following algorithm:
A.Normalize P and Q. That is, if there is a timezone present, but it is not Z, convert it to Z using the addition operation defined in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>
• Thus 2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z
B. If P and Q either both have a time zone or both do not have a time zone, compare P and Q field by field from the year field down to the second field, and return a result as soon as it can be determined. That is:
1. For each i in {year, month, day, hour, minute, second}1. If P[i] and Q[i] are both not specified, continue to the next i
2. If P[i] is not specified and Q[i] is, or vice versa, stop and return P <> Q
3. If P[i] < Q[i], stop and return P < Q
4. If P[i] > Q[i], stop and return P > Q
5. Stop and return P = Q
C.Otherwise, if P contains a time zone and Q does not, compare as follows:
1. P < Q if P < (Q with time zone +14:00)
2. P > Q if P > (Q with time zone -14:00)
3. P <> Q otherwise, that is, if (Q with time zone +14:00) < P < (Q with time zone -14:00)
D. Otherwise, if P does not contain a time zone and Q does, compare as follows:
1. P < Q if (P with time zone -14:00) < Q.
2. P > Q if (P with time zone +14:00) > Q.
3. P <> Q otherwise, that is, if (P with time zone +14:00) < Q < (P with time zone -14:00)
Examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
3.2.7.5 Totally ordered dateTimesCertain derived types from dateTime can be guaranteed have a total order. To do so, they must require that a specific set of fields are always specified, and that remaining fields (if any) are always unspecified. For example, the date datatype without time zone is defined to contain exactly year, month, and day. Thus dates without time zone have a total order among themselves.
3.2.7.6 Constraining facetsdateTime has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text weight="heavy">
</rich_text><rich_text underline="single" weight="heavy">
8. time
</rich_text><rich_text>time represents an instant of time that recurs every day. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of time is the space of time of day values as defined in § 5.3 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Specifically, it is a set of zero-duration daily time instances.
Since the lexical representation allows an optional time zone indicator, time values are partially ordered because it may not be able to determine the order of two values one of which has a time zone and the other does not. The order relation on time values is the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime-order">Order relation on dateTime (§3.2.7.4)</rich_text><rich_text> using an arbitrary date. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>. Pairs of time values with or without time zone indicators are totally ordered.
Note: See the conformance note in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#year-sec-conformance">(§3.2.6)</rich_text><rich_text> which applies to the seconds part of this datatype as well.3.2.8.1 Lexical representationThe lexical representation for time is the left truncated lexical representation for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>: hh:mm:ss.sss with optional following time zone indicator. For example, to indicate 1:20 pm for Eastern Standard Time which is 5 hours behind Coordinated Universal Time (UTC), one would write: 13:20:00-05:00. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats">ISO 8601 Date and Time Formats (§D)</rich_text><rich_text>.
3.2.8.2 Canonical representationThe canonical representation for time is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#time-lexical-repr">Lexical representation (§3.2.8.1)</rich_text><rich_text>. Specifically, either the time zone must be omitted or, if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z". Additionally, the canonical representation for midnight is 00:00:00.
3.2.8.3 Constraining facetstime has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
</rich_text><rich_text underline="single" weight="heavy">
9. date
</rich_text><rich_text>The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of date consists of top-open intervals of exactly one day in length on the timelines of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, beginning on the beginning moment of each day (in each timezone), i.e. '00:00:00', up to but not including '24:00:00' (which is identical with '00:00:00' of the next day). For nontimezoned values, the top-open intervals disjointly cover the nontimezoned timeline, one per day. For timezoned values, the intervals begin at every minute and therefore overlap.
A "date object" is an object with year, month, and day properties just like those of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> objects, plus an optional timezone-valued timezone property. (As with values of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> timezones are a special case of durations.) Just as a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> object corresponds to a point on one of the timelines, a date object corresponds to an interval on one of the two timelines as just described.
Timezoned date values track the starting moment of their day, as determined by their timezone; said timezone is generally recoverable for canonical representations. </rich_text><rich_text foreground="#850021">[Definition:] </rich_text><rich_text>The recoverable timezone is that duration which is the result of subtracting the first moment (or any moment) of the timezoneddate from the first moment (or the corresponding moment) UTC on the same date. </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#recoverable-timezone">·recoverable timezone·</rich_text><rich_text>s are always durations between '+12:00' and '-11:59'. This "timezone normalization" (which follows automatically from the definition of the date </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>) is explained more in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date-lexical-representation">Lexical representation (§3.2.9.1)</rich_text><rich_text>.
For example: the first moment of 2002-10-10+13:00 is 2002-10-10T00:00:00+13, which is 2002-10-09T11:00:00Z, which is also the first moment of 2002-10-09-11:00. Therefore 2002-10-10+13:00 is 2002-10-09-11:00; they are the same interval.
Note: For most timezones, either the first moment or last moment of the day (a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> value, always UTC) will have a date portion different from that of the date itself! However, noon of that date (the midpoint of the interval) in that (normalized) timezone will always have the same date portion as the dateitself, even when that noon point in time is normalized to UTC. For example, 2002-10-10-05:00 begins during 2002-10-09Z and 2002-10-10+05:00 ends during 2002-10-11Z, but noon of both 2002-10-10-05:00 and 2002-10-10+05:00 falls in the interval which is 2002-10-10Z.Note: See the conformance note in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#year-sec-conformance">(§3.2.6)</rich_text><rich_text> which applies to the year part of this datatype as well.3.2.9.1 Lexical representationFor the following discussion, let the "date portion" of a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> or date object be an object similar to a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> or date object, with similar year, month, and day properties, but no others, having the same value for these properties as the original </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> or date object.
The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of date consists of finite-length sequences of characters of the form: '-'? yyyy '-' mm '-' dd zzzzzz? where the date and optional timezone are represented exactly the same way as they are for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>. The first moment of the interval is that represented by: '-' yyyy '-' mm '-' dd 'T00:00:00' zzzzzz? and the least upper bound of the interval is the timeline point represented (noncanonically) by: '-' yyyy '-' mm '-' dd 'T24:00:00' zzzzzz?.
Note: The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#recoverable-timezone">·recoverable timezone·</rich_text><rich_text> of a date will always be a duration between '+12:00' and '11:59'. Timezone lexical representations, as explained for</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>, can range from '+14:00' to '-14:00'. The result is that literals of dates with very large or very negative timezones will map to a "normalized" datevalue with a </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#recoverable-timezone">·recoverable timezone·</rich_text><rich_text> different from that represented in the original representation, and a matching difference of +/- 1 day in the date itself.3.2.9.2 Canonical representationGiven a member of the date </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text>, the date portion of the canonical representation (the entire representation for nontimezoned values, and all but the timezone representation for timezoned values) is always the date portion of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text> canonical representation of the interval midpoint (the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>representation, truncated on the right to eliminate 'T' and all following characters). For timezoned values, append the canonical representation of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#recoverable-timezone">·recoverable timezone·</rich_text><rich_text>.
</rich_text><rich_text underline="single" weight="heavy">
10. gYearMonth
</rich_text><rich_text>gYearMonth represents a specific gregorian month in a specific gregorian year. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of gYearMonth is the set of Gregorian calendar months as defined in § 5.2.1 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Specifically, it is a set of one-month long, non-periodic instances e.g. 1999-10 to represent the whole month of 1999-10, independent of how many days this month has.
Since the lexical representation allows an optional time zone indicator, gYearMonth values are partially ordered because it may not be possible to unequivocally determine the order of two values one of which has a time zone and the other does not. If gYearMonth values are considered as periods of time, the order relation on gYearMonth values is the order relation on their starting instants. This is discussed in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime-order">Order relation on dateTime (§3.2.7.4)</rich_text><rich_text>. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>. Pairs of gYearMonth values with or without time zone indicators are totally ordered.
Note: Because month/year combinations in one calendar only rarely correspond to month/year combinations in other calendars, values of this type are not, in general, convertible to simple values corresponding to month/year combinations in other calendars. This type should therefore be used with caution in contexts where conversion to other calendars is desired.Note: See the conformance note in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#year-sec-conformance">(§3.2.6)</rich_text><rich_text> which applies to the year part of this datatype as well.3.2.10.1 Lexical representationThe lexical representation for gYearMonth is the reduced (right truncated) lexical representation for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>: CCYY-MM. No left truncation is allowed. An optional following time zone qualifier is allowed. To accommodate year values outside the range from 0001 to 9999, additional digits can be added to the left of this representation and a preceding "-" sign is allowed.
For example, to indicate the month of May 1999, one would write: 1999-05. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats">ISO 8601 Date and Time Formats (§D)</rich_text><rich_text>.
3.2.10.2 Constraining facetsgYearMonth has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text underline="single" weight="heavy">
11. gYear
</rich_text><rich_text>gYear represents a gregorian calendar year. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of gYear is the set of Gregorian calendar years as defined in § 5.2.1 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Specifically, it is a set of one-year long, non-periodic instances e.g. lexical 1999 to represent the whole year 1999, independent of how many months and days this year has.
Since the lexical representation allows an optional time zone indicator, gYear values are partially ordered because it may not be possible to unequivocally determine the order of two values one of which has a time zone and the other does not. If gYear values are considered as periods of time, the order relation ongYear values is the order relation on their starting instants. This is discussed in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime-order">Order relation on dateTime (§3.2.7.4)</rich_text><rich_text>. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>. Pairs of gYear values with or without time zone indicators are totally ordered.
Note: Because years in one calendar only rarely correspond to years in other calendars, values of this type are not, in general, convertible to simple values corresponding to years in other calendars. This type should therefore be used with caution in contexts where conversion to other calendars is desired.Note: See the conformance note in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#year-sec-conformance">(§3.2.6)</rich_text><rich_text> which applies to the year part of this datatype as well.3.2.11.1 Lexical representationThe lexical representation for gYear is the reduced (right truncated) lexical representation for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>: CCYY. No left truncation is allowed. An optional following time zone qualifier is allowed as for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime">dateTime</rich_text><rich_text>. To accommodate year values outside the range from 0001 to 9999, additional digits can be added to the left of this representation and a preceding "-" sign is allowed.
For example, to indicate 1999, one would write: 1999. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats">ISO 8601 Date and Time Formats (§D)</rich_text><rich_text>.
3.2.11.2 Constraining facetsgYear has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text underline="single" weight="heavy">
12. gMonthDay
</rich_text><rich_text>gMonthDay is a gregorian date that recurs, specifically a day of the year such as the third of May. Arbitrary recurring dates are not supported by this datatype. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of gMonthDay is the set of calendar dates, as defined in § 3 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Specifically, it is a set of one-day long, annually periodic instances.
Since the lexical representation allows an optional time zone indicator, gMonthDay values are partially ordered because it may not be possible to unequivocally determine the order of two values one of which has a time zone and the other does not. If gMonthDay values are considered as periods of time, in an arbitrary leap year, the order relation on gMonthDay values is the order relation on their starting instants. This is discussed in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime-order">Order relation on dateTime (§3.2.7.4)</rich_text><rich_text>. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>. Pairs of gMonthDay values with or without time zone indicators are totally ordered.
Note: Because day/month combinations in one calendar only rarely correspond to day/month combinations in other calendars, values of this type do not, in general, have any straightforward or intuitive representation in terms of most other calendars. This type should therefore be used with caution in contexts where conversion to other calendars is desired.3.2.12.1 Lexical representationThe lexical representation for gMonthDay is the left truncated lexical representation for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>: --MM-DD. An optional following time zone qualifier is allowed as for</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>. No preceding sign is allowed. No other formats are allowed. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats">ISO 8601 Date and Time Formats (§D)</rich_text><rich_text>.
This datatype can be used to represent a specific day in a month. To say, for example, that my birthday occurs on the 14th of September ever year.
3.2.12.2 Constraining facetsgMonthDay has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text underline="single" weight="heavy">
13. gDay
</rich_text><rich_text>gDay is a gregorian day that recurs, specifically a day of the month such as the 5th of the month. Arbitrary recurring days are not supported by this datatype. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of gDay is the space of a set of calendar dates as defined in § 3 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Specifically, it is a set of one-day long, monthly periodic instances.
This datatype can be used to represent a specific day of the month. To say, for example, that I get my paycheck on the 15th of each month.
Since the lexical representation allows an optional time zone indicator, gDay values are partially ordered because it may not be possible to unequivocally determine the order of two values one of which has a time zone and the other does not. If gDay values are considered as periods of time, in an arbitrary month that has 31 days, the order relation on gDay values is the order relation on their starting instants. This is discussed in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime-order">Order relation on dateTime (§3.2.7.4)</rich_text><rich_text>. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>. Pairs of gDay values with or without time zone indicators are totally ordered.
Note: Because days in one calendar only rarely correspond to days in other calendars, values of this type do not, in general, have any straightforward or intuitive representation in terms of most other calendars. This type should therefore be used with caution in contexts where conversion to other calendars is desired.3.2.13.1 Lexical representationThe lexical representation for gDay is the left truncated lexical representation for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>: ---DD . An optional following time zone qualifier is allowed as for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>. No preceding sign is allowed. No other formats are allowed. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats">ISO 8601 Date and Time Formats (§D)</rich_text><rich_text>.
3.2.13.2 Constraining facetsgDay has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text underline="single" weight="heavy">
14. gMonth
</rich_text><rich_text>gMonth is a gregorian month that recurs every year. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of gMonth is the space of a set of calendar months as defined in § 3 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ISO8601">[ISO 8601]</rich_text><rich_text>. Specifically, it is a set of one-month long, yearly periodic instances.
This datatype can be used to represent a specific month. To say, for example, that Thanksgiving falls in the month of November.
Since the lexical representation allows an optional time zone indicator, gMonth values are partially ordered because it may not be possible to unequivocally determine the order of two values one of which has a time zone and the other does not. If gMonth values are considered as periods of time, the order relation ongMonth is the order relation on their starting instants. This is discussed in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dateTime-order">Order relation on dateTime (§3.2.7.4)</rich_text><rich_text>. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#adding-durations-to-dateTimes">Adding durations to dateTimes (§E)</rich_text><rich_text>. Pairs of gMonth values with or without time zone indicators are totally ordered.
Note: Because months in one calendar only rarely correspond to months in other calendars, values of this type do not, in general, have any straightforward or intuitive representation in terms of most other calendars. This type should therefore be used with caution in contexts where conversion to other calendars is desired.3.2.14.1 Lexical representationThe lexical representation for gMonth is the left and right truncated lexical representation for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>: --MM. An optional following time zone qualifier is allowed as for</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#date">date</rich_text><rich_text>. No preceding sign is allowed. No other formats are allowed. See also </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#isoformats">ISO 8601 Date and Time Formats (§D)</rich_text><rich_text>.
3.2.14.2 Constraining facetsgMonth has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><table char_offset="14874" col_max="500" col_min="40"><row><cell>2000-01-15T00:00:00 < 2000-02-15T00:00:00</cell><cell>2000-01-01T12:00:00 <> 1999-12-31T23:00:00Z</cell></row><row><cell>2000-01-15T12:00:00 < 2000-01-16T12:00:00Z</cell><cell>2000-01-16T12:00:00 <> 2000-01-16T12:00:00Z</cell></row><row><cell> </cell><cell>2000-01-16T00:00:00 <> 2000-01-16T12:00:00Z</cell></row><row><cell>Determinate</cell><cell>Indeterminate</cell></row></table></node><node name="Binary Data" prog_lang="custom-colors" readonly="False" tags="" unique_id="53"><rich_text underline="single">15. </rich_text><rich_text underline="single" weight="heavy">hexBinary</rich_text><rich_text>
hexBinary represents arbitrary hex-encoded binary data. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of hexBinary is the set of finite-length sequences of binary octets.
3.2.15.1 Lexical RepresentationhexBinary has a lexical representation where each binary octet is encoded as a character tuple, consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code. For example, "0FB7" is a hex encoding for the 16-bit integer 4023 (whose binary representation is 111110110111).
3.2.15.2 Canonical RepresentationThe canonical representation for hexBinary is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#hexBinary-lexical-representation">Lexical Representation (§3.2.15.1)</rich_text><rich_text>. Specifically, the lower case hexadecimal digits ([a-f]) are not allowed.
3.2.15.3 Constraining facetshexBinary has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text weight="heavy">
</rich_text><rich_text underline="single" weight="heavy">
16. base64Binary
</rich_text><rich_text>[Definition:] </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> represents Base64-encoded arbitrary binary data. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> is the set of finite-length sequences of binary octets. For </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> data the entire binary stream is encoded using the Base64 Alphabet in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2045">[RFC 2045]</rich_text><rich_text>.
The lexical forms of </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> values are limited to the 65 characters of the Base64 Alphabet defined in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2045">[RFC 2045]</rich_text><rich_text>, i.e., a-z, A-Z, 0-9, the plus sign (+), the forward slash (/) and the equal sign (=), together with the characters defined in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text> as white space. No other characters are allowed.
For compatibility with older mail gateways, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2045">[RFC 2045]</rich_text><rich_text> suggests that base64 data should have lines limited to at most 76 characters in length. This line-length limitation is not mandated in the lexical forms of </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> data and must not be enforced by XML Schema processors.
The lexical space of </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> is given by the following grammar (the notation is that used in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>); legal lexical forms must match the</rich_text><rich_text weight="heavy">Base64Binary</rich_text><rich_text> production.
Base64Binary ::= ((B64S B64S B64S B64S)*
((B64S B64S B64S B64) |
(B64S B64S B16S '=') |
(B64S B04S '=' #x20? '=')))?
B64S ::= B64 #x20?
B16S ::= B16 #x20?
B04S ::= B04 #x20?
B04 ::= [AQgw]
B16 ::= [AEIMQUYcgkosw048]
B64 ::= [A-Za-z0-9+/]
Note that this grammar requires the number of non-whitespace characters in the lexical form to be a multiple of four, and for equals signs to appear only at the end of the lexical form; strings which do not meet these constraints are not legal lexical forms of </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> because they cannot successfully be decoded by base64 decoders.
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text>The above definition of the lexical space is more restrictive than that given in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2045">[RFC 2045]</rich_text><rich_text> as regards whitespace -- this is not an issue in practice. Any string compatible with the RFC can occur in an element or attribute validated by this type, because the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-whiteSpace">·whiteSpace·</rich_text><rich_text> facet of this type is fixed to </rich_text><rich_text style="italic">collapse</rich_text><rich_text>, which means that all leading and trailing whitespace will be stripped, and all internal whitespace collapsed to single space characters, before the above grammar is enforced.The canonical lexical form of a </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> data value is the base64 encoding of the value which matches the Canonical-base64Binary production in the following grammar:
Canonical-base64Binary ::= (B64 B64 B64 B64)*
((B64 B64 B16 '=') | (B64 B04 '=='))?
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text>For some values the canonical form defined above does not conform to </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2045">[RFC 2045]</rich_text><rich_text>, which requires breaking with linefeeds at appropriate intervals.The length of a </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> value is the number of octets it contains. This may be calculated from the lexical form by removing whitespace and padding characters and performing the calculation shown in the pseudo-code below:
lex2 := killwhitespace(lexform) -- remove whitespace characters
lex3 := strip_equals(lex2) -- strip padding characters at end
length := floor (length(lex3) * 3 / 4) -- calculate length
Note on encoding: </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2045">[RFC 2045]</rich_text><rich_text> explicitly references US-ASCII encoding. However, decoding of </rich_text><rich_text weight="heavy">base64Binary</rich_text><rich_text> data in an XML entity is to be performed on the Unicode characters obtained after character encoding processing as specified by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>
3.2.16.1 Constraining facetsbase64Binary has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
</rich_text></node><node name="Identifiers" prog_lang="custom-colors" readonly="False" tags="" unique_id="54"><rich_text underline="single" weight="heavy">17. anyURI</rich_text><rich_text>
anyURI represents a Uniform Resource Identifier Reference (URI). An anyURI value can be absolute or relative, and may have an optional fragment identifier (i.e., it may be a URI Reference). This type should be used to specify the intention that the value fulfills the role of a URI as defined by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2396">[RFC 2396]</rich_text><rich_text>, as amended by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2732">[RFC 2732]</rich_text><rich_text>.
The mapping from anyURI values to URIs is as defined by the URI reference escaping procedure defined in Section 5.4 </rich_text><rich_text link="webs http://www.w3.org/TR/2001/REC-xlink-20010627/#link-locators">Locator Attribute</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XLink">[XML Linking Language]</rich_text><rich_text> (see also Section 8 </rich_text><rich_text link="webs http://www.w3.org/TR/2001/WD-charmod-20010126/#sec-URIs">Character Encoding in URI References</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#CharMod">[Character Model]</rich_text><rich_text>). This means that a wide range of internationalized resource identifiers can be specified when an anyURI is called for, and still be understood as URIs per </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2396">[RFC 2396]</rich_text><rich_text>, as amended by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2732">[RFC 2732]</rich_text><rich_text>, where appropriate to identify resources.
Note: Section 5.4 </rich_text><rich_text link="webs http://www.w3.org/TR/2001/REC-xlink-20010627/#link-locators">Locator Attribute</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XLink">[XML Linking Language]</rich_text><rich_text> requires that relative URI references be absolutized as defined in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XBase">[XML Base]</rich_text><rich_text> before use. This is an XLink-specific requirement and is not appropriate for XML Schema, since neither the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> nor the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#anyURI">anyURI</rich_text><rich_text> type are restricted to absolute URIs. Accordingly absolutization must not be performed by schema processors as part of schema validation.Note: Each URI scheme imposes specialized syntax rules for URIs in that scheme, including restrictions on the syntax of allowed fragment identifiers. Because it is impractical for processors to check that a value is a context-appropriate URI reference, this specification follows the lead of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2396">[RFC 2396]</rich_text><rich_text> (as amended by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2732">[RFC 2732]</rich_text><rich_text>) in this matter: such rules and restrictions are not part of type validity and are not checked by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minimally-conforming">·minimally conforming·</rich_text><rich_text> processors. Thus in practice the above definition imposes only very modest obligations on </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minimally-conforming">·minimally conforming·</rich_text><rich_text> processors.3.2.17.1 Lexical representationThe </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of anyURI is finite-length character sequences which, when the algorithm defined in Section 5.4 of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XLink">[XML Linking Language]</rich_text><rich_text> is applied to them, result in strings which are legal URIs according to </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2396">[RFC 2396]</rich_text><rich_text>, as amended by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC2732">[RFC 2732]</rich_text><rich_text>.
Note: Spaces are, in principle, allowed in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of anyURI, however, their use is highly discouraged (unless they are encoded by %20).3.2.17.2 Constraining facetsanyURI has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text weight="heavy">
</rich_text><rich_text underline="single" weight="heavy">
18. QName
</rich_text><rich_text>QName represents </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-qname">XML qualified names</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of QName is the set of tuples {</rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-NSName">namespace name</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-localname">local part</rich_text><rich_text>}, where </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-NSName">namespace name</rich_text><rich_text> is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#anyURI">anyURI</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-localname">local part</rich_text><rich_text> is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of QName is the set of strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName">QName</rich_text><rich_text> production of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>.
Note: The mapping between literals in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> and values in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of QName requires a namespace declaration to be in scope for the context in which QName is used.3.2.18.1 Constraining facetsQName has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
The use of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-length">·length·</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minLength">·minLength·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxLength">·maxLength·</rich_text><rich_text> on datatypes </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text> is deprecated. Future versions of this specification may remove these facets for this datatype.</rich_text><rich_text underline="single" weight="heavy">
19. NOTATION</rich_text><rich_text>
</rich_text><rich_text weight="heavy">NOTATION</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-NotationType">NOTATION</rich_text><rich_text> attribute type from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NOTATION</rich_text><rich_text> is the set of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text>s of notations declared in the current schema. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NOTATION</rich_text><rich_text> is the set of all names of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#declare-notation">notations</rich_text><rich_text> declared in the current schema (in the form of</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#QName">QName</rich_text><rich_text>s).
</rich_text><rich_text weight="heavy">Schema Component Constraint: enumeration facet value required for NOTATION</rich_text><rich_text>
It is an </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-error">·error·</rich_text><rich_text> for </rich_text><rich_text weight="heavy">NOTATION</rich_text><rich_text> to be used directly in a schema. Only datatypes that are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text weight="heavy">NOTATION</rich_text><rich_text> by specifying a value for </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-enumeration">·enumeration·</rich_text><rich_text> can be used in a schema.For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">NOTATION</rich_text><rich_text> should be used only on attributes and should only be used in schemas with no target namespace.
3.2.19.1 Constraining facetsNOTATION has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
The use of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-length">·length·</rich_text><rich_text>, </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minLength">·minLength·</rich_text><rich_text> and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxLength">·maxLength·</rich_text><rich_text> on datatypes </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NOTATION">NOTATION</rich_text><rich_text> is deprecated. Future versions of this specification may remove these facets for this datatype.</rich_text></node></node><node name="Notes and Plans" prog_lang="custom-colors" readonly="False" tags="" unique_id="41"><rich_text>Under this page I collect ideas, notes and thoughts I have while writing the draft.</rich_text></node></node><node name="Derived Types" prog_lang="custom-colors" readonly="False" tags="" unique_id="55"><rich_text></rich_text><node name="Derived Types Draft" prog_lang="custom-colors" readonly="False" tags="" unique_id="56"><rich_text>3.3.1 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#normalizedString">normalizedString</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.2 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#token">token</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.3 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#language">language</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.4 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NMTOKEN">NMTOKEN</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.5 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NMTOKENS">NMTOKENS</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.6 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#Name">Name</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.7 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.8 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID">ID</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.9 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREF">IDREF</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.10 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREFS">IDREFS</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.11 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ENTITY">ENTITY</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.12 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ENTITIES">ENTITIES</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.13 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.14 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonPositiveInteger">nonPositiveInteger</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.15 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#negativeInteger">negativeInteger</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.16 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#long">long</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.17 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#int">int</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.18 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#short">short</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.19 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#byte">byte</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.20 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger">nonNegativeInteger</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.21 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedLong">unsignedLong</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.22 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedInt">unsignedInt</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.23 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedShort">unsignedShort</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.24 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedByte">unsignedByte</rich_text><rich_text>
</rich_text><rich_text foreground="#000000"> 3.3.25 </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#positiveInteger">positiveInteger</rich_text><rich_text>
This section gives conceptual definitions for all </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> datatypes defined by this specification. The XML representation used to define </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text>datatypes (whether </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> or </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-user-derived">·user-derived·</rich_text><rich_text>) is given in section </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#xr-defn">XML Representation of Simple Type Definition Schema Components (§4.1.2)</rich_text><rich_text> and the complete definitions of the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> datatypes are provided in Appendix A </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#schema">Schema for Datatype Definitions (normative) (§A)</rich_text><rich_text>.
3.3.1 normalizedString[Definition:] </rich_text><rich_text weight="heavy">normalizedString</rich_text><rich_text> represents white space normalized strings. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">normalizedString</rich_text><rich_text> is the set of strings that do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">normalizedString</rich_text><rich_text> is the set of strings that do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">normalizedString</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#string">string</rich_text><rich_text>.
3.3.1.1 Constraining facetsnormalizedString has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.1.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from normalizedString:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#token">token</rich_text><rich_text>
3.3.2 token[Definition:] </rich_text><rich_text weight="heavy">token</rich_text><rich_text> represents tokenized strings. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">token</rich_text><rich_text> is the set of strings that do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters, that have no leading or trailing spaces (#x20) and that have no internal sequences of two or more spaces. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">token</rich_text><rich_text>is the set of strings that do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters, that have no leading or trailing spaces (#x20) and that have no internal sequences of two or more spaces. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">token</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#normalizedString">normalizedString</rich_text><rich_text>.
3.3.2.1 Constraining facetstoken has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.2.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from token:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#language">language</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NMTOKEN">NMTOKEN</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#Name">Name</rich_text><rich_text>
3.3.3 language[Definition:] </rich_text><rich_text weight="heavy">language</rich_text><rich_text> represents natural language identifiers as defined by by </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC3066">[RFC 3066]</rich_text><rich_text> . The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">language</rich_text><rich_text> is the set of all strings that are valid language identifiers as defined </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#RFC3066">[RFC 3066]</rich_text><rich_text> . The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">language</rich_text><rich_text> is the set of all strings that conform to the pattern [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})* . The</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">language</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#token">token</rich_text><rich_text>.
3.3.3.1 Constraining facetslanguage has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.4 NMTOKEN[Definition:] </rich_text><rich_text weight="heavy">NMTOKEN</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">NMTOKEN attribute type</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NMTOKEN</rich_text><rich_text> is the set of tokens that</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken">Nmtoken</rich_text><rich_text> production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NMTOKEN</rich_text><rich_text> is the set of strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Nmtoken">Nmtoken</rich_text><rich_text> production in</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NMTOKEN</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#token">token</rich_text><rich_text>.
For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">NMTOKEN</rich_text><rich_text> should be used only on attributes.
3.3.4.1 Constraining facetsNMTOKEN has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.4.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from NMTOKEN:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NMTOKENS">NMTOKENS</rich_text><rich_text>
3.3.5 NMTOKENS[Definition:] </rich_text><rich_text weight="heavy">NMTOKENS</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">NMTOKENS attribute type</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NMTOKENS</rich_text><rich_text> is the set of finite, non-zero-length sequences of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-NMTOKEN">·NMTOKEN·</rich_text><rich_text>s. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NMTOKENS</rich_text><rich_text> is the set of space-separated lists of tokens, of which each token is in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NMTOKEN">NMTOKEN</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NMTOKENS</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NMTOKEN">NMTOKEN</rich_text><rich_text>.
For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">NMTOKENS</rich_text><rich_text> should be used only on attributes.
3.3.5.1 Constraining facetsNMTOKENS has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
3.3.6 Name[Definition:] </rich_text><rich_text weight="heavy">Name</rich_text><rich_text> represents </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-name">XML Names</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">Name</rich_text><rich_text> is the set of all strings which </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Name">Name</rich_text><rich_text> production of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">Name</rich_text><rich_text> is the set of all strings which </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Name">Name</rich_text><rich_text> production of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">Name</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#token">token</rich_text><rich_text>.
3.3.6.1 Constraining facetsName has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.6.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from Name:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>
3.3.7 NCName[Definition:] </rich_text><rich_text weight="heavy">NCName</rich_text><rich_text> represents XML "non-colonized" Names. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NCName</rich_text><rich_text> is the set of all strings which </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production of</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">NCName</rich_text><rich_text> is the set of all strings which </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of</rich_text><rich_text weight="heavy">NCName</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#Name">Name</rich_text><rich_text>.
3.3.7.1 Constraining facetsNCName has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.7.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from NCName:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ID">ID</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREF">IDREF</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ENTITY">ENTITY</rich_text><rich_text>
3.3.8 ID[Definition:] </rich_text><rich_text weight="heavy">ID</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">ID attribute type</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ID</rich_text><rich_text> is the set of all strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text>production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ID</rich_text><rich_text> is the set of all strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text>of </rich_text><rich_text weight="heavy">ID</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>.
For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">ID</rich_text><rich_text> should be used only on attributes.
3.3.8.1 Constraining facetsID has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.9 IDREF[Definition:] </rich_text><rich_text weight="heavy">IDREF</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">IDREF attribute type</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">IDREF</rich_text><rich_text> is the set of all strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the</rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">IDREF</rich_text><rich_text> is the set of strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">IDREF</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>.
For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) this datatype should be used only on attributes.
3.3.9.1 Constraining facetsIDREF has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.9.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from IDREF:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREFS">IDREFS</rich_text><rich_text>
3.3.10 IDREFS[Definition:] </rich_text><rich_text weight="heavy">IDREFS</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">IDREFS attribute type</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">IDREFS</rich_text><rich_text> is the set of finite, non-zero-length sequences of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREF">IDREF</rich_text><rich_text>s. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">IDREFS</rich_text><rich_text> is the set of space-separated lists of tokens, of which each token is in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREF">IDREF</rich_text><rich_text>. The</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">IDREFS</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#IDREF">IDREF</rich_text><rich_text>.
For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">IDREFS</rich_text><rich_text> should be used only on attributes.
3.3.10.1 Constraining facetsIDREFS has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
3.3.11 ENTITY[Definition:] </rich_text><rich_text weight="heavy">ENTITY</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">ENTITY</rich_text><rich_text> attribute type from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITY</rich_text><rich_text> is the set of all strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the</rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text> and have been declared as an </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-unparsed">unparsed entity</rich_text><rich_text> in a </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-doctype">document type definition</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITY</rich_text><rich_text> is the set of all strings that </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-match">·match·</rich_text><rich_text> the </rich_text><rich_text link="webs http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName">NCName</rich_text><rich_text> production in </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XMLNS">[Namespaces in XML]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITY</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#NCName">NCName</rich_text><rich_text>.
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITY</rich_text><rich_text> is scoped to a specific instance document.For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">ENTITY</rich_text><rich_text> should be used only on attributes.
3.3.11.1 Constraining facetsENTITY has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
3.3.11.2 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from ENTITY:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ENTITIES">ENTITIES</rich_text><rich_text>
3.3.12 ENTITIES[Definition:] </rich_text><rich_text weight="heavy">ENTITIES</rich_text><rich_text> represents the </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-TokenizedType">ENTITIES attribute type</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#XML">[XML 1.0 (Second Edition)]</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITIES</rich_text><rich_text> is the set of finite, non-zero-length sequences of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-ENTITY">·ENTITY·</rich_text><rich_text>s that have been declared as </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-unparsed">unparsed entities</rich_text><rich_text> in a </rich_text><rich_text link="webs http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-doctype">document type definition</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITIES</rich_text><rich_text> is the set of space-separated lists of tokens, of which each token is in the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-lexical-space">·lexical space·</rich_text><rich_text> of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ENTITY">ENTITY</rich_text><rich_text>. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-itemType">·itemType·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITIES</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#ENTITY">ENTITY</rich_text><rich_text>.
</rich_text><rich_text weight="heavy">Note: </rich_text><rich_text> The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">ENTITIES</rich_text><rich_text> is scoped to a specific instance document.For compatibility (see </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#terminology">Terminology (§1.4)</rich_text><rich_text>) </rich_text><rich_text weight="heavy">ENTITIES</rich_text><rich_text> should be used only on attributes.
3.3.12.1 Constraining facetsENTITIES has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-length">length</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minLength">minLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxLength">maxLength</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
3.3.13 integer[Definition:] </rich_text><rich_text weight="heavy">integer</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#decimal">decimal</rich_text><rich_text> by fixing the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-fractionDigits">·fractionDigits·</rich_text><rich_text> to be 0and disallowing the trailing decimal point. This results in the standard mathematical concept of the integer numbers. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">integer</rich_text><rich_text> is the infinite set {...,-2,-1,0,1,2,...}. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">integer</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#decimal">decimal</rich_text><rich_text>.
3.3.13.1 Lexical representation</rich_text><rich_text weight="heavy">integer</rich_text><rich_text> has a lexical representation consisting of a finite-length sequence of decimal digits (#x30-#x39) with an optional leading sign. If the sign is omitted, "+" is assumed. For example: -1, 0, 12678967543233, +100000.
3.3.13.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">integer</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer-lexical-representation">Lexical representation (§3.3.13.1)</rich_text><rich_text>. Specifically, the preceding optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.13.3 Constraining facetsinteger has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.13.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from integer:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonPositiveInteger">nonPositiveInteger</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#long">long</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger">nonNegativeInteger</rich_text><rich_text>
3.3.14 nonPositiveInteger[Definition:] </rich_text><rich_text weight="heavy">nonPositiveInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 0. This results in the standard mathematical concept of the non-positive integers. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">nonPositiveInteger</rich_text><rich_text> is the infinite set {...,-2,-1,0}. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">nonPositiveInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text>.
3.3.14.1 Lexical representation</rich_text><rich_text weight="heavy">nonPositiveInteger</rich_text><rich_text> has a lexical representation consisting of an optional preceding sign followed by a finite-length sequence of decimal digits (#x30-#x39). The sign may be "+" or may be omitted only for lexical forms denoting zero; in all other lexical forms, the negative sign ("-") must be present. For example: -1, 0, -12678967543233, -100000.
3.3.14.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">nonPositiveInteger</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonPositiveInteger-lexical-representation">Lexical representation (§3.3.14.1)</rich_text><rich_text>. In the canonical form for zero, the sign must be omitted. Leading zeroes are prohibited.
3.3.14.3 Constraining facetsnonPositiveInteger has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.14.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from nonPositiveInteger:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#negativeInteger">negativeInteger</rich_text><rich_text>
3.3.15 negativeInteger[Definition:] </rich_text><rich_text weight="heavy">negativeInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonPositiveInteger">nonPositiveInteger</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be -1. This results in the standard mathematical concept of the negative integers. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">negativeInteger</rich_text><rich_text> is the infinite set {...,-2,-1}. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">negativeInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonPositiveInteger">nonPositiveInteger</rich_text><rich_text>.
3.3.15.1 Lexical representation</rich_text><rich_text weight="heavy">negativeInteger</rich_text><rich_text> has a lexical representation consisting of a negative sign ("-") followed by a finite-length sequence of decimal digits (#x30-#x39). For example: -1, -12678967543233, -100000.
3.3.15.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">negativeInteger</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#negativeInteger-lexical-representation">Lexical representation (§3.3.15.1)</rich_text><rich_text>. Specifically, leading zeroes are prohibited.
3.3.15.3 Constraining facetsnegativeInteger has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.16 long[Definition:] </rich_text><rich_text weight="heavy">long</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 9223372036854775807 and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minInclusive">·minInclusive·</rich_text><rich_text> to be -9223372036854775808. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">long</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text>.
3.3.16.1 Lexical representation</rich_text><rich_text weight="heavy">long</rich_text><rich_text> has a lexical representation consisting of an optional sign followed by a finite-length sequence of decimal digits (#x30-#x39). If the sign is omitted, "+" is assumed. For example: -1, 0, 12678967543233, +100000.
3.3.16.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">long</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#long-lexical-representation">Lexical representation (§3.3.16.1)</rich_text><rich_text>. Specifically, the the optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.16.3 Constraining facetslong has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.16.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from long:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#int">int</rich_text><rich_text>
3.3.17 int[Definition:] </rich_text><rich_text weight="heavy">int</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#long">long</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 2147483647 and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minInclusive">·minInclusive·</rich_text><rich_text> to be -2147483648. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">int</rich_text><rich_text> is</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#long">long</rich_text><rich_text>.
3.3.17.1 Lexical representation</rich_text><rich_text weight="heavy">int</rich_text><rich_text> has a lexical representation consisting of an optional sign followed by a finite-length sequence of decimal digits (#x30-#x39). If the sign is omitted, "+" is assumed. For example: -1, 0, 126789675, +100000.
3.3.17.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">int</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#int-lexical-representation">Lexical representation (§3.3.17.1)</rich_text><rich_text>. Specifically, the the optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.17.3 Constraining facetsint has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.17.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from int:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#short">short</rich_text><rich_text>
3.3.18 short[Definition:] </rich_text><rich_text weight="heavy">short</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#int">int</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 32767 and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minInclusive">·minInclusive·</rich_text><rich_text> to be -32768. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">short</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#int">int</rich_text><rich_text>.
3.3.18.1 Lexical representation</rich_text><rich_text weight="heavy">short</rich_text><rich_text> has a lexical representation consisting of an optional sign followed by a finite-length sequence of decimal digits (#x30-#x39). If the sign is omitted, "+" is assumed. For example: -1, 0, 12678, +10000.
3.3.18.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">short</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#short-lexical-representation">Lexical representation (§3.3.18.1)</rich_text><rich_text>. Specifically, the the optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.18.3 Constraining facetsshort has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.18.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from short:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#byte">byte</rich_text><rich_text>
3.3.19 byte[Definition:] </rich_text><rich_text weight="heavy">byte</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#short">short</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 127 and </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minInclusive">·minInclusive·</rich_text><rich_text> to be -128. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">byte</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#short">short</rich_text><rich_text>.
3.3.19.1 Lexical representation</rich_text><rich_text weight="heavy">byte</rich_text><rich_text> has a lexical representation consisting of an optional sign followed by a finite-length sequence of decimal digits (#x30-#x39). If the sign is omitted, "+" is assumed. For example: -1, 0, 126, +100.
3.3.19.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">byte</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#byte-lexical-representation">Lexical representation (§3.3.19.1)</rich_text><rich_text>. Specifically, the the optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.19.3 Constraining facetsbyte has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.20 nonNegativeInteger[Definition:] </rich_text><rich_text weight="heavy">nonNegativeInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minInclusive">·minInclusive·</rich_text><rich_text> to be 0. This results in the standard mathematical concept of the non-negative integers. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">nonNegativeInteger</rich_text><rich_text> is the infinite set {0,1,2,...}. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">nonNegativeInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#integer">integer</rich_text><rich_text>.
3.3.20.1 Lexical representation</rich_text><rich_text weight="heavy">nonNegativeInteger</rich_text><rich_text> has a lexical representation consisting of an optional sign followed by a finite-length sequence of decimal digits (#x30-#x39). If the sign is omitted, the positive sign ("+") is assumed. If the sign is present, it must be "+" except for lexical forms denoting zero, which may be preceded by a positive ("+") or a negative ("-") sign. For example: 1, 0, 12678967543233, +100000.
3.3.20.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">nonNegativeInteger</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger-lexical-representation">Lexical representation (§3.3.20.1)</rich_text><rich_text>. Specifically, the the optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.20.3 Constraining facetsnonNegativeInteger has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.20.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from nonNegativeInteger:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedLong">unsignedLong</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#positiveInteger">positiveInteger</rich_text><rich_text>
3.3.21 unsignedLong[Definition:] </rich_text><rich_text weight="heavy">unsignedLong</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger">nonNegativeInteger</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 18446744073709551615. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of</rich_text><rich_text weight="heavy">unsignedLong</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger">nonNegativeInteger</rich_text><rich_text>.
3.3.21.1 Lexical representation</rich_text><rich_text weight="heavy">unsignedLong</rich_text><rich_text> has a lexical representation consisting of a finite-length sequence of decimal digits (#x30-#x39). For example: 0, 12678967543233, 100000.
3.3.21.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">unsignedLong</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedLong-lexical-representation">Lexical representation (§3.3.21.1)</rich_text><rich_text>. Specifically, leading zeroes are prohibited.
3.3.21.3 Constraining facetsunsignedLong has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.21.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from unsignedLong:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedInt">unsignedInt</rich_text><rich_text>
3.3.22 unsignedInt[Definition:] </rich_text><rich_text weight="heavy">unsignedInt</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedLong">unsignedLong</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 4294967295. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">unsignedInt</rich_text><rich_text> is</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedLong">unsignedLong</rich_text><rich_text>.
3.3.22.1 Lexical representation</rich_text><rich_text weight="heavy">unsignedInt</rich_text><rich_text> has a lexical representation consisting of a finite-length sequence of decimal digits (#x30-#x39). For example: 0, 1267896754, 100000.
3.3.22.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">unsignedInt</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedInt-lexical-representation">Lexical representation (§3.3.22.1)</rich_text><rich_text>. Specifically, leading zeroes are prohibited.
3.3.22.3 Constraining facetsunsignedInt has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.22.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from unsignedInt:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedShort">unsignedShort</rich_text><rich_text>
3.3.23 unsignedShort[Definition:] </rich_text><rich_text weight="heavy">unsignedShort</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedInt">unsignedInt</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 65535. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">unsignedShort</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedInt">unsignedInt</rich_text><rich_text>.
3.3.23.1 Lexical representation</rich_text><rich_text weight="heavy">unsignedShort</rich_text><rich_text> has a lexical representation consisting of a finite-length sequence of decimal digits (#x30-#x39). For example: 0, 12678, 10000.
3.3.23.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">unsignedShort</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedShort-lexical-representation">Lexical representation (§3.3.23.1)</rich_text><rich_text>. Specifically, the leading zeroes are prohibited.
3.3.23.3 Constraining facetsunsignedShort has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.23.4 Derived datatypesThe following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-built-in">·built-in·</rich_text><rich_text> datatypes are </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from unsignedShort:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedByte">unsignedByte</rich_text><rich_text>
3.3.24 unsignedByte[Definition:] </rich_text><rich_text weight="heavy">unsignedByte</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedShort">unsignedShort</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-maxInclusive">·maxInclusive·</rich_text><rich_text> to be 255. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">unsignedByte</rich_text><rich_text> is</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedShort">unsignedShort</rich_text><rich_text>.
3.3.24.1 Lexical representation</rich_text><rich_text weight="heavy">unsignedByte</rich_text><rich_text> has a lexical representation consisting of a finite-length sequence of decimal digits (#x30-#x39). For example: 0, 126, 100.
3.3.24.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">unsignedByte</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#unsignedByte-lexical-representation">Lexical representation (§3.3.24.1)</rich_text><rich_text>. Specifically, leading zeroes are prohibited.
3.3.24.3 Constraining facetsunsignedByte has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
3.3.25 positiveInteger[Definition:] </rich_text><rich_text weight="heavy">positiveInteger</rich_text><rich_text> is </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-derived">·derived·</rich_text><rich_text> from </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger">nonNegativeInteger</rich_text><rich_text> by setting the value of </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-minInclusive">·minInclusive·</rich_text><rich_text> to be 1. This results in the standard mathematical concept of the positive integer numbers. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-value-space">·value space·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">positiveInteger</rich_text><rich_text> is the infinite set {1,2,...}. The </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-basetype">·base type·</rich_text><rich_text> of </rich_text><rich_text weight="heavy">positiveInteger</rich_text><rich_text> is</rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#nonNegativeInteger">nonNegativeInteger</rich_text><rich_text>.
3.3.25.1 Lexical representation</rich_text><rich_text weight="heavy">positiveInteger</rich_text><rich_text> has a lexical representation consisting of an optional positive sign ("+") followed by a finite-length sequence of decimal digits (#x30-#x39). For example: 1, 12678967543233, +100000.
3.3.25.2 Canonical representationThe canonical representation for </rich_text><rich_text weight="heavy">positiveInteger</rich_text><rich_text> is defined by prohibiting certain options from the </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#positiveInteger-lexical-representation">Lexical representation (§3.3.25.1)</rich_text><rich_text>. Specifically, the optional "+" sign is prohibited and leading zeroes are prohibited.
3.3.25.3 Constraining facetspositiveInteger has the following </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#dt-constraining-facet">·constraining facets·</rich_text><rich_text>:
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-totalDigits">totalDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-fractionDigits">fractionDigits</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-pattern">pattern</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-whiteSpace">whiteSpace</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-enumeration">enumeration</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxInclusive">maxInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-maxExclusive">maxExclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minInclusive">minInclusive</rich_text><rich_text>
• </rich_text><rich_text link="webs http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/datatypes.html#rf-minExclusive">minExclusive</rich_text><rich_text>
</rich_text></node></node><node name="Workspace" prog_lang="custom-colors" readonly="False" tags="" unique_id="99"><rich_text></rich_text><node name="Issues" prog_lang="custom-colors" readonly="False" tags="" unique_id="18"><rich_text>Here I'll be planning syntactic aspects of the language and defining rules. I'm not an expert and I don't have any theoretical knowledge of how languages are designed, but I can think of issues and aspects and design related language features and rules. Later maybe I'll read about languages and language design in Wikipedia and use the theoretical foundations here too.
This page explains the status markers given to syntax issues: </rich_text><rich_text link="node 21">Status Markers</rich_text><rich_text>.
When I read more about language design, I'll probably be able to group these issues using some kind of categories, but for now I'll just write them in a list.
</rich_text><rich_text link="node 19">Statements and Semicolons</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 62">Structure</rich_text><rich_text>
</rich_text><rich_text link="node 20">Indentation and Blocks</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 63">Lines</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 22">Keywords</rich_text><rich_text>
</rich_text><rich_text link="node 38">Case of Keywords</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 39">Null Object</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 40">Boolean Values</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 48">Definition Keywords</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 31">Type Names</rich_text><rich_text>
</rich_text><rich_text link="node 36">Word Combination</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 43">Set Definition</rich_text><rich_text>
</rich_text><rich_text link="node 44">Abstract Set Definition</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 100">Fields</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 45">Explicit Set Definition</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 107">Set-Builder Notation</rich_text><rich_text> </rich_text><rich_text foreground="#ffff52525457">TODO</rich_text><rich_text>
</rich_text><rich_text link="node 46 Explicit Definition">Primitive Type Definition</rich_text><rich_text>
</rich_text><rich_text link="node 47">The Mapping Function</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 105">Prototypes</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 94">Mathematical Notation</rich_text><rich_text>
</rich_text><rich_text link="node 96">Sets, Lists, Sequences and Tuples</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 95">Relations of Size 3 and More</rich_text><rich_text> </rich_text><rich_text foreground="#ffff52525457">TODO</rich_text><rich_text>
</rich_text><rich_text link="node 97">Named Fields</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
</rich_text><rich_text link="node 61">Wide Color Range</rich_text><rich_text> </rich_text><rich_text foreground="#ffff52525457">TODO</rich_text><rich_text>
</rich_text><rich_text link="node 108">Object Names and References</rich_text><rich_text> </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
</rich_text><rich_text link="node 109">Classes</rich_text><rich_text> </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><node name="Status Markers" prog_lang="custom-colors" readonly="False" tags="" unique_id="21"><rich_text>Status markers will help me keep track of the development of language syntax by providing simple categorization of syntax issues by the state of development.
The markers are colored words in capital letters. Instead of finding the color every time, one can simply copy them from this page. But I will also specify here the hex numbers of the colors, so that they can easily be used for text by directly setting text color, and used by syntax highlighters to automatically given them the right color.
Here they are:
</rich_text><rich_text foreground="#ffff52525457">TODO</rich_text><rich_text>
red 255
green 92
blue 92
hex #FF5C5C
</rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>
red 255
green 165
blue 0
hex #FFA500
</rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>
red 255
green 255
blue 0
hex #FFFF00
</rich_text><rich_text foreground="#1634cd710574">DONE</rich_text><rich_text>
red 0
green 200
blue 0
hex #00C800
What they mean:
• </rich_text><rich_text foreground="#ffff52525457">TODO</rich_text><rich_text>: This is a new syntax issue I need to plan, not touched yet
• </rich_text><rich_text foreground="#ffffa5a50000">WIP</rich_text><rich_text>: This syntax issue us being developed/planned/designed
• </rich_text><rich_text foreground="#ffffffff0000">TEMP</rich_text><rich_text>: This syntax issue has a temporary decision/plan/design, which works for now but should be reviewed again
• </rich_text><rich_text foreground="#1634cd710574">DONE</rich_text><rich_text>: This syntax issue has been fully planned and all decisions have been made</rich_text></node><node name="Statements and Semicolons" prog_lang="custom-colors" readonly="False" tags="" unique_id="19"><rich_text>The way statements are separated in a language is extremely important. I'd like to start by writing some random examples, not taken from any particular language, and then explain the issue.
With a semicolon (like C and C++, and Java too with slight differences)
</rich_text><rich_text justification="left"></rich_text><rich_text>
Without a semicolon
</rich_text><rich_text justification="left"></rich_text><rich_text>
Considering the decision to use indentation as the syntax for blocks, using semicolons don't add much to the language, while producing a significant amount of visual clutter and beginner bugs. And they would unnecessarily annoy all users.
However, semicolons are not the only issue. There are also parentheses issues and colon issues to be resolved. For now, the two issues I have to decide on are semicolons and colons. Here's an example for colon usage in a class definition:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The other option is simply to omit the colon:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Python explains the usage of colons in the FAQ, here it is:
"</rich_text><rich_text weight="heavy">Why are colons required for the if/while/def/class statements?</rich_text><rich_text>
The colon is required primarily to enhance readability (one of the results of the experimental ABC language). Consider this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
versus
</rich_text><rich_text justification="left"></rich_text><rich_text>
Notice how the second one is slightly easier to read. Notice further how a colon sets off the example in this FAQ answer; it’s a standard usage in English.
Another minor reason is that the colon makes it easier for editors with syntax highlighting; they can look for colons to decide when indentation needs to be increased instead of having to do a more elaborate parsing of the program text."
</rich_text><rich_text weight="heavy">Semicolons as statement terminators</rich_text><rich_text>:
</rich_text><rich_text style="italic">Options</rich_text><rich_text>: Use, Not Use
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">Not Use</rich_text><rich_text>
</rich_text><rich_text weight="heavy">Colons before Indented Blocks</rich_text><rich_text>
</rich_text><rich_text style="italic">Options</rich_text><rich_text>: Use, Not Use
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">Use</rich_text><codebox char_offset="263" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">int x;
int y;
bool b, c;
float p; double q;</codebox><codebox char_offset="286" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">int x
int y
int b, c
float p
double q</codebox><codebox char_offset="769" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
property a
property b</codebox><codebox char_offset="819" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass
property a
property b</codebox><codebox char_offset="1072" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">if a == b
print a</codebox><codebox char_offset="1081" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">if a == b:
print a</codebox></node><node name="Structure" prog_lang="custom-colors" readonly="False" tags="" unique_id="62"><rich_text></rich_text><node name="Indentation and Blocks" prog_lang="custom-colors" readonly="False" tags="" unique_id="20"><rich_text>Program blocks are commonly marked with indentation, but in some langiages indentation just makes the code readable, while in others it is a syntax feature and affects the logical structure of the program. C and C++ are an example for the first option, and Python is an example for the second.
Here's an example from Wikipedia, comparing C and Python. This is a C function:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And this is the Python equivalent:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The thing is, my language doesn't currently need any kind of functions. It only represents data. So we can compare some examples with classes. I'll write my own examples for class definitions, without particular rules, just to demonstrate the difference between brackets and indentation.
This one uses bracket blocks:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now the same definition with indentation blocks:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The benefit I personally feel brackets have, is that you can easily see where the block ends. In Python, it's just a "staircase" with growing indentation, which in C you clearly see where the blocks ends and even can have a comment there saying which blocks ends here.
But when using a special editor, seeing blocks is not a problem. An editor can mark blocks in many ways, and make it clear where they start and end. It can also offer code folding, just like with bracket blocks.
As you can see, indentation is used anyway, with or without brackets, because it makes the code readable. So why not make then a syntax feature? According to wikipedia, there's a problem with tabs and spaces being used together, and some non-code editors collapsing spaces (e.g. in online forums) and damaging the code indentation. Without brackerts, the indentation is not just a readability bonus. It's part of the syntax.
Before I decide, let's make lists of pros and cons.
</rich_text><rich_text underline="single">Brackets</rich_text><rich_text>:
</rich_text><rich_text foreground="#0000ffff0000">Pros</rich_text><rich_text>:
• You clearly see where the block (starts and) ends
• Free text, you can organize statements in a single line or several lines or any other free form
• Code semantics not damaged when tabs and spaces are collapsed
</rich_text><rich_text foreground="#ffff2f2e2f2e">Cons</rich_text><rich_text>:
• Brackets add clutter to code, since indentation is used anyway to increase readability
- But a dedicated editor can hide them, and easily switch between having them or hiding them
• You need to get used to putting them everywhere, especially if you're a non-programmer
- But an editor can automatically place closing brackets
</rich_text><rich_text underline="single">Indentation</rich_text><rich_text>:
</rich_text><rich_text foreground="#0000ffff0000">Pros</rich_text><rich_text>:
• Highly readable, no clutter
• No need to remember to put brackets everywhere, just add indentation with the tab key (remove with backspace)
• Makes the code look like natural flow of text, very easy to read for non-programmers
</rich_text><rich_text foreground="#ffff2f2e2f2e">Cons</rich_text><rich_text>:
• You don't clearly see where a block ends
- But a dedicated editor can blocks and do code folding
• The way you organize the text isn't free: you have to use the indentation rules because they're syntax rules
- But indentation organizes code in a readable way, you don't really need the freedom to do mess
• Code semantics are damaged when spaces and tabs are collapsed
- But it's just a technical issue (a bug) and a problem of those systems which collapse spaces automatically
</rich_text><rich_text style="italic">Options</rich_text><rich_text>: Brackets, Indentation
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">Indentation</rich_text><codebox char_offset="376" frame_height="250" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="c" width_in_pixels="True">void foo (int x)
{
if (x == 0)
{
bar ();
baz ();
}
else
{
qux (x);
foo (x - 1);
}
}</codebox><codebox char_offset="415" frame_height="140" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">def foo(x):
if not x:
bar()
baz()
else:
qux(x)
foo(x - 1)</codebox><codebox char_offset="738" frame_height="244" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">class MyClass
{
property myprop1
property myprop2
property myprop3
compound property myprop4
{
property z
property y
property z
}
}</codebox><codebox char_offset="791" frame_height="176" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass
property myprop1
property myprop2
property myprop3
compound property myprop4
property x
property y
property z</codebox></node><node name="Lines" prog_lang="custom-colors" readonly="False" tags="" unique_id="63"><rich_text>What exactly is allowed by a single line? How many statements? What are the smallest and largest units of code allowed/should be on a line of code?
My syntax is much more like Python that C/C++, so let's examine Python. Two statements can't be on the same line. I'm going to use the same convention in my language: A single simple statement per line. But Python does allow things like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This would set a and b by first evaluating the expressions on the left, and then assigning the resuls to the variables.</rich_text><codebox char_offset="393" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">x = 6
a,b = 4, 5*x-3</codebox></node></node><node name="Keywords" prog_lang="custom-colors" readonly="False" tags="" unique_id="22"><rich_text></rich_text><node name="Case of Keywords" prog_lang="custom-colors" readonly="False" tags="" unique_id="38"><rich_text>Keywords can start with a capital letter, or be in lower case, or be in higher case. Here are some examples.
Start with capital letter:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Lowercase:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Capital case:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Here's an initial set of decisions:
</rich_text><rich_text underline="single">Styles</rich_text><rich_text>:
camelcase: Keyword, LongKeyword C++ classes
donkeycase: keyword, longKeyword
lowercase: keyword, longkeyword
lowercscores: keyword, long_keyword C++ functions, methods, variables, fields, namespaces
scapital: K
ssmall: k C++ local helper variables
symbol: ℂ
traincase: keyword, long-keyword Usually not used due to "-" denoting subtraction
uppercase: KEYWORD, LONGKEYWORD
uppescores: KEYWORD, LONG_KEYWORD C macros, Java constants
</rich_text><rich_text underline="single">Keyword Types</rich_text><rich_text>:
language keywords lowerscores
sets camelcase, scapital, symbol
namespaces
built-in/standard lowerscores
specific/user lowercase/camelcase
types lowercase/lowerscores
relations lowerscores/donkeycase
classes camelcase
objects lowerscores, donkeycase</rich_text><codebox char_offset="138" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="chdr" width_in_pixels="True">Integer var</codebox><codebox char_offset="153" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="chdr" width_in_pixels="True">integer var</codebox><codebox char_offset="171" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="chdr" width_in_pixels="True">INTEGER var</codebox></node><node name="Null Object" prog_lang="custom-colors" readonly="False" tags="" unique_id="39"><rich_text>In cases I'll need to specify no object, I'd like to use a special keyword for that. In C and C++, common keywords are </rich_text><rich_text style="italic">NULL</rich_text><rich_text> and </rich_text><rich_text style="italic">nullptr.</rich_text><rich_text> In java, </rich_text><rich_text style="italic">null</rich_text><rich_text> is used. In Python there's a </rich_text><rich_text style="italic">None</rich_text><rich_text> keyword.
Since </rich_text><rich_text style="italic">null</rich_text><rich_text> is a technical name used in computing and mathematics, while </rich_text><rich_text style="italic">none</rich_text><rich_text> is a common English word, I prefer </rich_text><rich_text style="italic">none</rich_text><rich_text> (no pun intended). The decision regarding case of keyword is still work in progress, but for now I'll use a lowercase </rich_text><rich_text style="italic">none</rich_text><rich_text>. It's still unclear whether it is going to be a keyword or simply the string "none", but the important thing is that I chose the name.
</rich_text><rich_text style="italic">Options</rich_text><rich_text>: NULL, Null, null, NONE, None, none
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">none</rich_text><rich_text>
</rich_text><rich_text style="italic">Secondary choice</rich_text><rich_text>: </rich_text><rich_text weight="heavy">None</rich_text></node><node name="Boolean Values" prog_lang="custom-colors" readonly="False" tags="" unique_id="40"><rich_text>There are three questions about boolean values:
1. </rich_text><rich_text underline="single">Standard boolean values</rich_text><rich_text>
The values themselves will be "true" and "false". But I can use different cases for them:
• true, false (C++, Java)
• True, False (Python)
• TRUE, FALSE (C)
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">true, false</rich_text><rich_text>
2. </rich_text><rich_text underline="single">0 and 1</rich_text><rich_text>
In XSD, if I'm not mistaken, 0 and 1 are legal boolean values, representing false and true respectively. Should my language allow that too?
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffff00000000" weight="heavy">?</rich_text><rich_text>
3. </rich_text><rich_text underline="single">Other numbers and values</rich_text><rich_text>
In C and other languages, any non-zero number can be considered true, while zero means false. Should my language do that too?
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">No</rich_text><rich_text>
Also, should values like enabled/disabled, on/off, left/right, etc. be built-in (or user-defined through literal definition) convenient alternatives for true/false?
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffff00000000" weight="heavy">?</rich_text><rich_text>
4. </rich_text><rich_text underline="single">Mathematical Notation</rich_text><rich_text>
In the Logic and Set Theory course I tool on my first semester, we used </rich_text><rich_text style="italic">T</rich_text><rich_text> and </rich_text><rich_text style="italic">F</rich_text><rich_text> to specify the truth values in logic. Should my language support them? Or some other mathematical notations? (Wikipedia can help)
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffff00000000" weight="heavy">?</rich_text></node><node name="Definition Keywords" prog_lang="custom-colors" readonly="False" tags="" unique_id="48"><rich_text></rich_text><node name="Unused" prog_lang="custom-colors" readonly="False" tags="" unique_id="101"><rich_text>This page lists keyword not used for anything yet, including both random ideas and keywords from common computer languages.
</rich_text><rich_text weight="heavy">property</rich_text><rich_text>
</rich_text><rich_text weight="heavy">relation</rich_text><rich_text>
</rich_text><rich_text weight="heavy">in</rich_text><rich_text> for set containtment, i.e. the same as the ϵ symbol
</rich_text><rich_text weight="heavy">get</rich_text><rich_text>
</rich_text><rich_text weight="heavy">set</rich_text><rich_text> already used for defining a set
</rich_text><rich_text weight="heavy">string</rich_text><rich_text>
</rich_text><rich_text weight="heavy">text</rich_text><rich_text>
</rich_text><rich_text weight="heavy">int</rich_text><rich_text>
</rich_text><rich_text weight="heavy">integer</rich_text><rich_text>
</rich_text><rich_text weight="heavy">bool</rich_text><rich_text>
</rich_text><rich_text weight="heavy">boolean</rich_text><rich_text>
</rich_text><rich_text weight="heavy">decimal</rich_text><rich_text>
</rich_text><rich_text weight="heavy">number</rich_text><rich_text>
</rich_text><rich_text weight="heavy">float</rich_text><rich_text>
</rich_text><rich_text weight="heavy">double</rich_text><rich_text>
</rich_text><rich_text weight="heavy">char</rich_text><rich_text>
</rich_text><rich_text weight="heavy">character</rich_text><rich_text>
</rich_text><rich_text weight="heavy">byte</rich_text><rich_text>
</rich_text><rich_text weight="heavy">short</rich_text><rich_text>
</rich_text><rich_text weight="heavy">long</rich_text><rich_text>
</rich_text><rich_text weight="heavy">signed</rich_text><rich_text>
</rich_text><rich_text weight="heavy">unsigned</rich_text><rich_text>
</rich_text><rich_text weight="heavy">positive</rich_text><rich_text>
</rich_text><rich_text weight="heavy">negative</rich_text><rich_text>
</rich_text><rich_text weight="heavy">non</rich_text><rich_text>
</rich_text><rich_text weight="heavy">zero</rich_text><rich_text>
</rich_text><rich_text weight="heavy">null</rich_text><rich_text>
</rich_text><rich_text weight="heavy">not</rich_text><rich_text>
</rich_text><rich_text weight="heavy">and</rich_text><rich_text>
</rich_text><rich_text weight="heavy">or</rich_text><rich_text>
</rich_text><rich_text weight="heavy">xor</rich_text><rich_text>
</rich_text><rich_text weight="heavy">nand</rich_text><rich_text>
</rich_text><rich_text weight="heavy">nor</rich_text><rich_text>
</rich_text><rich_text weight="heavy">nxor</rich_text><rich_text>
</rich_text><rich_text weight="heavy">concept</rich_text><rich_text>
</rich_text><rich_text weight="heavy">primitive</rich_text><rich_text>
</rich_text><rich_text weight="heavy">def</rich_text><rich_text>
</rich_text><rich_text weight="heavy">define</rich_text><rich_text>
</rich_text><rich_text weight="heavy">let</rich_text><rich_text>
</rich_text><rich_text weight="heavy">text</rich_text><rich_text>
</rich_text><rich_text weight="heavy">check</rich_text><rich_text>
</rich_text><rich_text weight="heavy">assert</rich_text><rich_text>
</rich_text><rich_text weight="heavy">include(s)</rich_text><rich_text>
</rich_text><rich_text weight="heavy">has</rich_text><rich_text>
</rich_text><rich_text weight="heavy">contains</rich_text><rich_text>
</rich_text><rich_text weight="heavy">equal</rich_text><rich_text>
</rich_text><rich_text weight="heavy">greater</rich_text><rich_text>
</rich_text><rich_text weight="heavy">less</rich_text><rich_text>
</rich_text><rich_text weight="heavy">gequel</rich_text><rich_text>
</rich_text><rich_text weight="heavy">gless</rich_text><rich_text>
</rich_text><rich_text weight="heavy">than</rich_text><rich_text>
</rich_text><rich_text weight="heavy">exists</rich_text><rich_text>
</rich_text><rich_text weight="heavy">satisfies</rich_text><rich_text>
</rich_text><rich_text weight="heavy">yes</rich_text><rich_text>
</rich_text><rich_text weight="heavy">no</rich_text><rich_text>
</rich_text><rich_text weight="heavy">maybe</rich_text><rich_text>
</rich_text><rich_text weight="heavy">begin</rich_text><rich_text>
</rich_text><rich_text weight="heavy">end</rich_text><rich_text>
</rich_text><rich_text weight="heavy">start</rich_text><rich_text>
</rich_text><rich_text weight="heavy">stop</rich_text><rich_text>
</rich_text><rich_text weight="heavy">list</rich_text><rich_text>
</rich_text><rich_text weight="heavy">sequence</rich_text><rich_text>
</rich_text><rich_text weight="heavy">union</rich_text><rich_text>
</rich_text><rich_text weight="heavy">tuple</rich_text><rich_text>
</rich_text><rich_text weight="heavy">pair</rich_text><rich_text>
</rich_text><rich_text weight="heavy">symdiff</rich_text><rich_text>
</rich_text><rich_text weight="heavy">map</rich_text><rich_text>
</rich_text><rich_text weight="heavy">function</rich_text><rich_text>
</rich_text><rich_text weight="heavy">vector</rich_text><rich_text>
</rich_text><rich_text weight="heavy">matrix</rich_text><rich_text>
</rich_text><rich_text weight="heavy">size</rich_text><rich_text>
</rich_text><rich_text weight="heavy">length</rich_text><rich_text>
</rich_text><rich_text weight="heavy">count</rich_text><rich_text>
</rich_text><rich_text weight="heavy">add</rich_text><rich_text>
</rich_text><rich_text weight="heavy">mul</rich_text><rich_text>
</rich_text><rich_text weight="heavy">sub</rich_text><rich_text>
</rich_text><rich_text weight="heavy">div</rich_text><rich_text>
</rich_text><rich_text weight="heavy">multiply</rich_text><rich_text>
</rich_text><rich_text weight="heavy">subtract</rich_text><rich_text>
</rich_text><rich_text weight="heavy">divide</rich_text><rich_text>
</rich_text><rich_text weight="heavy">mod</rich_text><rich_text>
</rich_text><rich_text weight="heavy">modulo</rich_text><rich_text>
</rich_text><rich_text weight="heavy">pow</rich_text><rich_text>
</rich_text><rich_text weight="heavy">power</rich_text><rich_text>
</rich_text><rich_text weight="heavy">ratio</rich_text><rich_text>
</rich_text><rich_text weight="heavy">time</rich_text><rich_text>
</rich_text><rich_text weight="heavy">lang</rich_text><rich_text>
</rich_text><rich_text weight="heavy">language</rich_text><rich_text>
</rich_text><rich_text weight="heavy">id</rich_text><rich_text>
</rich_text><rich_text weight="heavy">identifier</rich_text><rich_text>
</rich_text><rich_text weight="heavy">sum</rich_text><rich_text>
</rich_text><rich_text weight="heavy">product</rich_text><rich_text>
</rich_text><rich_text weight="heavy">all</rich_text><rich_text>
</rich_text><rich_text weight="heavy">some</rich_text><rich_text>
</rich_text><rich_text weight="heavy">none</rich_text></node><node name="Proposed" prog_lang="custom-colors" readonly="False" tags="" unique_id="102"><rich_text>The page lists keywords proposed for specific usage.
</rich_text><rich_text weight="heavy">set</rich_text><rich_text> for definition of sets
</rich_text><rich_text weight="heavy">type</rich_text><rich_text> for definition of types
</rich_text><rich_text weight="heavy">class</rich_text><rich_text> for definition of classes
</rich_text><rich_text weight="heavy">none</rich_text><rich_text> as the null object
</rich_text><rich_text weight="heavy">true</rich_text><rich_text> as a boolean truth value
</rich_text><rich_text weight="heavy">false</rich_text><rich_text> as a boolean truth value</rich_text></node><node name="Assigned" prog_lang="custom-colors" readonly="False" tags="" unique_id="103"><rich_text>This page contains keywords in status of "temporarily assigned", meaning their proposal is approved, but they haven't entered the language formally yet.</rich_text></node><node name="Used" prog_lang="custom-colors" readonly="False" tags="" unique_id="104"><rich_text>This page lists keywords formally approved for usage in the language.</rich_text></node></node></node><node name="Type Names" prog_lang="custom-colors" readonly="False" tags="" unique_id="31"><rich_text></rich_text><node name="Word Combination" prog_lang="custom-colors" readonly="False" tags="" unique_id="36"><rich_text>The types in programming languages usually use keywords to specify and define the referred type, while XML uses strings of concatenated words, i.e. without spaces. For example, </rich_text><rich_text style="italic">unsignedInt</rich_text><rich_text> is used in XSD, while </rich_text><rich_text style="italic">unsigned int</rich_text><rich_text> is used in C and C++.
My language tries to be verbose, and avoid making users use technical notations unless they choose to, so I prefer the second option, </rich_text><rich_text style="italic">unsigned int</rich_text><rich_text>. Use clear simple separate words. Here's a "graphical" representation of this guideline.
</rich_text><rich_text foreground="#ffff00000000">Bad</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#0000ffff0000">Good</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="488" frame_height="30" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">unsignedInt var</codebox><codebox char_offset="496" frame_height="30" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">unsigned int var</codebox></node></node><node name="Set Definition" prog_lang="custom-colors" readonly="False" tags="" unique_id="43"><rich_text></rich_text><node name="Intensional ("abstract") Set Definition" prog_lang="custom-colors" readonly="False" tags="" unique_id="44"><rich_text>An abstract set definition contains just words describing the </rich_text><rich_text style="italic">unique characteristics</rich_text><rich_text> of the set's members, and these characteristics serve to determine whether a given entity is a member of the set.
First, what would I like to see in such a definition? The immediate answer is "just words", but in practice it may be useful to supply some other useful fields. At the moment I have two ideas: a </rich_text><rich_text weight="heavy">mathematical symbol</rich_text><rich_text> of the set, if such exists, and a special </rich_text><rich_text weight="heavy">language symbol</rich_text><rich_text> for the set. For example, the language may have a set without a mathematical symbol, but still should be able to refer to it. Or the mathematical symbol may be inconvenient to use in the language.
Here's a suggestion for the components of an intensional ("abstract") set definition:
• set definition syntax
• language symbol
• description
• (optional) mathematical/alternative symbol
</rich_text><rich_text scale="h3">Examples</rich_text><rich_text>
Here are some ideas and examples. Later, if I don't choose any self-made example, I'll paste here examples from programming languages and examine them.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Here are more examples in a more </rich_text><rich_text style="italic">explicit</rich_text><rich_text> notation:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Here's an example without any assignment operator, like in Turtle syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h3">More Fields</rich_text><rich_text>
</rich_text><rich_text underline="single" weight="heavy">superset</rich_text><rich_text>:
These examples are probably enough. But don't I need more fields? Example: The natural numbers are a subset of the real numbers, but still get defined in abstract notation. Even if not, "people with black hair" is a subset of "people" and still it may not be possible to define it not using abtract notation. So it should be possible to define a </rich_text><rich_text weight="heavy">superset</rich_text><rich_text> too.
Before I continue, I'm creating a new subpage for the fields and I'll update it when I add new fields: </rich_text><rich_text link="node 100">Fields</rich_text><rich_text>.
Now I need to add the existing fields to that page (description, symbol, superset), but before that - </rich_text><rich_text style="italic">can</rich_text><rich_text> N be defined without abstract notation? And if it can - </rich_text><rich_text style="italic">should</rich_text><rich_text> N it be defined without abstract notation?
According to Wikipedia, there's no direct way to define N directly. Basically, I could take 0 and 1 and define al numbers recursively, but then the computer can't easily determine whether a given number is natural or not. I can also use something like "all real numbers whose floor is equal to the number itself and are non-negative". This would actually work, wouldn't it?
I think there's a deeper problem: Defining sets using math operations means I need to add a whole feature of math to the language. Most of the time there's no need for direct math, so it may be much easier to just define N using </rich_text><rich_text style="italic">abstract definition</rich_text><rich_text>.
Now let's make a list of fields on the new subpage... done.
</rich_text><rich_text scale="h3">Chosen Syntax</rich_text><rich_text>
Since fields are a technical addition which can be always extended further, I'll make them a separate syntax issue. I want to choose the abstract definition syntax and be done here.
Since the various ways to define sets include a variety of possible fields and parameters, I want to use the one most verbose and dynamic.
</rich_text><rich_text style="italic">Definition Syntax</rich_text><rich_text>: The keyword </rich_text><rich_text style="italic">set</rich_text><rich_text> followed by set name and a colon
</rich_text><rich_text style="italic">Name</rich_text><rich_text>: Appears on the first like after the </rich_text><rich_text style="italic">set</rich_text><rich_text> keyword
</rich_text><rich_text style="italic">Fields</rich_text><rich_text>: Each field on a separate indented line: name, assignment operator and value
</rich_text><rich_text style="italic">Assignment Operator</rich_text><rich_text>: None at all, like in Turtle syntax (i.e. just a space)
Example:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1023" frame_height="115" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">set People
"The set of all the people who ever existed"
set R
"The set of all real numbers"
ℝ</codebox><codebox char_offset="1026" frame_height="115" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">set People:
"The set of all the people who ever existed"
set R:
"The set of all real numbers"
ℝ</codebox><codebox char_offset="1029" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="python" width_in_pixels="True">set People : "The set of all the people who ever existed"
set R (ℝ) : "The set of all real numbers"</codebox><codebox char_offset="1032" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">set People : The set of all the people who ever existed
set R (ℝ) : The set of all real numbers</codebox><codebox char_offset="1035" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">set People = The set of all the people who ever existed
set R (ℝ) = The set of all real numbers</codebox><codebox char_offset="1091" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People
description = "The set of all the people who ever existed"
symbol = ℝ</codebox><codebox char_offset="1094" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description = "The set of all the people who ever existed"
symbol = ℝ</codebox><codebox char_offset="1097" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description : "The set of all the people who ever existed"
symbol : ℝ</codebox><codebox char_offset="1100" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description := "The set of all the people who ever existed"
symbol := ℝ</codebox><codebox char_offset="1103" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description : The set of all the people who ever existed
symbol : ℝ</codebox><codebox char_offset="1106" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description = The set of all the people who ever existed
symbol = ℝ</codebox><codebox char_offset="1109" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description (The set of all the people who ever existed)
symbol (ℝ)</codebox><codebox char_offset="1187" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description "The set of all the people who ever existed"
symbol ℝ</codebox><codebox char_offset="3218" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">set People:
description "The set of all the people who ever existed"
symbol ℝ</codebox></node><node name="Fields" prog_lang="custom-colors" readonly="False" tags="" unique_id="100"><rich_text>Definition Syntax
Name
Description
Symbol
Superset
Definition
Alias</rich_text></node><node name="Extensional ("explicit") Set Definition" prog_lang="custom-colors" readonly="False" tags="" unique_id="45"><rich_text>Some issues are presented here: </rich_text><rich_text link="node 42 Explicit Definition">Primitive Type Theory ::: Explicit Set Definition</rich_text><rich_text>.
</rich_text><rich_text scale="h3">Syntax</rich_text><rich_text>
If we define a set of numbers like this:
</rich_text><rich_text style="italic">X = {1, 2, 3, 4}</rich_text><rich_text>
The computer needs to know we refer to numbers. How will it know? The question lies in a broader issue: How do we define and specify objects? In general, explicit definition is made by specifying objects. For example:
</rich_text><rich_text style="italic">X = {1, two, "three"}</rich_text><rich_text>
I can use any member of any set. How do we define objects? This leads to another question: </rich_text><rich_text style="italic">What</rich_text><rich_text> exactly are objects? Before I decide, there's </rich_text><rich_text style="italic">another</rich_text><rich_text> question to ask!
Sets are defined for the purpose of defining types. For example, defining some enum type, or defining a "grade" type whose range is the set [0, 100]. Do I need non-primitive types for that? Imagine I want to define some compound type. Should it be possible? The answer is: yes, it should be possible, and such a type would be called a </rich_text><rich_text style="italic">class</rich_text><rich_text>. But a class is not defined using sets. All the fields of a class are themselves </rich_text><rich_text style="italic">objects</rich_text><rich_text>, which are members of sets, detoned and parsed through their </rich_text><rich_text style="italic">types</rich_text><rich_text> or </rich_text><rich_text style="italic">classes</rich_text><rich_text>.
But look at the following example: Assume I want to define a type an enumeration type whose values are objects. For example, I have a team of 10 people. 3 of them are managers. I want an enum type to specify which manager is responsible for a given project, so for each project I want to have an enum field.
This field maps language text (all types have strings as their domain) to </rich_text><rich_text style="italic">people</rich_text><rich_text>. In this specific case, it doesn't just map to any person, but to a set of specific three people. So naturally I want to specify an enum of three people. It can be something like this:
</rich_text><rich_text style="italic">enum responsible {John, Anne, Thomas}</rich_text><rich_text>
But John, Anne and Thomas are not language keywords. They cannot be used just like that, as if they were C global variables. They need to appear in a form of Qualified ID. Assume I define a task. How do I refer to it? Actually, in the case of a task I may not need to, but you get the point. Let's take some other object. A person. Assume I defined a person object, just like in RDF. Then that person gets two names: a URI and a local name. That local name can be used to refer to that person.
Since a document may define many objects, it's possible to refer to them by a set they belong to, or put them in new namespaces/sets.
So this is how a set is defined using object names in a list: the names or URIs are specified between braces. Yes. Exactly. It's official. I just need to create a page for object names and references... done.
</rich_text><rich_text scale="h3">Reasoning</rich_text><rich_text>
Sometimes Jane may want to define a set using random objects, but most of the time she wants to use objects from a single set. As a result, usually the new set is a subset of some set Jane has already defined. So a good question may be: should the user help the computer do reasoning about supersets?
Let's try to be the computer and do some reasoning. Assume the user has defined a set using explicit notation, and we want to determine two things: First, what's the tightest superset of this set, if any; Second, check if the set is a subset of a given set we already have.
For the first problem, we run through the objects and simply check their definitions. If all objects are defined to have a set, we just need to find a common superset. But yes, it may not be fast. For the second problem, we need to check for each object whether it's a member of the given set.
Both operations may take time, but providing a superset by hand meand </rich_text><rich_text weight="heavy">duplication of information</rich_text><rich_text>, which is bad. So, the </rich_text><rich_text style="italic">decision</rich_text><rich_text> is: </rich_text><rich_text weight="heavy">do not</rich_text><rich_text> provide duplicate data which can be inferred from the definitions.</rich_text></node><node name="Set-Builder Notation" prog_lang="custom-colors" readonly="False" tags="" unique_id="107"><rich_text></rich_text></node></node><node name="Primitive Type Definition" prog_lang="custom-colors" readonly="False" tags="" unique_id="46"><rich_text></rich_text><node name="The Mapping Function" prog_lang="custom-colors" readonly="False" tags="" unique_id="47"><rich_text>The question is: How do we define the mapping function for a primitive type? Is a textual description always enough? Can we write a mathematical definition? Pseudo-code? Provide a programming-language procedure? Source code? Binary? Can/should we provide both words and math?
Some thoughts and ideas of mine can be found at </rich_text><rich_text link="node 42 Defining Primitive Types">Defining Primitive Types</rich_text><rich_text>.
</rich_text><rich_text scale="h3">For Types</rich_text><rich_text>
</rich_text><rich_text style="italic">Decision</rich_text><rich_text>: </rich_text><rich_text foreground="#ffff00000000" weight="heavy">?</rich_text><rich_text>
</rich_text><rich_text scale="h3">For Classes</rich_text><rich_text>
Classes are different from plain types. The reason is that classes don't need custom or specialized types. For example, assume you want to specify an integer. In C, you can use 1.0f or 1 or 1.0 or 1e0 and probably other combinations. The point is that there's a wide set of options and syntax rules for numbers.
Now, what about classes? Assume you have an object. How do you refer to it? That's right, you use a variable's name. While numbers need explicit definition due to their nature, objects are specific listings of properties, define one-by-one by a human being. So there's one natural way to refer to them: either using a URI, or by using a name. This name should be valid at least inside the definition file.
So for class objects, it doesn't make sense to first define a class, and then also define a type which maps names to objects. It's </rich_text><rich_text style="italic">obvious</rich_text><rich_text> you want to map names and URIs to objects. In numbers, you can have a scheme, a formal function. For example, for an array of digits, a simple function can multiply each digit by 10 raise to the power of its position in the array. Example: 3869 = 9 * 10^0 + 6 * 10^1 + 8 * 10^2 + 3 * 10^3. Not surprising, right? But for objects, there's no math involved, so you don't need all that complicated syntax.
Thus, a class </rich_text><rich_text style="italic">automatically</rich_text><rich_text> makes a type, which maps local names and URIs to objects. There's no need to define any function.</rich_text></node><node name="Prototypes" prog_lang="custom-colors" readonly="False" tags="" unique_id="105"><rich_text>I'm going to suggest a prototype here, for defining types. I already wrote prototype definitions for some sets, and now I want to define the types themselves.
I also wrote "generators" like P(X), Seq(X) and Fin(X), and basically types are functions just like generators are. So I can even give them a unified syntax and make them the same type of entity. But for now, let's just define them as types, maybe using </rich_text><rich_text style="italic">generator</rich_text><rich_text> syntax as guidance.
In order to define types with complex rules, I need to use some standard syntax for text expressions. I guess </rich_text><rich_text style="italic">Regular Expressions</rich_text><rich_text> are what I need. But I'll start by defining some simple types and later add the regex parts where needed.
type string:
range = Strings
function = Id
type text:
base = string
function = ?
type natural:
domain = [0-9]* // update this to a correct regexp
function = sum from 0 to len-1 (num (s[i]))
type rational:
type real:
function = ?
type complex:
There are two issues here: How generators are used, and how types are defined.
</rich_text><rich_text style="italic">Types</rich_text><rich_text>: Currently the decision is </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">not to define them explicitly at all</rich_text><rich_text>
</rich_text><rich_text style="italic">Generators</rich_text><rich_text>: </rich_text><rich_text foreground="#ffff00000000" weight="heavy">?</rich_text></node></node><node name="Mathematical Notation" prog_lang="custom-colors" readonly="False" tags="" unique_id="94"><rich_text>As a result of the mathematical basis of the language, a need arises to decide which mathematical notations are relevant, and what are their simple programmatic equivalent operators and keywords.</rich_text><node name="Sets, Lists, Sequences and Tuples" prog_lang="custom-colors" readonly="False" tags="" unique_id="96"><rich_text>In many programming language, one of the syntax choices affecting the visual presentation of the code is the way block delimiters are used.
I'd like to choose the block delimiters for the various kinds of sequences and compound constructs in the language. They are not formally defined yet, but I'll try to make a list of ideas are guidelines. Before I start suggesting ideas, I'll informally define the structures I refer to.
</rich_text><rich_text scale="h3">Informal Definition</rich_text><rich_text>
</rich_text><rich_text underline="single" weight="heavy">Set</rich_text><rich_text>: The </rich_text><rich_text style="italic">set</rich_text><rich_text> structure is the textual representation used by the language to denote a set, in the mathematical sense. Since abstract concepts cannot be specified by characters, their text representations may be used in a </rich_text><rich_text style="italic">set</rich_text><rich_text> definition.
</rich_text><rich_text underline="single" weight="heavy">List</rich_text><rich_text>: The </rich_text><rich_text style="italic">list</rich_text><rich_text> structure is a computer tool used as means to refer to a series of objects in memory. In the mathematical sense, a list may be though of as a member of all finite tuples over some set or cartesian product of some sets. Specifically, when all items in a list are objects of the same class, the list is a member of the set of all finite tuples of instances of that class. It's like a power set, but for tuples instead of sets.
</rich_text><rich_text underline="single" weight="heavy">Sequence</rich_text><rich_text>: This is basically a convenient dynamic structure more-or-less representing a finite series, in the mathematical sense. The length of the series may be changed after definition.
</rich_text><rich_text underline="single" weight="heavy">Tuple</rich_text><rich_text>: A tuple structure is the way by which the language denotes a mathematical tuple, i.e. a member of the cartesian product of some </rich_text><rich_text style="italic">n</rich_text><rich_text> sets A</rich_text><rich_text scale="sub">1</rich_text><rich_text>,...A</rich_text><rich_text scale="sub">n</rich_text><rich_text>, with n being some constant natural number (zero is legal). A tuple is the mathematical basis for sequences. A tuple has a fixed size, while a sequence may get new series elements after initial definition.
</rich_text><rich_text scale="h3">Mathematical Notation</rich_text><rich_text>
</rich_text><rich_text weight="heavy">Sets</rich_text><rich_text> have a clear known formal notation. Plans for set definition syntax is specified on </rich_text><rich_text link="node 43">another page</rich_text><rich_text>, but before those plans I need to define the delimiter styles for all structures. Without going into detail, the delimiters used for definition of sets in mathematics are </rich_text><rich_text style="italic">curly brackets</rich_text><rich_text>, {}.
</rich_text><rich_text weight="heavy">Lists</rich_text><rich_text> are not mathematical notions, but they have common syntax in many programming languages. Since angle brackets and parentheses have common meaningful mathematical notations in set theory, a good delimiter for lists may be </rich_text><rich_text style="italic">square brackets</rich_text><rich_text>, []. But </rich_text><rich_text style="italic">angle brackets</rich_text><rich_text>, <>, are a candidate too.
</rich_text><rich_text weight="heavy">Sequences</rich_text><rich_text> are somewhere in between, without a common concrete definition of what they mean. I assume the same candidates for lists apply here too.
</rich_text><rich_text weight="heavy">Tuples</rich_text><rich_text> are a mathematical notion like sets, and thus have a clear formal notation. But unlike sets, there is more than one common notation. The most common one is probably </rich_text><rich_text style="italic">parentheses</rich_text><rich_text> (), which Python uses, and another common notation is </rich_text><rich_text style="italic">angle brackets</rich_text><rich_text> <>, which I used in </rich_text><rich_text style="italic">Logic and Set Theory</rich_text><rich_text> in my first semester.
</rich_text><rich_text scale="h3">Explicit Notation and Shorthand Notation</rich_text><rich_text>
The idea of two notations works as follows: A shorthand notation using mathematical symbols may be short and compact, but it's not necessarily practical. A computer language is, after all, a language for people to use in models and designs and programs, and it can't let format conventions damage readability and effectivity.
So I had an idea, why not have two forms of notation? One will be a mathematical shorthand notation, similar to formal math, and the other one will be explicit notation suitable for readable definition file written in the language.
For example, using </rich_text><rich_text weight="heavy">begin</rich_text><rich_text> and </rich_text><rich_text weight="heavy">end</rich_text><rich_text> as delimiters and using keyword like </rich_text><rich_text weight="heavy">def</rich_text><rich_text>, </rich_text><rich_text weight="heavy">define</rich_text><rich_text>, </rich_text><rich_text weight="heavy">set</rich_text><rich_text>, </rich_text><rich_text weight="heavy">domain</rich_text><rich_text>, </rich_text><rich_text weight="heavy">range</rich_text><rich_text>, etc. instead of mathematical symbols, to make the code readable to any user, even without knowledge of formal set theory.
</rich_text><rich_text scale="h3">Helper Functions</rich_text><rich_text>
When I started writing definition prototypes, I realized I need to use Seq(), Fin(), P(), etc. for the definitions of some sets. For example, Fin(Chars) is the set of all finite sequences of characters, i.e. the set of all strings.
So before defining sets, I need to define these "functions". They are some kind of "generators" or "templates" which I need to define formally. Maybe I can call them </rich_text><rich_text style="italic">generators</rich_text><rich_text>. Function-like expressions which generate sets, tuples, etc.
First, I'm adding prototype definitions for the set of all sets, and the set of all tuples.</rich_text></node></node><node name="Relations of Size 3 and More" prog_lang="custom-colors" readonly="False" tags="" unique_id="95"><rich_text link="webs http://www.w3.org/TR/swbp-n-aryRelations/">http://www.w3.org/TR/swbp-n-aryRelations/</rich_text></node><node name="Named Fields" prog_lang="custom-colors" readonly="False" tags="" unique_id="97"><rich_text>What are named fields? Here's an example of defining a function and calling it in C:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This type of argument passing is called </rich_text><rich_text style="italic">positional arguments</rich_text><rich_text>. It means the passed values are matched to the function parameters by their </rich_text><rich_text style="italic">position</rich_text><rich_text> only. The order of the arguments must exactly match the order of the parameters.
Python has another form of argument passing, which may be very useful to me as a concept: </rich_text><rich_text style="italic">named arguments</rich_text><rich_text>. It means arguments are matched to parameters by </rich_text><rich_text style="italic">name</rich_text><rich_text>. Possibly also by position, but let's ignore this combined case for now. When I see this new way to pass arguments, I ask myself a question: how is it better/worse than positional arguments?
First let's see an example. This is the same C example above, slightly adapted to use named arguments:
</rich_text><rich_text justification="left"></rich_text><rich_text>
A more (or less) readable code may look like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Or like this:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="86" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="c" width_in_pixels="True">int func (int n, float r, const char* s)
{
}
int result = func (5, 3.4f, "This is a C string");</codebox><codebox char_offset="773" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="c" width_in_pixels="True">int func (int n, float r, const char* s)
{
}
int result = func (r = 3.4f, s = "This is a C string", n = 5);</codebox><codebox char_offset="828" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="c" width_in_pixels="True">int func (int n, float r, const char* s)
{
}
int result = func (r=3.4f, s="This is a C string", n=5);</codebox><codebox char_offset="846" frame_height="136" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="c" width_in_pixels="True">int func (int n, float r, const char* s)
{
}
int result = func (r = 3.4f,
s = "This is a C string",
n = 5);</codebox></node><node name="Wide Color Range" prog_lang="custom-colors" readonly="False" tags="" unique_id="61"><rich_text>When I was working with OpenGL, I read about some technique of handling a wide range of colors, not limited to the RGB scheme commonly used, where each component has two hex digits (i.e. a single byte). I remember the OpenEXR format uses them, and there was some other tool.
So here's a suggestion: why limit ourselves to plain old RGB? Who said colors can't be described in a more precise or creative manner? The language doesn't enforce any binary form, so basically, why does each component range from 0 to 255, instead of prividing a larger range like 0 to 65535? Well, maybe 65535 levels is more than a human I can see, and simply to much to be useful, but I'm going to examine the OpenEXR colors and see what I can do.</rich_text></node><node name="Object Names and References" prog_lang="custom-colors" readonly="False" tags="" unique_id="108"><rich_text>Imagine you have lots of objects and you want to put them into some order. For example, you have lots of people objects defined, and you want to make it explicit to which ones you refer.
</rich_text><rich_text scale="h3">Namespaces</rich_text><rich_text>
Just like with C++ namespaces, it may be convenient to mention a name of a set, in which the object is defined. We also have the concept of namespaces, so care should be taken when defining exactly what namespaces are. I think they're necessary for nothing but convenience.
So let's start with namespaces. Namespaces are simply sets, but they include other things. They basically could include objects, but for now I'm limiting them to include only </rich_text><rich_text style="italic">types and sets</rich_text><rich_text>. No wait...
Let's start again! Namespaces are something else. They're a lexical convention. I want to put my definitions into groups, but these groups are for language usage, and are </rich_text><rich_text style="italic">beyond</rich_text><rich_text> the scope of general-purpose reasoning. For example, I have the "set of all sets". I can't put that definition in any set, can I? But for convenient reference, I put it in a namespace. It's just a way to separate </rich_text><rich_text style="italic">names</rich_text><rich_text>. It's a concept which belongs to the </rich_text><rich_text style="italic">lexical space</rich_text><rich_text>, not to the </rich_text><rich_text style="italic">value space</rich_text><rich_text>.
But namespaces may be used fo refer to names. Think of them as an identifier saying which software, or which organization, or which person, wrote the definitions inside. They can be used for names, just like sets.
</rich_text><rich_text scale="h3">Qualified Names Using Namespaces</rich_text><rich_text>
Now we know we can use namespaces with names. How do we do that? Very simple. I suggest to use either the </rich_text><rich_text style="italic">member syntax</rich_text><rich_text> or the </rich_text><rich_text style="italic">namespace syntax</rich_text><rich_text> used by C++. Let's start with namespace syntax and consider changing it later.
Assume we define a class, and now we want to use it from another computer. We have to specify the URI of that class. But if we use many classes and types from the same namespace, typing URIs make the code ugly. Just like in XML, it is desirable to specify a URI for the namespace, and then all other URIs are generated automatically from this URI, conbined with entity names.
For example, assume we have a namespace </rich_text><rich_text style="italic">Partager</rich_text><rich_text> with the URI "</rich_text><rich_text style="italic">freedom://fr33domlover/Partager/</rich_text><rich_text>". Now we want to refer to a class within that namespace. Once we declared the namespace, instead of specifying the full URI it's not enough to specify the namespace prefix, the scope operator and the entity name. For example, if we have a class </rich_text><rich_text style="italic">Person</rich_text><rich_text> and we use the C++ scope operator (::), then referring to the Person class from the Partager namespace will be done by specifying the qualified name </rich_text><rich_text style="italic">Partager::Person</rich_text><rich_text>.
</rich_text><rich_text scale="h3">Qualified Names Using Sets</rich_text><rich_text>
Using namespaces is a good way to refer to classes and types, but namespaces alone are big, and it's sometimes much more convenient to refer to objects by a set which contains them. Either a direct set, or some superset of it. This notation is particularly useful for objects.
Let's see an example. Assume I define an object of class Partager::Person. This object has a URI which is a level4 randomly generated UUID, and its local name is JohnSmith. I know objects in C++ usually don't get camelcase names, but let's ignore those conventions for now. How do we refer to John? Assume we have a community object, and one of its properties is a set of all members, and all of them are instances of the Partager::Person class. There's also a subset of the members set, which contains only the </rich_text><rich_text style="italic">leaders</rich_text><rich_text> of the community.
Assume the community is huge, and there may be many people with the name John Smith. But specifying a URI is ugly, especially if the URI is a random UUID. And even if you have some mechanism of identity numbers, i.e. a URN scheme for identifying people, it's still not the nicest thing to specify the 9 or 10 or 11 digit number. Instead, what if we could use the fact that John Smith belongs to the </rich_text><rich_text style="italic">leaders</rich_text><rich_text>?
Assume there are just three leaders: John, Anne and Thomas. In your file, John has the local name John Smith. As long as you don't change the file, John is still a leader. So using his name is safe. What if you could use the set he belongs to, as a prefix for his qualified name?
Assume there's a Partager::Community class, and an object whose name is </rich_text><rich_text style="italic">comm</rich_text><rich_text>. For simplicity, let's ignore the scope and source of that object, and refer to it without any prefixes. That community object has a property called </rich_text><rich_text style="italic">people</rich_text><rich_text>, which is a set (enum) of people. Then, in order to refer to </rich_text><rich_text style="italic">people</rich_text><rich_text>, we probably need some operator. We can use the dot operator, i.e. use the expression </rich_text><rich_text style="italic">comm.people</rich_text><rich_text>. This creates a problem, because properties and set members now use the same operator, but I have another operator to suggest. Actually to: The -> operator and the : operator.
Assume we use . for properties and -> for sets. And assume we have the </rich_text><rich_text style="italic">leaders</rich_text><rich_text> property in addition to </rich_text><rich_text style="italic">people</rich_text><rich_text>. Then we can conveniently refer to our John using the expression </rich_text><rich_text style="italic">comm.leaders->JohnSmith</rich_text><rich_text>. Or, another option, which makes the name look somewhat like a URI reference, is to use the # operator: </rich_text><rich_text style="italic">comm.leaders#JohnSmith</rich_text><rich_text>.
</rich_text><rich_text scale="h3">Syntax Choices</rich_text><rich_text>
Alright, I made all the necessary plans for initial decisions. Now I need to choose:
1. Does each reference type (set members, class property, namespace member) need it own special operator?
2. Which operator should I use for each?
In C++, :: is used both for namespaces and for enum members, and . is used to refer to members. Actually, -> is used for that quite often too.
Hey, I have another idea! Just like with array indices, I can use the [] operator: </rich_text><rich_text style="italic">comm.leaders[JohnSmith]</rich_text><rich_text>.
Here's a list of operator suggestions:
:: : . -> [] # @ ! % /
Here's a list of uses waiting for operators:
• namespace membership
• set membership
• object property
Some examples:
Partager::comm.leaders:JohnSmith
Partager::comm.leaders->JohnSmith
Partager::comm.leaders[]JohnSmith
Partager::comm.leaders[JohnSmith]
</rich_text><rich_text foreground="#ffffffff0000">Partager::comm.leaders#JohnSmith</rich_text><rich_text>
Partager::comm.leaders@JohnSmith
Partager::comm.leaders!JohnSmith
Partager::comm.leaders%JohnSmith
Partager::comm.leaders/JohnSmith
</rich_text><rich_text style="italic">Decisions</rich_text><rich_text>:
</rich_text><rich_text style="italic">Namespace membership</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">::</rich_text><rich_text>
</rich_text><rich_text style="italic">Set membership</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">#</rich_text><rich_text>
</rich_text><rich_text style="italic">Object property</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">.</rich_text></node><node name="Classes" prog_lang="custom-colors" readonly="False" tags="" unique_id="109"><rich_text>So, it's time to start defining classes! I'll probably be working with RDF and OWL here.
</rich_text><rich_text scale="h3">Intro</rich_text><rich_text>
First, what is a class? We already have sets, don't we? John Smith can simply belong to the set of people or the set of leaders. What do we need classes for? How are they different from sets?
Assume we have a set of people, and John Smith belongs there. Now we want to define some details about John. Introduce new data to the system. After all, a UUID and a name don't say much about a person. They are just identifiers. This is where </rich_text><rich_text style="italic">classes</rich_text><rich_text> come to our aid. The define how we describe an object.
Each class is a sort of template, specifying </rich_text><rich_text style="italic">how</rich_text><rich_text> a certain group of objects should be described. How each such object would be defined. All these objects must belong to a given set, which is a property of a class.
Each class also comes with a built-in type. This type can perform a match between a URI to an object, and between a qualified or local name, to an object. So there's no need to define types for classes. Types usually match numbers, or other structured strings, to some real/abstract objects.
So, all we need is a name, a URI and a list of properties. How do we define those properties? Good question.
</rich_text><rich_text scale="h3">Properties</rich_text><rich_text>
Basically, once we are able to define objects, the next thing we want to do is to say things about these objects. Subject, predicate, object. For example, "John has 100 coins". We have a subject, John. We have a relation, "has coins". And we have the object, specifying how many coins John has.
Unlike in programming languages, relations have a deep meaning here. Like in RDF. Properties cannot just be used randomly. They must be defined properly first. In the future we will see shortcut notations which allow defining properties in-place, but it's just a shortcut and not a full proper definition.
How do we define a relation? Relations have several properties we can set. I'll open some RDF and OWL resources to help me choose all the useful settings I need.
First, each relation has a </rich_text><rich_text style="italic">domain</rich_text><rich_text> and a </rich_text><rich_text style="italic">range</rich_text><rich_text>.
Each relation can be </rich_text><rich_text style="italic">reflexive</rich_text><rich_text>, </rich_text><rich_text style="italic">transitive</rich_text><rich_text> and </rich_text><rich_text style="italic">symmetric</rich_text><rich_text>.
Each relation can have </rich_text><rich_text style="italic">sub-relations</rich_text><rich_text>, </rich_text><rich_text style="italic">super-relations</rich_text><rich_text>, and an </rich_text><rich_text style="italic">inverse</rich_text><rich_text> relation.
A </rich_text><rich_text weight="heavy">relation</rich_text><rich_text> is just a subset of </rich_text><rich_text style="italic">D x R</rich_text><rich_text>, with D being the domain and R being the range. A </rich_text><rich_text weight="heavy">property</rich_text><rich_text> is a relation referring to a given class or specific object. When we define a proper independent definition, then it's a relation. When we assign it to a class, then it's a property.
</rich_text><rich_text scale="h3">Defining Relations</rich_text><rich_text>
We will define a relation using the </rich_text><rich_text style="italic">relation</rich_text><rich_text> keyword. Just like with sets, this may be a good definition:
</rich_text><rich_text style="italic">relation hasCoins:
domain Person
range Natural
description "Specifies the amount of coins a person has"</rich_text><rich_text>
There are some important things to notice here:
• </rich_text><rich_text style="italic">reflexive</rich_text><rich_text>, </rich_text><rich_text style="italic">transitive</rich_text><rich_text> and </rich_text><rich_text style="italic">symmetric</rich_text><rich_text> and only relevant if range=domain (or at least they have a common subset)
• Usually </rich_text><rich_text style="italic">sub-relations</rich_text><rich_text> are specified while </rich_text><rich_text style="italic">super-relations</rich_text><rich_text> are inferred from that
• </rich_text><rich_text style="italic">inverse</rich_text><rich_text> makes sense only for a non-primitive range
</rich_text><rich_text scale="h3">Interoperability with RDF and OWL</rich_text><rich_text>
The language does not try to be a separate standalone alternative to RDF and OWL. It is preferred that all data translates directly to RDF or OWL ontologies, and definition files translate to RDF resources.
Therefore, while the simple syntax of the language develops, it allows usage of RDF and OWL resources. This is done by referring to them using a URI through a special property, which will probably be called </rich_text><rich_text style="italic">rdf</rich_text><rich_text>.
In the future I'll make more decisions regarding the syntax. It's a waste of time and effort, to try to map OWL and RDF to my language. Instead, properties, classes and objects will simply be referred using a URI.
</rich_text><rich_text scale="h3">Defining Classes</rich_text><rich_text>
A class is defined using the </rich_text><rich_text style="italic">class</rich_text><rich_text> keyword, and must have some required properties. Every class has to belong to a set. Therefore every class specifies a set in the definition. I suggest for now, that the keyword </rich_text><rich_text style="italic">in</rich_text><rich_text> is used for that, e.g. </rich_text><rich_text style="italic">class Person in People</rich_text><rich_text>.
Since classes may have their own properties, I consider adding the keyword </rich_text><rich_text style="italic">property</rich_text><rich_text> as the way to mark properties. This way regular properties are attached to the class, while </rich_text><rich_text style="italic">property</rich_text><rich_text> properties are attached to the objects. Another option for a shorter notation is to use the @ operator instead of the </rich_text><rich_text style="italic">property</rich_text><rich_text> keyword.
There are 3 kinds of possible properties:
• Named language relations
• Anonymous properties
• RDF relations
Any property can be specified using a URI or a local name. Anonynous properties simply specify a name and a range. RDF relations specify a URI (or a qname, if a namespace prefix has been declared) and an object.
For all 3 types, the property value can be anonymous or named. It is also possible for the value to be a property of an existing named object (this feature should be treated under </rich_text><rich_text link="node 95">Relations of Size 3 or More</rich_text><rich_text>).</rich_text></node></node><node name="Theory" prog_lang="custom-colors" readonly="False" tags="" unique_id="98"><rich_text></rich_text><node name="Theory and Ideas" prog_lang="custom-colors" readonly="False" tags="" unique_id="2"><rich_text>In parallel to studying XSD datatypes, and taking other knowledge I have into consideration, I'm going to start offering and defining datatypes for the language.
</rich_text><rich_text scale="h3">Previous Existing Examples</rich_text><rich_text>
These are the examples I know. This is the knowledge I have, on which I base the datatypes:
• C/C++ types
• Java types
• XSD types
Let's start with guidelines, then maybe offer some ideas and thoughts, and finally start suggesting datatypes.
</rich_text><rich_text scale="h3">Guidelines</rich_text><rich_text>
</rich_text><rich_text underline="single">Minimalism and Simplicity</rich_text><rich_text>: Don't add language types which can be derived from other types. Instead, define only the ones you must, and then you can supply a "system library" which offers convenient derived types. Make the language small the simple, and add the versatile functionality as a language tool.
</rich_text><rich_text underline="single">No Technical Terms</rich_text><rich_text>: Don't mix the mathematical foundations into the language. For example, don't enforce use of mathematical symbols like ℝ, ℚ, ℤ for sets, and don't let the basic technical definitions leak into the practical usage of the language.
</rich_text><rich_text underline="single">Consider Home Users</rich_text><rich_text>: It's very important, enough to have two guidelies! Consider home users. Consider users who just want to arrange and organize their life. Even the ones who don't know or don't remember what ℝ is. Make it simple, self-documenting as much as possible, and allow a simple user avoid advanced features, and easily ignore their existence.
</rich_text><rich_text underline="single">Independent Complexity Levels</rich_text><rich_text>: Don't mix complex advanced features with simple ones. Allow a simple user to use only simple features and safely ignore the rest, and allow an advanced user make effective use of advanced features without having inconvenient barriers between simple features and advanced features.
</rich_text><rich_text scale="h3">Ideas and Thoughts</rich_text><rich_text>
</rich_text><rich_text underline="single">i18n</rich_text><rich_text>: For properties and classes, but also for types, make a built-in system for giving translated names to objects and definitions, so that users are able to understand them easily, and GUI apps can directly use them.</rich_text></node><node name="Primitive Type Theory" prog_lang="custom-colors" readonly="False" tags="" unique_id="42"><rich_text>Primitive types are mappings from UTF-8 character strings to other sets. I mean sets in the mathematical sense. Let's define it with some mathematics.
</rich_text><rich_text scale="h3">Set of All Characters</rich_text><rich_text>
On the theoretical side, not yet looking at practical issues, let's define the set of all Unicode characters, i.e. all characters which can be expressed in UTF-8 (also UTF-16, etc., but it doesn't matter right now).
U = {c : c is a Unicode character}
Some characters exist in ASCII, such as R, while others don't, such as ℝ.
</rich_text><rich_text scale="h3">Strings</rich_text><rich_text>
Then what is a string? It is a finite sequence of characters from U. U is called the </rich_text><rich_text style="italic">alphabet</rich_text><rich_text> of strings. Note that the sequence may have any natural length, including zero, but it has no be finite. In mathematical notation, the set of all strings is:
S = { <c</rich_text><rich_text scale="sub">1</rich_text><rich_text>, ... , c</rich_text><rich_text scale="sub">n</rich_text><rich_text>> : nϵℕ, ∀i, c</rich_text><rich_text scale="sub">i</rich_text><rich_text>ϵU }
Or we can define S as the union of all powers (cartesian product with itself) of the set U:
S = ⋃(U</rich_text><rich_text scale="sup">n</rich_text><rich_text>) for all nϵℕ
Both definitions denote exactly the same set.
A </rich_text><rich_text weight="heavy">string</rich_text><rich_text> is, therefore, a member of the set S.
</rich_text><rich_text scale="h3">Relation to Computer Representations</rich_text><rich_text>
Some types have a common/standard computer representation, such as floating-point numbers (float, double, long double) and integers (char/byte, short, int, long, long long). An important question is: if the language doesn't specify the binary forms of the datatypes, and only the abstract concept represented by the type, does it need to enforce any binary form?
And another question, </rich_text><rich_text style="italic">should</rich_text><rich_text> the language specify a binary form?
XSD mentions binary forms, but since the language is just the text, I don't see a reason to mention them. The language may offer types which are restricted to the subset of ℝ representable by common binary forms like float and int, but this is just for convenience, and it won't actually enforce the usage of any binary form. It is the choice of a software tool working with the definition file, how to translate and text into an in-memory representation. In any case, the definition file remains the "canonical" representation of the definitions.
</rich_text><rich_text scale="h3">Primitive Types</rich_text><rich_text>
A primitive type is a mapping between strings and some other set. This mapping is univalent, i.e. each string has one and only one matching member of the other set, which makes such a mapping a </rich_text><rich_text weight="heavy">function</rich_text><rich_text> in the mathematical sense.
The language itself is a tool for creation of text documents, which means it contains only the string, and not the actual members of the Range set. But the language specification explains how the mapping is done, so that anyone who reads the text, a human or a computer, can easily infer from the text which member of the range is represented by the string.
Mathematically, a primitive type can be thought of as a function from S or a subset of it, to some other set. For simplicity, let's assume A can be any set, although there are probably some extreme cases which don't make sense. For example, making A be the set of all primitive types may create a problem, because I currently don't intend to refer to types like any other class or object. Anyway, like I said, let's ignore these cases for now and define primitive types like this:
Let A be a (non-empty) subset of S, i.e. A⊆S, (A≠∅)
Let B be some (non-empty) set
Let </rich_text><rich_text style="italic">𝑓</rich_text><rich_text> be a function from A to B, i.e. </rich_text><rich_text style="italic">𝑓</rich_text><rich_text>: A → B
Then </rich_text><rich_text style="italic">𝑓</rich_text><rich_text> is a </rich_text><rich_text weight="heavy">primitive type</rich_text><rich_text>.
</rich_text><rich_text scale="h3">Sets</rich_text><rich_text>
Assume Jane wants to define a new type. Then what details does she need to mention about it? Basically, three things:
• The set A, which is a subset of S which serves as the domain of the function </rich_text><rich_text style="italic">𝑓</rich_text><rich_text>, i.e. Dom(</rich_text><rich_text style="italic">𝑓</rich_text><rich_text>)
• The set B, which is the range of </rich_text><rich_text style="italic">𝑓</rich_text><rich_text>, i.e. Range(</rich_text><rich_text style="italic">𝑓</rich_text><rich_text>)
• An explanation how A is mapped to B, which allows one to take some aϵA and exactly determine </rich_text><rich_text style="italic">𝑓</rich_text><rich_text>(a)
Since the type definition is on the language level, and not program level, Jane doesn't need to supply any code or any program which does the actual conversion from A to B. She just needs to explain how it is done, so that all implementations will understand it and do the same conversion.
Currently it's hard to tell whether it's useful to allow conversion methods to be reused, or to have semantic value, so for now let's concentrate on the other two things: the sets A and B. How does Jane specify them?
The easiest approach, like with the mapping function, is to have Jane provide a verbal explanation. If there's mathematical notation which describes the set, Jane can add it too as an embedded image or PDF or a Latex expression. But if Jane uses a set already used for other types, providing a consistent mechanism for specifying sets may allow creation of interesting language features or applications through the software which works with the definition files.
I'd like to suggest such a mechanism here. A scheme for specifying sets, and a list of some built-in common sets. These sets don't actually have to be built-in, but then I won't be able to define primitive types using these sets, so it makes sense to define them as built-in sets belonging to the "standard library", and define datatypes using them.
As I add new primitive types, I'll also add the sets required by their definition. But before that, I definitely need to make a design of the set definition mechanism. How are sets defined by the user? Sets are an abstract notion. They are just groups of "elements or "things", and can be anything. They can even contain sets, and even sets of sets. In theory, a set can even be defined to contain itself, e.g. "the set of all sets".
As a result of the infinitely wide range of sets, they will only serve as an abstract description of a concept. Just like NEPOMUK ontologies try to organize different types of content into concrete semantic representations, the sets in my definition language try to gradually create a "library" of sets representing common concepts and real-life sets, like "all the people who ever existed" or "all the people in the whole space-time, i.e. the ones who existed, exist or will exist." Or "all the languages in the world", "all the triangles in the world", "all countries in the world", "all the people who currently live in Israel", etc.
This includes finite sets, like "all countries in the world", and infinite sets, like "all the complex numbers".
</rich_text><rich_text scale="h3">Definition Mechanism for Sets</rich_text><rich_text>
Defining a set is somewhat like defining a new RDF class or ontology: all you define is an abstract concept, but once you define it, everyone understands what it means and integrates it into existing models. In my definition language, the set is just a formalization of an abstract concept. Documentation and specification are responsible for providing an exact definition, but the rest is up to human beings to interpret. Just like a computer doesn't understand an ontology, but can recognize and parse documents written in formally defined ontologies.
Since things like {n>5 | nϵℕ} don't exist until we define the set ℕ, we must have a way to define a set axiomatically, without using any existing definition. It's possible to define natural numbers using set theory, as explained in </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/Natural_number">http://en.wikipedia.org/wiki/Natural_number</rich_text><rich_text>. The standard construction is:
0 = {}
1 = {0} = {{}}
2 = {0, 1} = {{}, {{}}}
3 = {0, 1, 2} = {{}, {{}}, {{}, {{}}}}
And so on. But construction is just a theoretical formal way to construct new concepts from existing concepts, and numbers can be thought of as common and elementary enough to stand for themselves. Numbers existed long before set theory, so I feel there's no need to formally define them using set theory notations.
</rich_text><rich_text underline="single">Abstract Definition</rich_text><rich_text>
An abstract definition of a set describes it using words. For example, there is no direct mathematical way to define the set of all people in the universe. Such as set may be defined like this:
X = {all the people in the words}
This kind of definition is an </rich_text><rich_text style="italic">abstract definition</rich_text><rich_text>. This kind of definition is called in mathematics an </rich_text><rich_text style="italic">intensional definition</rich_text><rich_text>. Here's an explanation from Wikipedia: "In logic and mathematics, an intensional definition gives the meaning of a term by specifying all the properties required to come to that definition, that is, the necessary and sufficient conditions for belonging to the set being defined."
An example from Wikipedia: "A is the set whose members are the first four positive integers". This is exactly the set {1, 2, 3, 4}.
Such a definition, therefore, contains just words. A verbal description of the unique characteristics of the members of the set. Now I need to define the syntax for such a definition. I'm adding a new syntax issue page under </rich_text><rich_text link="node 18">Syntax Rules</rich_text><rich_text>, in which I'll develop the exact syntax.
</rich_text><rich_text justification="left"></rich_text><rich_text underline="single">Explicit Definition</rich_text><rich_text>
This is the </rich_text><rich_text style="italic">extensional definition</rich_text><rich_text> of sets, i.e. a definition which specifies the members. Ellipsis (...) may also be used when it's obvious which members are missing, as in {1,2,...,100}. Example:
X = {1, 2, 3, 4}
Y = {red, yellow, green}
Z = {2, 4, 6, 8... 1000}
This kind of definition has a problem which an intensional definition doesn't have: You can't always specify the elements themselves. For example, Jane can describe N, the natural numbers, as the "set of all natural numbers". This is a textual/verbal description, not mentioning the members themselves. Now imagine Jane defines the same set like this:
N = {0, 1, 2, 3, 4...}
Now there's a problem, because "0", "1", "2" and so on, they are </rich_text><rich_text weight="heavy">strings</rich_text><rich_text>. But since N is a special case, in which we use the numbers before we even define the set, I want to look at another example.
Assume Jane already defined N to be the set of natural numbers. Now she wants to define a set A containing the numbers 2, 3 and 9. In mathematical notation, it would be defined like this:
</rich_text><rich_text style="italic">A = {2, 3, 9}</rich_text><rich_text>
But 2, 3 and 9 are also characters, and strings of length 1. What if Jane defines A like this:
</rich_text><rich_text style="italic">A = {two, three, nine}</rich_text><rich_text>
Or like this:
</rich_text><rich_text style="italic">A = {"2", "3", "9"}</rich_text><rich_text>
Or like this:
</rich_text><rich_text style="italic">A = {"two", "three", "nine"}</rich_text><rich_text>
What do all these definitions mean exactly? Let's see an example without numbers:
</rich_text><rich_text style="italic">A = {Totem, Empathy, Evolution}</rich_text><rich_text>
This one doesn't involve numbers. Assume we already have the whole primitive type system, and now Jane defines the set A. Is A a set containing three strings? Or three English words? Or three computer programs? Clearly, words can mean many things, and therefore, there's no way to tell whether Empathy refers to the word or to the program. You could say the first letter being in uppercase can make the difference, but if I take an English word with two meanings, such as </rich_text><rich_text style="italic">line</rich_text><rich_text>, then there's really no way to tell.
I can discuss this issue further, but I'll do it under the Syntax Rules pages. Let's proceed to the next set definition mechanism.
</rich_text><rich_text underline="single">Set-Builder Notation</rich_text><rich_text>
This kind of definition can combine semantic text description, existing sets are conditions. Here's an example from Wikipedia:
F = {n</rich_text><rich_text scale="sup">2</rich_text><rich_text> − 4 : n is an integer; and 0 ≤ n ≤ 19}
The colon (:) means "such that". Sometimes a vertical bar (|) is used instead. According to Wikipedia, set-builder notation is defined like this:
Let Φ(x) be a formula in which x appears free. Set builder notation has the form {x : Φ(x)} (or {x | Φ(x)} according to the international standard ISO 31-11 using the vertical bar instead of the colon), denoting the set of all individuals in the universe of discourse satisfying the formula Φ(x), that is, the set whose members are every individual y such that Φ(y) is true: formally, the extension of the predicate. Sometimes the universe of discourse is established within the notation; writing {x ∈ U : Φ(x)} establishes that the universe of discourse is U for purposes of the set being built, though this is done at the expense of making the set membership operator ambiguous in the formal set builder notation. Set builder notation binds the variable x and must be used with the same care applied to variables bound by quantifiers.
Another variation on set-builder notation replaces the single variable x with a term T which may include one or more variables, combined with functions acting on them. So instead of {x : Φ(x)}, we would have {T : Φ(x1 ... xn)}, where T is a term involving variables x1 through xn. For example:
• {2</rich_text><rich_text style="italic">n</rich_text><rich_text> : </rich_text><rich_text style="italic">n</rich_text><rich_text> ∈ </rich_text><rich_text weight="heavy">N</rich_text><rich_text>}, where </rich_text><rich_text weight="heavy">N</rich_text><rich_text> is the set of all natural numbers, is the set of all even natural numbers.
• {</rich_text><rich_text style="italic">p</rich_text><rich_text>/</rich_text><rich_text style="italic">q</rich_text><rich_text> : </rich_text><rich_text style="italic">p</rich_text><rich_text>,</rich_text><rich_text style="italic">q</rich_text><rich_text> ∈ </rich_text><rich_text weight="heavy">Z</rich_text><rich_text>, </rich_text><rich_text style="italic">q</rich_text><rich_text>≠0}, where </rich_text><rich_text weight="heavy">Z</rich_text><rich_text> is the set of all integers, is the set of all rational numbers (</rich_text><rich_text weight="heavy">Q</rich_text><rich_text>).
Some examples from programming languages: </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/List_comprehension">http://en.wikipedia.org/wiki/List_comprehension</rich_text><rich_text>.
</rich_text><rich_text justification="left"></rich_text><rich_text scale="h3">Defining Primitive Types</rich_text><rich_text>
As I said earlier, I don't decide yet, whether the mapping function can/should be specified in a mathematical form, or a textual description is always enough. I'm adding this issue to the Syntax Rules.
With the mapping function in our mind, or on paper, we want to define a primitive type. We thus need to specify the sets </rich_text><rich_text style="italic">A</rich_text><rich_text> and </rich_text><rich_text style="italic">B</rich_text><rich_text>, and describe the function </rich_text><rich_text style="italic">f</rich_text><rich_text>.
How do we do that?
Let's make the follwing simple assumption. Assume we never define a set locally. In other words, all the sets we need are already defined! So we need to do three things:
• specify the already-defined set A
• specify the already-defined set B
• specify the mapping function f
Let's think, how do we specify the function? The language itself doesn't do any conversion, but a computer doesn't understand a textual description. So if we define a type </rich_text><rich_text weight="heavy">text</rich_text><rich_text> to be a type from </rich_text><rich_text style="italic">S</rich_text><rich_text> to </rich_text><rich_text style="italic">S</rich_text><rich_text>, with the description "maps a string to itself", the computer has no idea how to determine which value is denoted by a given string. Even in such a simple case, in which the value if that string itself, the computer can't tell.
Another example, assume we define a type </rich_text><rich_text weight="heavy">natural</rich_text><rich_text> to be a function as follows:
Domain: all the finite sequences of digits 0-9, in which 0 can be first only if the whole sequence is "0"
Range: all finite natural numbers
Function: map each string to the natural number which has a decimal representation identical to this string
This looks obvious. Any human being with elementary knowledge of math can look at a written number tell exactly which number it is. For example, if I show you the text "2", you this is the number "two". The one representing a pair. An element, another element, and that's all. Very simple, isn't it?
Now assume Jane defines the </rich_text><rich_text style="italic">natural</rich_text><rich_text> type like this, and the computer needs to do something with numeric data. For example, parse a definition file and then parse a due date of a task. When the computer gets a string representing an integer, how will it convert it into a binary representation? Can the computer be sure I use base 10? Can the computer be sure Jane didn't specify some unique rules like "map each string representing the number n, to the number 3n-1"? No, it can't be sure. Because it's a textual description.
In the case of an integer, the computer can implement a "special case". Actually, since all the primitive types are predefined, the computer can simply have predefined functions for mapping strings to all the relevant binary forms (integers, floating point, strings, booleans). But another option is to supply a formal definition.
I can supply an axiomatically predefined function which maps digits 0-9 and A-Z to numbers. Then defining natural number mapping in a formal manner is very easy.
The third option is that I supply some mechanism for referring to numbers. But that would defeat the whole purpose, since a notation like </rich_text><rich_text style="italic">number(5)</rich_text><rich_text> means that the language internals are already able to map "5" to the number five, so the natural next question is why we started defining integer types in the first place, as it seems we already have them.
I'll think about it further under Syntax Rules.</rich_text><encoded_png anchor="Explicit Definition" char_offset="8532">anchor</encoded_png><encoded_png anchor="Defining Primitive Types" char_offset="12336">anchor</encoded_png></node><node name="More Type Theory" prog_lang="custom-colors" readonly="False" tags="" unique_id="110"><rich_text scale="h3">Updates to Types</rich_text><rich_text>
After making plans and writing prototypes and drafts, I decided to consider a new definition for types.
Currently, types are mappings between strings and objects. They are defined explicitly using existing sets. But after seeing how things work in practice, I realized that types defitions are obvious for primitive types, and auto-generated for classes. So explicit type definitions just add clutter and don't bring any advantages or power to the language.
So I decided to try to remove them. Types will exist as a concept, but will not be explicitly defined. Instead, the mappings for primitive types will be built-in.
Since I'm going to use set names directly, allow me to take a moment to update the prototype files... done.
</rich_text><rich_text scale="h3">Updates to Sets</rich_text><rich_text>
For similar reasons, it feels like sets are somewhat unnecessary formal clutter. Just like RDF uses simple primitive types, and everything else is a class, I can do that too. In other words, avoid all the mess of sets and directly work with classes and object descriptions.
Idea: for non-programmers, touching RDF is much too technical. So any connection of the language with RDF is a responsibility of programmers and ontology designers.
What the user needs to do is define properties and define objects. Properties may be connected to RDF properties, so that programmers can create language schemas which match RDF ontologies, but they don't have to.
In any case, the user can define the range and cardinality of a given property. Any RDF and OWL property is supported for classes and properties, but since I don't want simple users to work with RDF and OWL directly, a convenient set of properties and classes will be supplied with documentation and examples, making the usage simple and easy.
Considering these changes, I'm writing another prototype of the sets, now defining them as classes and changing some of the property names.</rich_text></node></node><node name="Sets v1" prog_lang="custom-colors" readonly="False" tags="" unique_id="37"><rich_text>namespace std:
set Namespaces:
description "The set of all namespaces"
id "freedom://idan.std.Namespaces"
set Sets:
description = "The set of all sets (not including this one)"
definition = {*}
set SetsOfSets:
description = "The set of all sets whose all members are sets too (not including this one and Sets)"
superset = Sets
definition = {X in Sets : for x in X (x in Sets)}
set Tuples:
description = "The set of all tuples"
definition = <*>
set Chars:
description = "The set of all unicode characters"
set Strings:
description = "The set of all finite sequences of characters"
definition = Fin(Chars)
namespace math:
set R:
description = "The set of real numbers"
symbol = ℝ
set Q:
description = "The set of rational numbers"
symbol = ℚ
superset = R
set Z:
description = "The set of integers"
symbol = ℤ
superset = Q
set N:
description = "The set of natural numbers"
symbol = ℕ
superset = Z
set C:
description = "The set of complex numbers"
symbol = ℂ
set H:
description = "The set of quaternions"
symbol = ℍ</rich_text></node><node name="Sets v2" prog_lang="custom-colors" readonly="False" tags="" unique_id="111"><rich_text>namespace std:
set Namespaces:
description "The set of all namespaces"
id "freedom://idan.std.Namespaces"
set Sets:
description "The set of all sets (not including this one)"
definition {*}
set SetsOfSets:
description "The set of all sets whose all members are sets too (not including this one and Sets)"
superset Sets
definition {X in Sets : for x in X (x in Sets)}
set Tuples:
description "The set of all tuples"
definition <*>
set Classes:
description "The set of all classes"
set Relations:
description "The set of all language relations"
set Chars:
description "The set of all unicode characters"
set Strings:
description "The set of all finite sequences of characters"
definition Fin(Chars)
namespace math:
set Quaternion:
description "The set of quaternions"
symbol ℍ
alias H
set Complex:
description "The set of complex numbers"
symbol ℂ
superset Quaternion
alias C
set Real:
description "The set of real numbers"
symbol ℝ
superset Complex
alias R
set Rational:
description "The set of rational numbers"
symbol ℚ
superset Real
alias Q
set Integer:
description "The set of integers"
symbol ℤ
superset Rational
alias Z
set Natural:
description "The set of natural numbers"
symbol ℕ
superset Integer
alias N</rich_text></node><node name="Sets v3" prog_lang="custom-colors" readonly="False" tags="" unique_id="112"><rich_text>namespace std:
class Namespaces:
comment "The set of all namespaces"
id "freedom://idan.std.Namespaces"
class Sets:
comment "The set of all sets (not including this one)"
definition {*}
class SetsOfSets:
comment "The set of all sets whose all members are sets too (not including this one and Sets)"
superset Sets
definition {X in Sets : for x in X (x in Sets)}
class Tuples:
comment "The set of all tuples"
definition <*>
class Classes:
comment "The set of all classes"
class Relations:
comment "The set of all language relations"
class Chars:
comment "The set of all unicode characters"
class Strings:
comment "The set of all finite sequences of characters"
definition Fin(Chars)
namespace math:
class Quaternion:
comment "The set of quaternions"
symbol ℍ
alias H
class Complex:
comment "The set of complex numbers"
symbol ℂ
superset Quaternion
alias C
class Real:
comment "The set of real numbers"
symbol ℝ
superset Complex
alias R
class Rational:
comment "The set of rational numbers"
symbol ℚ
superset Real
alias Q
class Integer:
comment "The set of integers"
symbol ℤ
superset Rational
alias Z
class Natural:
comment "The set of natural numbers"
symbol ℕ
superset Integer
alias N</rich_text></node><node name="Generators" prog_lang="custom-colors" readonly="False" tags="" unique_id="106"><rich_text>namespace std:
generator Pwr:
description = "The set of all subsets of a given set"
domain = Sets
range = SetsOfSets
f(X) = {Y : Y contained in X}
generator Seq:
generator Fin:</rich_text></node><node name="Type Hierarchy" prog_lang="custom-colors" readonly="False" tags="" unique_id="10"><rich_text>I'll be maintaining a type hierarchy and update it as I write:
• (Nothing)
</rich_text></node></node></node><node name="New Language Plan" prog_lang="custom-colors" readonly="False" tags="" unique_id="113"><rich_text>I decided to drop the complicated ideas and the duplication of RDF, and write a new plan for a simplt compact easy to implement language.</rich_text><node name="Plan Draft" prog_lang="custom-colors" readonly="False" tags="" unique_id="114"><rich_text scale="h3">The Idea</rich_text><rich_text>
I just realized something simple yet important.
Most of the language comes from RDF anyway, so why do I need do define a whole new language? Here's a suggestion: The language allows to define three things:
• properties
• classes
• objects
Each class and property can be either a hand-written one, or an RDF-mapped one. If an entity is mapped to RDF, then there's no need to define it in the language.
First let's see how we define new relations.
</rich_text><rich_text scale="h3">Relations, Classes and Objects</rich_text><rich_text>
A relation not mapped to RDF is user-defined and thus doesn't need much complexity. Actually, maybe I don't even need to allow explicitly defining it! Properties can be defined directly in classes. The only issue is the range of a property. I can use types from XSD and Python, without too much fancy definitions.
The ways of defining types are the same as in XSD, but with much easier syntax and an easy ability to specify object references.
It may be enough for the beginning to just specify the types integer, real and string. And I can add date and time types, trying to make them easier to use than the ugly XSD types. Then, restriction can be done using regex on text, enumerations and ranges. And object references are possible too, by specifying the class serving as the range of the property. It can be an RDF class of a language class. The point is, you have to specify a local name of a URI.
Then classes can be defined. They can either extend existing classes or be plain new classes
Objects can be defined using RDF classes or language classes. All their required properties much be specified, and then their optional ones, if the users wants them. Simple, isn't it?
</rich_text><rich_text scale="h3">Graphs</rich_text><rich_text>
Usually the verbosity of defining objects one-by-one is not much for usage in plain text formats, and requires special software. The language solves the problem by allowing a special syntax for defining objects:
• One special specified property is expressed through indentation without any property name
• One special specified property is on the first line without the property name
• Object IDs are written after # operator, and may be omitted
In order to mark a beginning of a graph, a line needs to start with a keyword </rich_text><rich_text style="italic">graph</rich_text><rich_text>, the graph name and a colon. Then the graph has to state the two special properties are used for </rich_text><rich_text style="italic">header</rich_text><rich_text> and </rich_text><rich_text style="italic">child</rich_text><rich_text>. They can be URIs or some RDF qnames or local names.
Let's see an example.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Another important feature is that strings in headers don't have to use the "". IDs can be dropped by making a space right after the # character.
And another one, is to be able to specify a property for all objects in a range.
UPDATE: Another useful graph feature may be to specify task completion. This is done by adding a box [ ], i.e. [ then space then ], after and index and before the task text. This box supports a status property. This property cal be specified by the </rich_text><rich_text style="italic">state</rich_text><rich_text> property under </rich_text><rich_text style="italic">graph</rich_text><rich_text>, together with </rich_text><rich_text style="italic">header</rich_text><rich_text> and </rich_text><rich_text style="italic">child</rich_text><rich_text>. If the specified property is of type </rich_text><rich_text style="italic">boolean</rich_text><rich_text>, then in addition to </rich_text><rich_text style="italic">true</rich_text><rich_text>/</rich_text><rich_text style="italic">false</rich_text><rich_text> it's possible to use space and X as false and true respectively.
</rich_text><rich_text scale="h3">Reference Example</rich_text><rich_text>
I'm going to define some task-related things, ignoring RDF for now. Everything I write will be defined with explicit notation, and with shorthand alternatives where appropriate.
The things I'm going to define are:
• Topic
• Task
• Timeline
• Topic graph
• Task graph
• Timeline objects
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h3">Improvements</rich_text><rich_text>
Now I have a whole example to look at, and find points which need further definition and polishing.
First, it should be possible to define properties externally. In the weekday example, I chose to define it explicitly outside because it's a long definition which would make the code ugly. Properties can be defined, externally and in-place, using these techniques:
• union
• regex
• range
• enum
It should also be possible to link classes, properties and objects with RDF resources, local entities and external entities.
First, let's make a temporary decision: Each file has to start with a namespace declaration. That declaration also brings other namespaces using the </rich_text><rich_text style="italic">using</rich_text><rich_text> keyword. The file namespace specifies a URI or the keyword </rich_text><rich_text style="italic">auto</rich_text><rich_text> which lets the system allocate a proper URI.
Here's a namespace example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And this one uses an automatic URI:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now the </rich_text><rich_text style="italic">using</rich_text><rich_text>s can be added. First, they should be able to point to other local namespaces:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Then, they should be able to point to a language namespace using a URI:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And, they also should be able to point to RDF namespaces:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we can use some external resources:
• link our classes with RDF classes
• link our properties with RDF properties
• refer to RDF objects
Here's a Person class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now let's link it with an RDF class. Let's link with... foaf:Person! It should be the standard person class in RDF. Here's how it's done, first let's use a URI directly:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The same thing, now using a prefix:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In the same manner we can link properties:
</rich_text><rich_text justification="left"></rich_text><rich_text>
We also want to refer to RDF objects:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Another issue is class extension. It's possible to extend an RDF class and a language class. It's done by specifying a </rich_text><rich_text style="italic">base</rich_text><rich_text> on the </rich_text><rich_text style="italic">class</rich_text><rich_text> line:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h3">Update to # and //</rich_text><rich_text>
I decided to change both tokens. / will not be used instead of #, and # will be used instead of //.
</rich_text><rich_text scale="h3">File Extensions</rich_text><rich_text>
The extensions depend on the name of the language. Currently the only suggestion is Idan. Any other ideas? Hmmm... maybe some acronym. Class, Object, Relation, Language. CORL? Semantic Desktop Language. Slide?
I added the ideas to the </rich_text><rich_text link="node 35">ideas page</rich_text><rich_text>. Anyway, for now I'll refer to the name as </rich_text><rich_text style="italic">[name]</rich_text><rich_text>. We can use one single prefix for all files, but instead we can make it clear what's in the file by adding suffix letters.
The types of files expected are:
• classes file
• objects file
• graph file
The name doesn't enforce anything: it's just a convenient way to know what's inside. Just like any XML file can be suffixed </rich_text><rich_text style="italic">.xml</rich_text><rich_text> but it doesn't say much, while using a specific name like </rich_text><rich_text style="italic">.note</rich_text><rich_text> or </rich_text><rich_text style="italic">.task</rich_text><rich_text> says much more.
The standard extensions will be:
• .[name] general-purpose
• .[name]c classes file
• .[name]o objects file
• .[name]g graph file
</rich_text><rich_text scale="h3">Simplicity and RDF</rich_text><rich_text>
As you may have noticed, this whole new language plan drops almost all features I planned. And specifically, it drops many useful features of RDF. For example, there's no way to specify sub-properties and property descriptions. Actually, most of the RDF features, besides the basic notions of classes, objects and relations, are missing.
I removed them because my intention is that any data too complicated to manage by hand on plain text is moved to software-managed RDF. If advanced features are needed, it's a sign that one should make that step and move to RDF.
But the language does provide means to link classes, properties and objects to RDF, so once the advanced RDF/OWL features are used, it's easy to use them from within the language without writing any bindings. Just use </rich_text><rich_text style="italic">import</rich_text><rich_text> to import the namespace prefix, and use the </rich_text><rich_text style="italic">link</rich_text><rich_text> or </rich_text><rich_text style="italic">base</rich_text><rich_text> properties to specify connections to RDF.
</rich_text><rich_text scale="h3">Property Cardinality</rich_text><rich_text>
As you probably noticed, there's some usage of property cardinality. I use {} after the class/type name to indicate a set. This is how cardinality works:
[class] 0 or 1
required [class] 1
[class] {} unlimited
[class] {3:} at least 3
[class] {:7} at most 7
[class] {3:7} between 3 and 7 inclusive
[class] {5} exactly 5
Note that </rich_text><rich_text style="italic">required</rich_text><rich_text> is </rich_text><rich_text weight="heavy">not allowed</rich_text><rich_text> to be specified when {} is used. Also, the </rich_text><rich_text style="italic">required</rich_text><rich_text> keyword is just a shorthand for {1:1}, which means the following two lines are equivalent:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Once cardinality is specified, there are two ways to specify the actual object properties: On a single line using commas as separators, or on separate lines. At least for now, the language will not limit the combination of two ways, i.e. it's possible to write some objects on separate lines, and then some more on a single line.
This is the single-line syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is the multi-line syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And this is an example for combined syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h3">Types</rich_text><rich_text>
Like I said earlier, a type can be formed through:
• union
• regex
• range
• enum
Types can either be defined directly inside a class definition, or on a separate line starting with </rich_text><rich_text style="italic">property</rich_text><rich_text>. Let's start making a list of built-in types:
• integer
• real
• string
• boolean
• date (can map internally to an object with day/month/year properties)
• time
• uri (maybe not necessary, just adding, you know, just in case)
I believe all the other types can be derived from these, without any special features. Also, the date formats requires some planning. Maybe I'll add a date_format property under </rich_text><rich_text style="italic">namespace</rich_text><rich_text> which will specify the format used throughout the namespace.
The XSD datetime is quite ugly, with all those T and Z parts. I want to use a format which is both standard and common enough, and easy to use i.e. readable.
Before I show you how to use the 4 forms of "type generation", allow me to take care of the datetime issues first. A Wikipedia article </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/ISO_8601">http://en.wikipedia.org/wiki/ISO_8601</rich_text><rich_text> explains the standard.
The first question I'd like to answer is: Should the language support any format, or enforce ISO format? First let's see what XSD does: </rich_text><rich_text link="node 52">Date and Time</rich_text><rich_text>.
It enforces a format. For most users, typing the date 2013-06-11 is something which requires getting used to. Should I allow that? No. I won't allow that.
Let's add a date spec to the </rich_text><rich_text style="italic">namespace</rich_text><rich_text> declaration: Under the </rich_text><rich_text style="italic">uri</rich_text><rich_text> property, we can add a </rich_text><rich_text style="italic">date_order</rich_text><rich_text> property which has to be a permutation of </rich_text><rich_text style="italic">y</rich_text><rich_text>, </rich_text><rich_text style="italic">m</rich_text><rich_text> and </rich_text><rich_text style="italic">d</rich_text><rich_text>. And the </rich_text><rich_text style="italic">date_separator</rich_text><rich_text> property, which has to be one of:
• . (dot)
• - (hyphen)
• / (slash)
Omitting parts is allowed, by leaving a blank field. For example, for an order </rich_text><rich_text style="italic">dmy</rich_text><rich_text> and separator </rich_text><rich_text style="italic">/</rich_text><rich_text>, the full date is 11/6/2013 but the date /6/2013 is valid too and specifies just a month. Also, //2013 is valid and specifies the year 2013.
Another question: How is time specified? Hmmm... add a time type or add to date? Decision: It doesn't seem to matter right now. I'll just make it a separate type </rich_text><rich_text style="italic">time</rich_text><rich_text> and later we'll see.
Now let's see how the four definition mechanisms are used.
</rich_text><rich_text weight="heavy">union</rich_text><rich_text>: Just use the </rich_text><rich_text style="italic">union</rich_text><rich_text> keyword and then types inside []. Examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">regex</rich_text><rich_text>: Wikipedia explains regex here: </rich_text><rich_text link="webs http://en.wikipedia.org/wiki/Regular_expression">http://en.wikipedia.org/wiki/Regular_expression</rich_text><rich_text>. I won't explain it now, but the point is that a regex is specified and then the type is used as a restricted string. In XSD pattens also apply to numbers, but for now I'll just have them apply to strings and later we'll see if more flexibility is needed.
Example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">range</rich_text><rich_text>: Added inside [] just like the pattern, i.e. two numbers with comma separator. Also possible to use () to indicate open interval. Applies to real and integer, maybe will also apply to date and time in the future. For unlimited bound use -inf and inf. Examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text weight="heavy">enum</rich_text><rich_text>: This one doesn't need to be based on any type, but I should probably allow it for string and integer, etc. Actually I already see a problem with the way strings are used: which ones need the "" and which don't? There's mess here which I need to fix. Anyway, here an enum example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Actually maybe I should use [] instead, like the other types:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h3">Polishing</rich_text><rich_text>
Now let's handle new issues and last problems, before I start writing a summary and formal rules. Issues to handle:
• string VS identifier: where to use/not use ""
• bracket usage: [], {}, <>
• which types can have pattern/range/enum
</rich_text><rich_text underline="single" weight="heavy">Strings and Quotes</rich_text><rich_text>:
In most cases, strings can simply continue until they reach the end of the line, and there's no need to mark them with "". Actually, I can add an optional feature of marking with "" to allow spaces or special characters or multiline strings.
In XSD there's no special characters like \n. They are not necessary in XML and I also don't think I should add these technical characters. Instead, just let the user insert tabs and spaces and line feeds and carriage returns.
So, how is a multi-line string written? First, from now on strings don't need to be surrounded by "". But strings without "" can't start or end with a space/tab/etc. and can't be multi-line.
Let's see an example. This one is taken from above, not yet polished:
</rich_text><rich_text justification="left"></rich_text><rich_text>
First let's remove the "", since like I said we don't have to use them:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is now a simple legal excellent example. But sometimes we have strings with special requirements. Here are examples for strings which may require "":
• " text"
• "start here...
finish here"
• "[a-z][0-9]*"
Without "", a string starts where non-empty characetrs (tab, space, etc.) start, and ends in the last non-empty character on the same line. This behavior seems right to me because if I insert a tab or space on the end of the line by mistake, it's invisible in plain text but may produce unwanted results when later parsed and pasted somewhere else. So starting or ending a string with those empty characters requires "".
Note that if a string starts with ", the " is considered a language character and not part of the string, so if you want your string to start with ", you'll have to use "". The first marks the end of the string while the second belongs to the string.
Another option is - wait a second... there's a problem: If the first " starts the string, then doesn't the second one end the string? There's no way to find the closing "! For example, assume I start a multi-line string with "". Basically I'd have to go find where a new property starts, and find the closing " just before that property. But what if "integer name" on that line is actually part of the string?
Conclusion: It can't be allowed to use " inside a string delimited by "!
In XML, " and ' can be escaped by using </rich_text><rich_text style="italic">&apos;</rich_text><rich_text> and </rich_text><rich_text style="italic">&quot;</rich_text><rich_text>. It's quite ugly and I don't want that. Instead, I prefer to find some nicer syntax. For example, use \' instead of '. Yeah, this sounds like a good idea. A string which starts with " has to be a ""-delimited string, and any " inside it should be preceded with \. It also means two things:
1. If you want to use \" itself, you add another \, e.g. \\" actually means literal \"
2. If you want your ""-delimited string to end with the \ character, then... you're in trouble...
Python solves this issue by not allowing a string to end with an odd number of \s. Since \ may be used in paths, maybe I should choose another, less likely character. Hmmm... any character is a possible ending for a string.
I'll tell you what. Python is a programming language. If you can't finish the string with \, you can always concatenate \ to the string easily using the ASCII code, or with some other workaround. For me, for this language, I need an easy by-hand way to handle strings with unallowed sequences.
Strings can either be written without the "", in which case they strech from non-space to last non-space on the same line, or be inside "", in which case they can contain whatever you want. The first kind is unlimited: on the same line, you can have whatever you want. But the second kind has a problem: What if I want my string to contain the " character? How do I make sure it's not interpreted as the string delimiter?
In C and C++ string literals, \ is always an escape character. So the only way to get \ is by using \\. It means strings can safely end with anything: \" means " (" character in string) while \\" means \" (\ and closing ").
In my language, I don't want any \ to be forced to be written as \\. Instead, here's what I'll do: In a string delimited by "", \" means ". And \\" means \". And \\\" means \\". And so on. Then there's a problem because a string can't end with \. The </rich_text><rich_text weight="heavy">solution:</rich_text><rich_text> a workaround. Omit the closing \s and add then </rich_text><rich_text style="italic">after</rich_text><rich_text> the ".
For example:
"hello" => hello
"hello\"" => hello"
"hello\\"" => hello\"
"hello"\ => hello\
"hello"\\ => hello\\
"hel\"lo" => hel"lo
Now, how do multi-line strings work? If you have a line end with a ""-delimited string, then if the next line starts with a ""-delimited string too (possibly with preceding spaces or tabs) then it's appended to the string from the previous line.
For example:
"hello "
"world" => hello world
"hello\\""\
" world"\ => hello\"\ world\
Last thing: The regex pattern. Since the pattern may contain {} and [] which are common in the language, surrounding the regex with "" may be a good way to make it clear that it's a regex.
</rich_text><rich_text underline="single" weight="heavy">Bracket Usage</rich_text><rich_text>:
The 4 bracket types are {}, [], () and <>. Here are examples I already presented, which use brackets:
1. Defining an enum:
</rich_text><rich_text style="italic">property enum [sun, mon, tue, wed, thu, fri, sat] weekday</rich_text><rich_text>
2. Defining class property cardinality:
</rich_text><rich_text style="italic">class Community:
Person {1:5} leaders</rich_text><rich_text>
3. Defining a union:
</rich_text><rich_text style="italic">property union [integer, string] my_prop</rich_text><rich_text>
4. Defining regex:
</rich_text><rich_text style="italic">property string ["[a-zA-Z0-9]{8}"] my_prop</rich_text><rich_text>
5. Defining ranges:
</rich_text><rich_text style="italic">property integer [0, 31] day
property real [0, 1) halfopen_1
class MyClass:
integer (3, 8] halfopen_2
real (-inf, 3) open</rich_text><rich_text>
Now, with all usages defined, I can choose brackets for each usage much more easily. First, I'd like to rate the brackets by ease of typing, from easy to difficult:
1. []
2. <>
3. {}
4. ()
I hope it's more or less true. Now, let's give them meaning! [] and () are already used for ranges, i.e. restrictions. So here's a suggestion: I can easily assign brackets once I choose one of these two options:
• Minimize bracket variety
• Try to give unique brackets for each usage
It's hard to tell which is better, so I'll just pick one. I'm taking the </rich_text><rich_text weight="heavy">second</rich_text><rich_text> option. If assuming the language will not expand, then using the full bracket range makes it easier to relate brackets to usage, and the code becomes easier to understand in a glance. Here are the usages and their brackets:
</rich_text><rich_text weight="heavy">1. Defining enums and unions</rich_text><rich_text>: Using set notation, i.e. braces {}:
</rich_text><rich_text style="italic">property enum {sun, mon, tue, wed, thu, fri, sat} weekday</rich_text><rich_text>
</rich_text><rich_text style="italic">property union {integer, string} my_prop</rich_text><rich_text>
</rich_text><rich_text weight="heavy">2. Defining restricted properties</rich_text><rich_text>: Using [] and ():
</rich_text><rich_text style="italic">property string ["[a-zA-Z0-9]{8}"] my_prop</rich_text><rich_text>
</rich_text><rich_text style="italic">property integer [0, 31] day
property real [0, 1) halfopen_1
class MyClass:
integer (3, 8] halfopen_2
real (-inf, 3) open</rich_text><rich_text>
</rich_text><rich_text weight="heavy">3. Defining property cardinality</rich_text><rich_text>: Using <>:
</rich_text><rich_text style="italic">class Community:
Person <1:5> leaders</rich_text><rich_text>
</rich_text><rich_text weight="heavy">NOTE</rich_text><rich_text>: There's a new enum syntax, maybe better. I decided it may be much better to explicitly say from which type the enum values are taken, so the </rich_text><rich_text style="italic">enum</rich_text><rich_text> keyword can replaced by the type, or the type can be added between the keyword and the {}. The same applies to </rich_text><rich_text style="italic">union</rich_text><rich_text>: the keyword can be completely omitted, since </rich_text><rich_text style="italic">property</rich_text><rich_text> followed by {} has only one meaning, so </rich_text><rich_text style="italic">union</rich_text><rich_text> can be safely omitted (although it may make the code less verbose).
</rich_text><rich_text underline="single" weight="heavy">Restrictions</rich_text><rich_text>:
I need to decide which types can have pattern, range and sum. Here's again the list of types:
• integer
• real
• string
• boolean
• date
• time
• uri (maybe not necessary, just adding, you know, just in case)
XSD has some restrictions I haven't considered, so I'll specify type restrictions now, with XSD type table open to help me. Later I'll clarify the special cases. First, some XSD material:
• This is what XSD provides for </rich_text><rich_text style="italic">xsd:decimal</rich_text><rich_text>: totalDigits, fractionDigits, pattern, whiteSpace, enumeration, maxInclusive, maxExclusive, minInclusive, minExclusive.
• Restrictions for </rich_text><rich_text style="italic">xsd:string</rich_text><rich_text> are: length, minLength, maxLength, pattern, enumeration, whiteSpace.
• Restrictions on datetime and all related types: pattern, enumeration, whiteSpace, maxInclusive, maxExclusive, minInclusive, minExclusive.
Now, my language.
</rich_text><rich_text weight="heavy">Enumeration</rich_text><rich_text>: Possible for all types
</rich_text><rich_text weight="heavy">Pattern</rich_text><rich_text>: Possible for numbers and strings
</rich_text><rich_text weight="heavy">Range</rich_text><rich_text>: Possible for numbers, dates and times
</rich_text><rich_text weight="heavy">Length</rich_text><rich_text>: Would be only for strings, for now </rich_text><rich_text style="italic">Pattern</rich_text><rich_text> will be the way to limit the length
</rich_text><rich_text scale="h3">Graph Object IDs</rich_text><rich_text>
In a </rich_text><rich_text style="italic">graph</rich_text><rich_text>, object IDs can be entered immediately after a / at the beginning of the line (after indentation). Question: What type do these IDs have? Are they like local names or map to a class property, or a special kind of ID which can be a number? </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO</rich_text><codebox char_offset="2409" frame_height="250" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">graph Tasks (Task):
header content
child subtask
#0 Do something
due 31/08/2013
topics action, planning, software
#1 Do something else
#2 Say something
#3 Listen to music
#4 Do things
@3</codebox><codebox char_offset="3400" frame_height="1250" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">class Topic:
text name
text description
Topic{} subtopics
class Task:
date creation_date
time creation_time
date due_date
time due_time
date start_date
time start_time
required text content
required boolean complete
Task{} subtasks
Topic{} topics
weeks estimated_length_w
days estimated_length_d
hours estimated_length_h
class Member:
required text name
required text email
required text jabber
required text irc
required text role
property enum {sun, mon, tue, wed, thu, fri, sat} weekday
class Team:
required Member leader
Member{} members
required weekday{} work_days
hours workday_length
class Timeline:
// what should be here? What's a timeline??? What's a convenient plaintext way to define them?
graph Topics (Topic):
header name
child subtopics
#Software
#FreeSoftware
#Licenses
#Freedom
#Freedom of Speech
#Sharing
@Music
@Movies
#Music
#Movies
graph Tasks (Task):
header content
child subtasks
#0 Do something
due_date 31/08/2013
topics action, planning, software
#1 Do something else
#2 Say something
#3 Listen to music
#4 Do things
@3
// timeline objects?</codebox><codebox char_offset="4236" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Partager:
uri "freedom://akrasner/partager/"</codebox><codebox char_offset="4276" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto</codebox><codebox char_offset="4372" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
using Arbre local</codebox><codebox char_offset="4448" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
using Angel "freedom://iklein/angels/"</codebox><codebox char_offset="4510" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
import dc "http://purl.org/dc/elements/1.1/"</codebox><codebox char_offset="4680" frame_height="170" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Partager:
uri auto
class Person:
required text name
required text email
required text jabber
required text irc
required date birthday</codebox><codebox char_offset="4854" frame_height="170" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Partager:
uri auto
class Person link "http://xmlns.com/foaf/0.1/Person"
required text name
required text email
required text jabber
required text irc
required date birthday</codebox><codebox char_offset="4894" frame_height="192" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Partager:
uri auto
import foaf "http://xmlns.com/foaf/0.1"
class Person link foaf:Person
required text name
required text email
required text jabber
required text irc
required date birthday</codebox><codebox char_offset="4941" frame_height="192" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Partager:
uri auto
import foaf "http://xmlns.com/foaf/0.1"
class Person link foaf:Person
required text name link "http://xmlns.com/foaf/0.1/name"
required text email
required text jabber link foaf:jabberID
required text irc
required date birthday</codebox><codebox char_offset="4983" frame_height="424" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Partager:
uri auto
import foaf "http://xmlns.com/foaf/0.1"
class Person link foaf:Person
required text name link "http://xmlns.com/foaf/0.1/name"
required text email
text jabber link foaf:jabberID
text irc
required date birthday
Person{} knows
object Person dave:
name "Dave Baker"
email "dave.baker@freedom.org"
birthday 01/05
object Person john:
name "John Smith"
email "john.smith@freedom.org"
birthday 29/02
knows "http://www.w3.org/People/Berners-Lee/card#i"
knows dave</codebox><codebox char_offset="5132" frame_height="200" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">class Person base foaf:Person
required text name link "http://xmlns.com/foaf/0.1/name"
required text email
text jabber link foaf:jabberID
text irc
required date birthday
Person{} knows
class Male base Person
integer strength</codebox><codebox char_offset="7572" frame_height="62" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">Person {1} leader
Person {1:1} leader
required Person leader</codebox><codebox char_offset="7939" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">object Community comm:
members john, anne, thomas</codebox><codebox char_offset="7974" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">object Community comm:
members john
members anne
members thomas</codebox><codebox char_offset="8022" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">object Community comm:
members john, dale, seth
members anne
members thomas, lisa</codebox><codebox char_offset="10176" frame_height="82" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">property union [integer, string] my_prop
class MyClass:
union [integer, string] some_prop</codebox><codebox char_offset="10532" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">property string ["[a-zA-Z0-9]{8}"] my_prop
class MyClass:
string ["[a-zA-Z0-9]{8}"] my_prop</codebox><codebox char_offset="10803" frame_height="120" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">property integer [0, 31] day
property real [0, 1) halfopen_1
class MyClass:
integer (3, 8] halfopen_2
real (-inf, 3) open</codebox><codebox char_offset="11093" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">property enum {sun, mon, tue, wed, thu, fri, sat} weekday
class MyClass
enum {one, two three} num</codebox><codebox char_offset="11159" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">property enum [sun, mon, tue, wed, thu, fri, sat] weekday
class MyClass
enum [one, two three] num</codebox><codebox char_offset="12164" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">object Person dave:
name "Dave Baker"
email "dave.baker@freedom.org"
birthday 01/05</codebox><codebox char_offset="12240" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">object Person dave:
name Dave Baker
email dave.baker@freedom.org
birthday 01/05</codebox></node><node name="Keywords" prog_lang="custom-colors" readonly="False" tags="" unique_id="115"><rich_text scale="h2">The Full List</rich_text><rich_text>
This is a list of all words which have special meaning in the language:
</rich_text><rich_text weight="heavy">base</rich_text><rich_text>
</rich_text><rich_text weight="heavy">boolean</rich_text><rich_text>
</rich_text><rich_text weight="heavy">child</rich_text><rich_text>
</rich_text><rich_text weight="heavy">class</rich_text><rich_text>
</rich_text><rich_text weight="heavy">date</rich_text><rich_text>
</rich_text><rich_text weight="heavy">date_order
date_separator</rich_text><rich_text>
</rich_text><rich_text weight="heavy">default</rich_text><rich_text>
</rich_text><rich_text weight="heavy">enum</rich_text><rich_text>
</rich_text><rich_text weight="heavy">graph</rich_text><rich_text>
</rich_text><rich_text weight="heavy">header</rich_text><rich_text>
</rich_text><rich_text weight="heavy">import</rich_text><rich_text>
</rich_text><rich_text weight="heavy">inf</rich_text><rich_text>
</rich_text><rich_text weight="heavy">integer</rich_text><rich_text>
</rich_text><rich_text weight="heavy">object</rich_text><rich_text>
</rich_text><rich_text weight="heavy">link</rich_text><rich_text>
</rich_text><rich_text weight="heavy">namespace</rich_text><rich_text>
</rich_text><rich_text weight="heavy">optional</rich_text><rich_text>
</rich_text><rich_text weight="heavy">parent</rich_text><rich_text>
</rich_text><rich_text weight="heavy">private</rich_text><rich_text>
</rich_text><rich_text weight="heavy">property</rich_text><rich_text>
</rich_text><rich_text weight="heavy">real</rich_text><rich_text>
</rich_text><rich_text weight="heavy">required</rich_text><rich_text>
</rich_text><rich_text weight="heavy">state</rich_text><rich_text>
</rich_text><rich_text weight="heavy">text</rich_text><rich_text>
</rich_text><rich_text weight="heavy">time</rich_text><rich_text>
</rich_text><rich_text weight="heavy">type</rich_text><rich_text>
</rich_text><rich_text weight="heavy">union</rich_text><rich_text>
</rich_text><rich_text weight="heavy">uri</rich_text><rich_text>
</rich_text><rich_text weight="heavy">using</rich_text><rich_text>
Now let's put them in groups.
</rich_text><rich_text scale="h2">Categories</rich_text><rich_text>
</rich_text><rich_text scale="h3">Entities</rich_text><rich_text>
class
graph
object
namespace
property
type
</rich_text><rich_text scale="h3">Standard Properties</rich_text><rich_text>
child, parent
date_order
date_separator
header
import
state
uri, private
using
</rich_text><rich_text scale="h3">Property Constraints</rich_text><rich_text>
required
optional
default
</rich_text><rich_text scale="h3">Types</rich_text><rich_text>
boolean
date
integer
real
text
time
</rich_text><rich_text scale="h3">Type Construction</rich_text><rich_text>
enum
union
inf
</rich_text><rich_text scale="h3">Class Attributes</rich_text><rich_text>
base
</rich_text><rich_text scale="h3">RDF Linkage</rich_text><rich_text>
link</rich_text></node><node name="Special Characters" prog_lang="custom-colors" readonly="False" tags="" unique_id="116"><rich_text scale="h2">The Full List</rich_text><rich_text>
First let's make a list of characters which have a special meaning in the language or some special usage or issue.
:
"
\
/
[
]
{
}
(
)
<
>
#
@
X
,
$
%</rich_text></node><node name="Tutorial First Draft" prog_lang="custom-colors" readonly="False" tags="" unique_id="117"><rich_text>Under this node I'll write some kind of tutorial, especially for myself to keep track of the language features and syntax. The tutorial is generated by taking all the ideas and plans from the draft, and making a simple final summary of them, divided into pages by topic. Have fun :)</rich_text><node name="Personal Notes" prog_lang="custom-colors" readonly="False" tags="" unique_id="121"><rich_text>This page contains personal notes I make while writing the tutorial, and is not part of the tutorial itself, but a helper for writing and updating the tutorial.
</rich_text><rich_text scale="h3">Todo:Task Properties</rich_text><rich_text>
content
subtask
complete
topic
creation_date
start_date
start_time
finish_date
finish_time
</rich_text><rich_text scale="h3">Plan for Polished Tutorial</rich_text><rich_text>
For a while, I've been holding a thought related to software documentation: Each document should match to specific audience, and each audience should be able to find a matching document. There should be a document for beginners, a document for experts, a technical reference document, etc.
I'd like to have all these type of documents here too. If I remember correctly, I made such a list once for GSTC or Photon or Old Sylva. But I don't remember where it is. I'll just make a new list.
• Simple tutorial for plain beginners (introduces basic concepts and practice, ignores the rest)
• Full tutorial (introduces all concepts, including advanced ones, has links to reference docs, etc.)
• List of special characters
• List of concepts
• List of keywords
Here's a list of topics from which I'll try to make the tutorial section hierarchy:
Purpose
Example
Files
Namespaces
Primitive Types
Strings
Boolean Numbers
Date
Time
Type Construction
Unions
Enumerations
Patterns
Ranges
Properties
Classes
Objects
Comments
Graphs
Inheritance
URIs
Linking
</rich_text><rich_text scale="h3">IDs and URIs</rich_text><rich_text>
I have a mess with IDs and URIs. There needs to be a clear way to define and use IDs which doesn't interfere with other syntax rules! I'm creating a new tutorial empty copy for that, in which I'll make all my updates and upgrade the language plans.</rich_text></node><node name="Intro" prog_lang="custom-colors" readonly="False" tags="" unique_id="118"><rich_text>In this tutorial I'm going to explain how to write models using the language. It doesn't have a name yet, But I already have one nice suggestion which I'm going to use throughout the tutorial: </rich_text><rich_text style="italic">Idan</rich_text><rich_text>.
The tutorial won't just explain the plain boring theory - all topic and accompanied by examples, all of which are linked by a "story". We will follow Jane as she implements a simple text-based TODO model using the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> language.</rich_text></node><node name="File Extensions" prog_lang="custom-colors" readonly="False" tags="" unique_id="119"><rich_text>The first thing Jane needs to do, is create a new file.
An empty text file may be used, but since most files probably have a common prefix, it may be useful to place a template file in the standard template folder and create new files from that template. It may also be useful to have several templates, for various file types and usage patterns. I may give an example later, but it's up to you: an empty plain text file is just fine.
Idan files have standatd extensions. They are currently not official MIME types or anything like that. They're just a convention allowing for several things:
• Make it easy for the file browser to tell you what kind of file it is
• Make it easy for a text editor to auto-detect the language and apply syntax highlighting and other features
• Make it easy for the computer to decided which programs can open Idan files for editing, and which is the best default
Aside from that, Idan file are plain text files, which anyone can edit, either manually or using any kind of special software.
The file extensions are:
• .idan general-purpose
• .idant types file
• .idanc classes file
• .idano objects file
• .idang graph file
Later we'll see what these extensions mean, when we talk about classes, objects and graphs.
Regarding file names, there's currently no clear convention for public files. But it is highly recommended to choose your own rules, and use them for all public files. It provides consistency and makes migration trivial. You can make the filename informative by including the namespace in it, and a name of some category/topic/class/graph/object, whichever is relevant to the contents of the file.
Since Jane needs to create her own new model, she is going to start from the </rich_text><rich_text style="italic">classes file</rich_text><rich_text>. It's perfectly possible to define many classes in a single file or a single class per file. For this tutorial, Jane will use a single classes file. Right now, it's too early to decide on a formal public name for the file, but after we fill it, we can change it so some formal name. Later we'll see an example of this. For now, Jane calls the new file </rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text>, and it's an empty plain text file.
It's absolutely valid to use the </rich_text><rich_text style="italic">.idan</rich_text><rich_text> extension for all files, but when a file contains only classes, using </rich_text><rich_text style="italic">.idanc</rich_text><rich_text> gives more information about its content.</rich_text></node><node name="Namespaces" prog_lang="custom-colors" readonly="False" tags="" unique_id="120"><rich_text>Each file may contain an optional namespace declaration. This declaration is not required, but highly recommended. Even if the parameters it allows to provide are not used, specifying the default values explicitly in the file makes it clear what values they have, and helps avoid confusion and surprising results. For example, if you forget to declare public properties for the file/namespace, it's not clear that the contents are private unless stated in the beginning of the file, in the namespace declaration.
We've been talking about namespaces, but what exactly is a namespace?
When many entities are defined, even by one person, there's a high chance of name collision. And when we combine entities defined by many different people, the chance for collision is ever higher. Much higher. Namespaces are basically a solution to this problem: You choose a namespace for your definitions, and everything you define belongs to it. Anything defined externally does not, and this is how collisions are avoided.
A definition which doesn't have a namespace defined, is an anonymous definition. It does have a namespace, but it's auto-generated and cannot be referred to from outside. This is something you may want to do with your private data. Public data meant to be shared can have an explicit human-readable namespace which you can share with others.
As you may have realized, namespaces can collide just like any definition. What happens if two people have a namespace with exactly the same name? This problem is solved by giving each namespace two identifiers: a namespace prefix and a resource identifier. The prefix is the human-readable name of the namespace, while the identifier is a unique string meant to be used by computers, and gives the namespace a unique ID.
Before we go back to Jane, I'll explain all the possibilities:
• drop the namespace declaration, i.e. not have it at all
• declare an anonymous namespace
• declare a namespace without an identifier
• declare a namespace with an identifier
The first two options have exactly the same result, but it is recommended to use the second one because it is explicit and avoids confusion and unexpected results.
There are two options for the name of the namespace: Either it's specified by you, or its name is auto-generated. The reason it always has a name, is to allow for internal representation and easily updating the name in the future.
The identifier, which is a Uniform Resource Idenfitier (URI), has three options: Either it's private auto-generated, or it's public auto-generated, or it's specified manually by you. When you define private entities not meant to be published, you can use automatic private URIs. If you edit your files using a plain text editor, and you need to pass the URI to someone, then you'll want to define the URI by yourself. If you use some other tool which works with the data defined in your </rich_text><rich_text style="italic">Idan</rich_text><rich_text> files, you can set that tool to use the pattern you want, and just let the URI be auto-generated.
You can also mark the URI as public automatic even if you work with plain text, but you don't get any guarantee which structure exactly it will have.
The namespace name defauls to auto-generated, and the URI defauls to private auto-generated.
Let's see examples.
Drop namespace declaration (defauls to anonymous namespace and auto private URI):
</rich_text><rich_text justification="left"></rich_text><rich_text>
Anonymous namespace with no URI (defauls to auto-private URI):
</rich_text><rich_text justification="left"></rich_text><rich_text>
Anonymous namespace with URI explicitly set to private:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Anonymous namespace with URI auto public:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Namespace with a name and auto public URI:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Namespace with specified URI:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note that the name and the URI specifications are independent, i.e. any combination is possible. Also note than private and auto are special values, so if for example you want your URI to be the word private, you'll need to surround it with double quotes: "private".
Now let's go back to Jane and the task model. She already created an empty file called </rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text>, and now she wants to give it a namespace declaration. A namespace declaration may appear only once, only as the first thing in the file (blank lines before the </rich_text><rich_text style="italic">namespace</rich_text><rich_text> keyword are allowed, but you probably don't want them).
Jane is going to work with the files using a simple text editor, so assigning automatic URIs won't allow her to give the URIs to other people. She wants to share the classes with friends, she give the namespace a name and specified a URI:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note the indentation at the beginning of the first line. When declaring/defining an entity (namespace, class, object, graph) all the lines containing properties begin with similar indentation, usually 4 or 8 spaces, or a tab. But any number os spaces/tabs is allowed, as long as the property lines have the save indentation.</rich_text><codebox char_offset="3358" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True"></codebox><codebox char_offset="3424" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace</codebox><codebox char_offset="3483" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace:
uri private</codebox><codebox char_offset="3528" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace:
uri auto</codebox><codebox char_offset="3574" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri auto</codebox><codebox char_offset="3607" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri freedom://jane/todo/</codebox><codebox char_offset="4446" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri http://www.jane-todo.org/todo/</codebox></node><node name="Properties" prog_lang="custom-colors" readonly="False" tags="" unique_id="122"><rich_text>Once Jane has declared her namespace, she can start defining </rich_text><rich_text style="italic">properties</rich_text><rich_text>. Before we can define tasks and make to-do lists, we need to define which properties a task can or should have.
There are two ways to define properties: outside the class, or inside the class. For simple usage like Jane's, it doesn't do much difference, but for the tutorial I will demonstrate both ways.
First, what properties would we like our tasks to have? Here's a basic set of properties Jane has come up with:
</rich_text><rich_text weight="heavy">content</rich_text><rich_text> The task text, in plain text
</rich_text><rich_text weight="heavy">creation_date</rich_text><rich_text> The day the task was created
</rich_text><rich_text weight="heavy">complete</rich_text><rich_text> True/False: Did we complete the task?
</rich_text><rich_text weight="heavy">topic</rich_text><rich_text> A topic to which this task belongs
</rich_text><rich_text weight="heavy">subtask</rich_text><rich_text> A task which is a dependency of this task (i.e. must be finished before we can start here)
</rich_text><rich_text weight="heavy">start_date</rich_text><rich_text> The day the task was started
</rich_text><rich_text weight="heavy">start_time</rich_text><rich_text> The time the task was started, on the start day
</rich_text><rich_text weight="heavy">finish_date</rich_text><rich_text> The day the task was finished
</rich_text><rich_text weight="heavy">finish_time</rich_text><rich_text> The time the task was finished, on the finish day
For the tutorial, I'll demonstrate outside-class definition by defining the first 3 properties outside the class, and the other 6 inside the class.
So how do we define a property? Each property has a type. Essentially, a property is like a relation between the class objects and some other entity: it can be an object or a number or text. Anything you want. Since we haven't defined any classes yet, we don't have classes to refer to. The types of content, subtask and complete will be built-in types. For content, we'll use the plain text type, </rich_text><rich_text weight="heavy">text</rich_text><rich_text>. For creation_date we'll use the </rich_text><rich_text weight="heavy">date</rich_text><rich_text>. For complete, we'll use </rich_text><rich_text weight="heavy">boolean</rich_text><rich_text>.
Properties are defined using the </rich_text><rich_text style="italic">property</rich_text><rich_text> keyword followed by the type (in this case, a built-in type), and then the name of the type. Remember this is a local name within the namespace we just declared. Here's the definition of our first three properties:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Combining this with the namespace declaration, so far the </rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text> file looks like this:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1858" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text content
property date creation_time
property boolean complete</codebox><codebox char_offset="1953" frame_height="116" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri http://www.jane-todo.org/todo/
property text content
property date creation_time
property boolean complete</codebox></node><node name="Classes" prog_lang="custom-colors" readonly="False" tags="" unique_id="123"><rich_text>Jane has defined just 3 properties, out of 9. The other 6 properties are going to be defined inside the </rich_text><rich_text style="italic">class</rich_text><rich_text>.
What is a class? A class represents a set, in the mathematical sense. For example, "the set of all people". When we need to work with certain objects on the computer, we naturally try to define how the information about these objects is represented in computer memory and files. We define the </rich_text><rich_text style="italic">computer representation</rich_text><rich_text> of a set of objects, so that we can describe them using computer tools. This is where classes help us.
A class represents a set, but isn't more than the representation. A class also defines the </rich_text><rich_text style="italic">computer representation</rich_text><rich_text> of the set. For the "set of all people", the </rich_text><rich_text style="italic">Person</rich_text><rich_text> class could define the properties we want to store on the computer, about each person. We would then choose properties according to our usage pattern. A bank may not care how tall a person is, but a shoe designer may care.
Before we can define the Task class, we need to define how topics are defined. One of the properties Jane wants each task to have is </rich_text><rich_text style="italic">topic</rich_text><rich_text>, and we haven't decided yet which type topics are going to have. If course they can be simple strings, but later in the tutorial we're going to see some features which whose demonstration will require topics to be class objects.
Here's our Topic class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The </rich_text><rich_text style="italic">class</rich_text><rich_text> keyword declares a new class. Then we specify the name of the class and a colon. All the lines after that are property lines and must be indented with exactly the same indentation level. It has to be at least one space or at least one tab.
The third property has three new features we haven't seen yet:
• Its type is a class type, not a built-in type
• Its type is the class being defined
• Its type contains cardinality specification
Classes serve as types, just like </rich_text><rich_text weight="heavy">text</rich_text><rich_text> and </rich_text><rich_text weight="heavy">boolean</rich_text><rich_text> are. And a class can have a property of self type, so that a topic can have sub-topics, a graph node can have neighbor nodes, etc.
A cardinality specification decides the number of times a property can be specified for a given object. By default, each property is </rich_text><rich_text style="italic">optional</rich_text><rich_text>, which means it can appear once or not at all. In many cases this default is enough, but in many other cases we want a different setting. For example, assume we have a Community class and we want it to have a </rich_text><rich_text style="italic">leader</rich_text><rich_text> property. According to the rules of the community, there must be 3-5 leaders, so we want the number of leaders to be 3, 4 or 5.
Instead of specifying the limits as numbers, it is possible to use the </rich_text><rich_text style="italic">required</rich_text><rich_text> keyword in simple cases. This keyword means a property must appear, i.e. the cardinality is exactly 1.
Let's see some examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The following examples are possible too:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is also possible to state exactly which cardinality values are allowed:
</rich_text><rich_text justification="left"></rich_text><rich_text>
For clarity and readability of the code, the keyword </rich_text><rich_text style="italic">optional</rich_text><rich_text> may be used as a clear way to indicate a property may appear once or not appear at all. It's exactly identical to not declaring cardinality at all, or declaring it using <0:1> or <0,1> or <:1>. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now let's go back to Jane. The Topic class has a </rich_text><rich_text style="italic">Topic<> subtopic</rich_text><rich_text> propety, which means a topic can have any number of subtopics, including zero. Now, using the Topic class, we can define our Task class according to the requirements we have:
</rich_text><rich_text justification="left"></rich_text><rich_text>
As you can see, we can use predefined properties by writing the property name. If we need to specify a cardinality constraint, we specify keywords (required, optional) before the name, like in the last example, and if we need to specify it using <>, we put the <> after the name (unlike with inline properties), like this:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1318" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
text name
text description
Topic<> subtopic</codebox><codebox char_offset="2649" frame_height="154" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text my_prop_1 ~ May appear once, or not appear at all
required text my_prop_2 ~ Must appear exactly once
text<> my_prop_3 ~ May appear any number of times, including zero
text<3:5> my_prop_4 ~ May appear 3-5 times, i.e. 3 or 4 or 5
text<4> my_prop_5 ~ Must appear exactly 4 times
text<:7> my_prop_6 ~ May appear up to 7 times
text<2:> my_prop_7 ~ Must appear at least twice</codebox><codebox char_offset="2694" frame_height="168" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text<0:> a ~ identical to text<>
text<1> b ~ identical to required text
text<1:1> c ~ identical to required text
text<4:4> d ~ identical to text<4>
text<0> ~ indicates the property must not appear
text<0:0> ~ identical to text<0>
text<0:5> ~ identical to text<:5>
text<0:1> ~ identical to text</codebox><codebox char_offset="2773" frame_height="120" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text<0, 3> a # Appear exactly 0 or 3 times
text<0, 1> b # Identical to text and text<0:1> and text<:1>
text<2, 5, 9> c # Appear 2 or 5 or 9 times
text<0, 1, 3, 6, 34> d # Appear 0 or 1 or 3 or 6 or 34 times
text<3, 54, 16, 68, 1, 0> # Order of cardinalities doesn't matter</codebox><codebox char_offset="3046" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
optional text a</codebox><codebox char_offset="3293" frame_height="190" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
required content
creation_time
required complete
Topic<> topic
Task<> subtask
date start_date
time start_time
date finish_date
time finish_time</codebox><codebox char_offset="3620" frame_height="82" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text b
class MyClass:
text <3:5> a
b <3:5></codebox></node><node name="Numbers" prog_lang="custom-colors" readonly="False" tags="" unique_id="124"><rich_text>Jane now has the Topic and Task classes defined. This is what she has written so far:
</rich_text><rich_text justification="left"></rich_text><rich_text>
We're now ready to start defining objects. But we don't know yet, how to specify values. So before we actually go and write objects, we'll see how we give values to properties of different types. First, these are the primitive types:
• integer
• real
• string
• boolean
• date
• time
Very simple, isn't it? These types are called </rich_text><rich_text style="italic">primitive</rich_text><rich_text> because they are not defined by extension or restriction of other types. Any other type, built-in or user-defined, is defined using these primitive types.
Integer values can be specified exactly as you'd expect: a sequence of digits 0-9. For example:
0
123
4329384213
234
3
999881
In some cases, it's more convenient to use a specific base than to use the traditional decimal numbers. For example, it's common to use binary numbers (base 2), octal numbers (base 8) and hexadecimal numbers (base 16) in some cases. In some programming languages, prepending 0 or 0x to a number denotes base 8 or 16. In the Idan language, any base between 2 and 36 (including both) can be used. Bases are specified by prepending the base number (in decimal) and an underscore to the number. For bases larger than 10:
A or a denotes 10
B or b denotes 11
C or c denotes 12
...
Z or z denotes 35
For example:
2_10010010100100111110
8_73271
10_2958105
16_1a87b1fd981e89
36_28rhc103210ndjxh
23_874AEJ98L87
13_A87BbC98c9bAa7
Negative integers are allowed to, by putting a minus sign after the underscore:
10_-2958105
16_-1a87b1fd981e89
36_-28rhc103210ndjxh
Lowercase and uppercase letters can be mixed, but a number is probably much more readable if the letter case is consistent.
Real numbers also have the expected syntax used in other languages, and again also the ability to use an arbitrary base, which is unique to Idan.
All integers are also valid real numbers. So real numbers are an extension to integers (this is a natural consequence of Z being a subset of R). In addition to what integer allow, it's possible with real numbers to specify a fractional part and an exponent. For example:
1 = 1.0 = 1.0%0 = 1%0 = 17_1 = 23_1%0
23.329%72
0.283
32%-239
31_2.3%5
The exponent part is a bit tricky: In decimal numbers (base 10), the exponent part means "multiply by the given power of ten", for example 2%3 = 2 * 10^3 = 2000. But in other bases, the exponent means multiply by a power of the base, which isn't ten anymore. For example, take 2_101%101. What does it mean? The way to avoid getting confused is using the following rule: After the underscore, assume the only base in the world is the base specified before the underscore. So the number we have is 101 in base 2 (which is 5 decimal) multiplied by the base (2 decimal) raised to power 101 (5 decimal). In other words, this number in decimal means 5 * 2^5.
In many programming languages and systems e or E denote the exponent part, while % is used in some languages as the modulo operator. Since Idan is a data modeling language and doesn't have "operations", while it focuses on definition of classes and objects, the characters e and E are used as digits of numbers in base 15 and above, and the % character isn't used anywhere else and is free to be used as a exponent marker.
The ability to specify a base is probably not useful most of the time, but it's quite common to specify user permissions on Linux as octal numbers, and use binary numbers in low-level computing and in electronics, and specify RGB colors using hexadecimal numbers. Since the choice of bases for specific usage is arbitrary, Idan supports arbitrary bases to ensure convenience.</rich_text><codebox char_offset="87" frame_height="404" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri http://www.jane-todo.org/todo/
property text content
property date creation_time
property boolean complete
class Topic:
text name
text description
Topic<> subtopic
class Task:
required content
creation_time
required complete
Topic<> topic
Task<> subtask
date start_date
time start_time
date finish_date
time finish_time</codebox></node><node name="Strings" prog_lang="custom-colors" readonly="False" tags="" unique_id="125"><rich_text>Like all other primitive types, as we'll see very soon, strings can be specified exactly as you would expect. Well, at least if you're not a programmer. Strings can appear in the file as simple plain text.
Wait a second! What's a 'string'? A string in computing is a sequence of characters. It is a computer representation of </rich_text><rich_text style="italic">text</rich_text><rich_text>.
Typing string directly, just like that, is not always what you want, but in many cases it is. Example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When strings are specified like that, the actual string starts from the first non-space-non-tab character and ends with the last character before the line ends, dropping any spaces and tabs from the line's end. It means the last example contains the string "some string here". But what if you want your string to be " some string here "? What if you want your string to be multiline?
These cases require different treatment. The direct simple string notation shown above is meant for use with short simple strings, and is not recommended for longer ones. It's great for names or addresses, but probably not so good for sentences or paragraphs.
It's also possible your string happens to contain a language keyword. For example, </rich_text><rich_text style="italic">some text here</rich_text><rich_text> contains the word </rich_text><rich_text style="italic">text</rich_text><rich_text> which is a keyword and cannot be used as a local name. In the last example, it may be possible to detect and ignore it, and treat is as a string, but with some keywords and usage patterns, it does matter whether the keyword is meant to be the actual language keyword or it belongs to the string. So "some text here" is not allowed.
The solution to all these problems is surrounding the string with double quotes:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This also allows the string to start and end with spaces and tabs, and contain keywords:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to have multi-line strings. It's done by starting a new string on the next line. All these strings lines must be indented, and have the same indentation. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note the indentation of the lines 2-4 of the string: they're indented further than the </rich_text><rich_text style="italic">uri</rich_text><rich_text> line, and all have the same indentation.
Unfortunately, qouted strings also have some extra issues, which the simple strings don't have. If you want your string to contain a quote, what do you do? Or what if you want it so </rich_text><rich_text style="italic">start</rich_text><rich_text> with a quote?
The second is simple: You have to use quoted strings. If the quote is inside the string, then a simple string like </rich_text><rich_text style="italic">this string has an " embedded quote</rich_text><rich_text> is fine. But if the string begins with a quote, the language will treat the quote as the beginning of a quoted string, so you'll need the string to be quoted.
For example, this will generate an error:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Once we decided we need a quoted string, how do we embed a quote inside it? Any quote inside a string will be regarded as a closing quote, so this code won't work:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The actual string is "This string contains ", and the rest of the line then generates an error. The answer is: we use an escape sequence. It is a sequence of characters with a special meaning: usually the sequence is made of 2 characters or more, and translates into a single character. This feature is present in many languages, with many possible sequences, but in the Idan language there's only a single sequence: \". It's a backslash followed by a quote.
In a quoted string, all appearances of \" are treated as the " character and allow to embed " in a string. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The question is, what if you want your string to end with \? In the following, the string is not closed:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The solution to this problem in Idan is to remove the \ from the string, and add it right after the closing quote. Then the string is correctly treated and the \ is included too. This is how we fix the last example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Our problems haven't been solved yet. What if we want to have the sequence \" in the string? And what if we want the string to end with \\ or \\\ or \\\\?
The first problem is solved by always adding an extra backslash. For example, assume we want to have the sequence \" in the string, as is. Then in the plain string we type \\", and the two last characters are escaped to a single ", and the result is \". In the same manner \\\" converts to \\" and so on
The second problem is solved by appending as many \s as we want. For example, "hello"\\\ is interpreted as the text </rich_text><rich_text style="italic">hello\\\</rich_text><rich_text>.
Last thing: non-ASCII characters. What if you want to type a string in your language? It could be French or Hebrew or Japanese. In Idan, the default encoding is UTF-8. It's up to you, the user, to make sure the plain-text files you create are in UTF-8 encoding. Then, you can directly use any unicode character in the text.</rich_text><codebox char_offset="438" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri some string here</codebox><codebox char_offset="1627" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri "some string here"</codebox><codebox char_offset="1720" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri " some text went to bar, and danced with a required boolean "</codebox><codebox char_offset="1910" frame_height="100" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri "This is a very long URI, and also an illegal one."
"At least it has a second line!"
"And even a third line!"
"And this is the last line of the string."</codebox><codebox char_offset="2605" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="pkgconfig" width_in_pixels="True">namespace SomeName:
uri "my string begins with a quote</codebox><codebox char_offset="2773" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri "This string contains " a quote"</codebox><codebox char_offset="3357" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri "This string contains \" a quote"</codebox><codebox char_offset="3466" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri "This string contains \" a quote\"</codebox><codebox char_offset="3686" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri "This string contains \" a quote"\</codebox></node><node name="Boolean Numbers" prog_lang="custom-colors" readonly="False" tags="" unique_id="126"><rich_text>Boolean numbers are very simple: A boolean number has only two possible values. In Idan, these values are denoted by the special objects </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text>. Nothing else is accepted.
Note that "true" and "false" are strings, and thus cannot be used as boolean values. </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text> are the only allowed values.</rich_text></node><node name="Date and Time" prog_lang="custom-colors" readonly="False" tags="" unique_id="127"><rich_text>Date and time can be described in many ways, in computers just like on paper. Since Idan aims to be easy to write by hand, it doesn't enforce a date representation format. Instead, you can choose the format you want.
The time format is always hh:mm:ss and the default date format is y-m-d so these would be legal:
2013-17-6
16:32:00
But you probably don't really use this date format in real life. Idan allows you to set the date format per-file by setting the namespace properties </rich_text><rich_text style="italic">date_order</rich_text><rich_text> and </rich_text><rich_text style="italic">date_separator</rich_text><rich_text>.
date_order is a 3-letter string containing y, m and d. Each exactly once. This property chooses the order in which you write day, month and year in all your dates within a file. The default value is </rich_text><rich_text style="italic">ymd</rich_text><rich_text>. You'll probably want to use </rich_text><rich_text style="italic">mdy</rich_text><rich_text> or </rich_text><rich_text style="italic">dmy</rich_text><rich_text>, but any order is possible.
date_separator chooses the separator character which separates the year, month and day parts of the date. The default value is - (hyphen). The possible values are -, / and . (hyphen, slash, dot).
Example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's possible to omit any part of the date by leaving the field blank. But the separator must remain. The following date values are legal, when used with the namespace declaration above:
3//
03//
/6/
/06/
//13
//2013
//02
//2002
17/6/
6/2013
17/6/13
17/06/13
17/06/2013
17/6/2013
These are </rich_text><rich_text weight="heavy">illegal</rich_text><rich_text>:
17//13
3//13
03//13
3//2013
03//2013
Some dates may make less sense than others. But Idan doesn't add limitations, so that the same built-in type </rich_text><rich_text style="italic">date</rich_text><rich_text> can be used for any partial date value without defining new types and objects. The only limitation is that specifying only day and year without month is </rich_text><rich_text weight="heavy">illegal</rich_text><rich_text>. In some cases it's probably desired to limit the date values, but currently Idan doesn't provide a built-in solution. Ranges can help, but the way to do it is probably defined a restricted string type containing three numbers and two separators between them. We'll see later how it's done.
Time parts can be omitted too, but only from the least-significant part. Seconds may be omitted from the hh:mm:ss value. If seconds are omitted, then minutes can be omitted too. Hourse cannot be omitted. It's possible to drop leading zeros, e.g. 1:2:3 is a legal value. But it's probably much more readable to include them: 01:02:03, at least in some cases.
Examples:
1:2:3
01:2:3
1:02:3
01:2:03
01:02:03
16:43:17
16:43
16
00:00:00
0:0:0
0:0
0
Note that the colon is omitted when seconds or minutes are omitted, unlike the date separator, which must remain in all cases.</rich_text><codebox char_offset="996" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri auto
date_order dmy
date_separator /</codebox></node><node name="Objects" prog_lang="custom-colors" readonly="False" tags="" unique_id="128"><rich_text>Jane now knows how to give values to types, and she can start defining objects. There are two ways to define objects: explicit definition and graph definition. Graph definition is much easier and shorter in some cases, but we'll start with the explicit definition method, which always works, for all cases.
Since the </rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text> file was meant for classes only, Jane is creating a new file called </rich_text><rich_text style="italic">todo.idano</rich_text><rich_text> will which contain object definitions.
Here's what we already did in </rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Our tasks are going to be private, so for the object file we'll use an private namespace. But we'll give it a name, so that we can refer to it from other private files. We'll also set the date order and separator:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we can define objects. Let's start with some topics. An object definition begins with the </rich_text><rich_text style="italic">object</rich_text><rich_text> keyword followed by the class, then the object's local name, and then a colon. The properties appear in the next lines.
Like any identifier, object local names must begin with a letter and can contain only letters, numbers and _.
Let's define our first topic:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we want to define a new subtopic, but we can't. </rich_text><rich_text style="italic">food</rich_text><rich_text> doesn't specify any subtopic. What if we want to create a subtopic of a topic defined by someone else. It may be much better to choose a topic's parents, rather than choose its children. Let's change the Topic class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we can define subtopics of food easily:
</rich_text><rich_text justification="left"></rich_text><rich_text>
As you probably have noticed, the object name is identical to the </rich_text><rich_text style="italic">name</rich_text><rich_text> property. It doesn't have to be like that, but in some cases it makes sense, and as a result we type all names twice. One of the things graph definition provides is avoiding this duplication.
Since none of Topic's properties are required, we can specify any properties we want. supertopic also has unlimited cardinality. How do we specify more than one supertopic? There are three options: On one line, or separated, or combining both.
Let's define some more topics to help us demonstrate:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is the one-line method:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is the separate method:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is both combined:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The names used in the supertopic property are local object names, not </rich_text><rich_text style="italic">name</rich_text><rich_text> property values.
There are more interesting features related to objects, which we will see in the next sections.
NOTE: I'm considering to make it possible to define local IDs which are not limited to the rules of local names. These IDs are only local, and are NOT the URIs/UUIDs for global use, but can make it easier to use serial IDs for mass creation of objects.
If it gets supported, the syntax will be:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And refering to these objects using the ID will be possible </rich_text><rich_text style="italic">only</rich_text><rich_text> by using the class name Topic#42pf83j.
NOTE: I forgot to mention that, but it's possible to define new types and properties in-place. I didn't give an example, did I? Well, it's done by defining the type in place without the type keyword, then entering the property name. I'll add examples later.</rich_text><codebox char_offset="491" frame_height="404" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri http://www.jane-todo.org/todo/
property text content
property date creation_time
property boolean complete
class Topic:
text name
text description
Topic<> subtopic
class Task:
required content
creation_time
required complete
Topic<> topic
Task<> subtask
date start_date
time start_time
date finish_date
time finish_time</codebox><codebox char_offset="709" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace JaneTasks:
uri private
date_order dmy
date_separator /</codebox><codebox char_offset="1076" frame_height="62" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic food:
name food
description Things people eat</codebox><codebox char_offset="1354" frame_height="82" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
text name
text description
Topic<> supertopic</codebox><codebox char_offset="1402" frame_height="132" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic fruit:
name fruit
supertopic food
object Topic vegetables:
name vegetables
supertopic food</codebox><codebox char_offset="1971" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic things:
name things
object Topic entities:
name entities</codebox><codebox char_offset="2004" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic apples:
name apples
supertopic fruit, things, entities</codebox><codebox char_offset="2037" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic oranges:
name oranges
supertopic fruit
supertopic things
supertopic entities</codebox><codebox char_offset="2064" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic pears:
name pears
supertopic fruit
supertopic entities, things</codebox><codebox char_offset="2556" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic #42pf83j:
name pears
supertopic fruit
supertopic entities, things</codebox></node><node name="Unions" prog_lang="custom-colors" readonly="False" tags="" unique_id="134"><rich_text>So far, the only types we've been using are primitive types and class types. But it is also possible to define other types. There are 4 type definition mechanisms:
• union
• enumeration
• pattern
• range
In this section we'll talk about </rich_text><rich_text weight="heavy">unions</rich_text><rich_text>.
Union types in Idan are much like unions of sets in mathematics. When a type is a union of other types, its range of legal values is the union of these types' ranges. It can have any value valid for at least one of these types. For example, a union of </rich_text><rich_text weight="heavy">text</rich_text><rich_text> and </rich_text><rich_text weight="heavy">integer</rich_text><rich_text> can have any number and string as a value.
As the text and integer example shows, sometimes there's a conflict between types. For example 1234 can be a number but can also be a string. So does 17/06/2013. The solution for that is </rich_text><rich_text style="italic">precedence</rich_text><rich_text>: There's an ordering of the types, which determines how a value is matched to a type. In particular, </rich_text><rich_text weight="heavy">text</rich_text><rich_text> is the last type in the ordering, which means 1234 will be considered as a number, and 17/06/2013 will be considered as a date. I haven't decided yet how other types are ordered (for example, 17 can be time (in hours) or an integer). But in many cases, using such unions doesn't make much sense. Make sure you have a good reason to mix types.
Types can be defined explicitly, using the </rich_text><rich_text style="italic">type</rich_text><rich_text> keyword, or in-place where properties are defined. This allows for the following three options to define a class property:
• define type explicitly, define property explicitly, use in class
• define type explicitly, define property in-place
• define type and property in-place
As a result of this variety, it is sometimes confusing to decide which option to take. For example, you can define a type </rich_text><rich_text style="italic">size</rich_text><rich_text> as a non-negative </rich_text><rich_text style="italic">integer</rich_text><rich_text> and then define properties of type </rich_text><rich_text style="italic">size</rich_text><rich_text>. Or, instead, you can define a property called </rich_text><rich_text style="italic">size</rich_text><rich_text>, whose type is a non-negative integer. When adding </rich_text><rich_text style="italic">inheritance</rich_text><rich_text> or properties to the picture, it adds even more variety of options and confusion.
The key to effective work with data models and reusable types, properties and classes, is to understand the concepts behind the entities defined in Idan. In some cases it's ambiguous and any choice can be as good as any other, but in most cases it's possible to get one clear decision based on simple rules. If you stick to the rules, you'll achieve better design in less sleepless nights.
Types and properties, like we just saw, can basically do the same role in some cases. The following rule helps decide which entity should be a type, and which should be a property:
A </rich_text><rich_text weight="heavy">type</rich_text><rich_text> is a mapping between a textual representation of an entity, to the entity space itself. Types exist because we need to be able to express abstract concepts in a written manner. Types don't always represent the most efficient computer representation of an entity, but they do try to provide a readable convenient representation. Types don't deal with the meaning of the data - only with the mapping and representation.
A </rich_text><rich_text weight="heavy">property</rich_text><rich_text> represents a relation between entities. Both entities are represented through a computer representation, i.e. each has a type, but the property itself is the </rich_text><rich_text style="italic">meaning</rich_text><rich_text> of the relation. It doesn't deal with technical mapping or representation issues, and only focuses on the semantics of the relation.
Let's see an example. The </rich_text><rich_text style="italic">size</rich_text><rich_text> entity we mentioned conveys a </rich_text><rich_text style="italic">meaning</rich_text><rich_text>: it's not just a non-negative integer, but it's also a size. Natural numbers can also represent mass, length, speed, ID, dimension and so on. Many many things which aren't called </rich_text><rich_text style="italic">size</rich_text><rich_text>. So a size is a specific meaning we can give to a natural number. But a natural number, as a type, has no meaning. It's just a computer representation of an integer, restricted to non-negative values. It's onlt technical. So in this case, we define a type </rich_text><rich_text style="italic">natural</rich_text><rich_text> (or </rich_text><rich_text style="italic">unsigned_integer</rich_text><rich_text>, whichever we prefer), and then define a property </rich_text><rich_text style="italic">size</rich_text><rich_text> to be of type </rich_text><rich_text style="italic">natural</rich_text><rich_text>.
One of the technical key differences between types and properties, is that properties may have sub-properties ad super-properties, and thus form a property hierarchy. This feature may help choose between type and property in ambiguous cases. We'll examine property inheritance later.
Now let's go back to unions. Types are defined using the </rich_text><rich_text style="italic">type</rich_text><rich_text> keyword, and unions can use the </rich_text><rich_text style="italic">union</rich_text><rich_text> keyword right after </rich_text><rich_text style="italic">type</rich_text><rich_text>, although </rich_text><rich_text style="italic">union</rich_text><rich_text> is optional and exists mainly for readability. After that, in braces {}, we list the types we want to unite. Then the name of the new type, and we're done.
Let's try an example. Assume we want to have a </rich_text><rich_text style="italic">duration</rich_text><rich_text> type, which can be a time expressed as hh:mm:ss, or an integer in millisecond units. Then we want to make a union of </rich_text><rich_text style="italic">date</rich_text><rich_text> and </rich_text><rich_text style="italic">integer</rich_text><rich_text>. Using the union keyword for best readability, this is how we do it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
We can also omit the </rich_text><rich_text style="italic">union</rich_text><rich_text> keyword, in which case the {} containing types serve as the indicator, indicating we're creating a union:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now, any property with the </rich_text><rich_text style="italic">duration</rich_text><rich_text> type can have both dates and integers as valid values.</rich_text><codebox char_offset="4703" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {date, integer} duration</codebox><codebox char_offset="4840" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type {date, integer} duration</codebox></node><node name="Enumerations" prog_lang="custom-colors" readonly="False" tags="" unique_id="135"><rich_text>Enumerations are a way to explicitly specify the values a type can have. For example, the </rich_text><rich_text style="italic">boolean</rich_text><rich_text> type has two values: </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text>.
In order to ensure type safety, Idan allows the user to specify the type of all enumeration members. If not specified, they are determined automatically. Sometimes it's not what you want. Sometimes it is.
An enumeration is defined as follows. First, the usual </rich_text><rich_text style="italic">type</rich_text><rich_text> keyword. Then the optional </rich_text><rich_text style="italic">enum</rich_text><rich_text> keyword and an optional existing type. Then, a list of values inside braces {}, and finally the name of the new type. For example, we can define an </rich_text><rich_text style="italic">answer</rich_text><rich_text> type like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note that strings must be quoted, and cannot be multi-line. Then, </rich_text><rich_text style="italic">yes</rich_text><rich_text> and </rich_text><rich_text style="italic">no</rich_text><rich_text> can be used without quotes when assigning values to properties.
These examples are the same as the one above, but omit optional details:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Special care must be taken when not specifying the type. If we omit </rich_text><rich_text style="italic">text</rich_text><rich_text> from the definition, how will any software know which type we want to derive our new type from? Well, in this case it may seem obvious: we derive the </rich_text><rich_text style="italic">text</rich_text><rich_text> type. But this first thought is misleading: What if we already have a type </rich_text><rich_text style="italic">word</rich_text><rich_text> and we want to use the values "yes" and "no" from type </rich_text><rich_text style="italic">word</rich_text><rich_text> and not from type </rich_text><rich_text style="italic">text</rich_text><rich_text>?
In other cases it's more critical: 2342 can be an integer or a time (in hours). How will software know?
There are two ways to specify the type. One way is to set the type for the whole enum. The other way is to choose the type for each value individually. This is done by prepending the type name to the value, separated from the value by a # character. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When using this notation, </rich_text><rich_text weight="heavy">strings without spaces</rich_text><rich_text> </rich_text><rich_text weight="heavy">and commas</rich_text><rich_text> can be written without the quotes:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And again it's possible to omit the </rich_text><rich_text style="italic">enum</rich_text><rich_text> keyword:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to easily mix values from different types:
</rich_text><rich_text justification="left"></rich_text><rich_text>
So far we've seen only primitive types in use by enumerations. How do we use other types? For types derived from primitive types, there's no difference: just like text#yes is used, answer#yes can be used. But for classes it's different.
The values of class objects, i.e. the objects themselves, are represented by their local names. It's also possible to have URIs, but we'll get there in a later section. Local names can be specified right after the # in a similar manner to primitive types. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Instead, it's possible to specify the names using the namespace they come from:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In this case, it's also possible to specify the type before the braces, to make it clear (and allow testing) which type we use:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When a class comes from an external namespace, or just for readability, it's possible to specify it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note, however, that namespaces must be </rich_text><rich_text style="italic">imported</rich_text><rich_text> or </rich_text><rich_text style="italic">using</rich_text><rich_text>ed before their names can be used. Later we'll see how it's done.</rich_text><codebox char_offset="606" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum text {"yes", "no"} answer</codebox><codebox char_offset="825" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum {"yes", "no"} answer
type text {"yes", "no"} answer
type {"yes", "no"} answer</codebox><codebox char_offset="1592" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type enum {text#"yes", text#"no"} answer</codebox><codebox char_offset="1691" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type enum {text#yes, text#no} answer</codebox><codebox char_offset="1745" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type {text#yes, text#no} answer</codebox><codebox char_offset="1811" frame_height="24" frame_width="870" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type enum {text#hello, integer#3_201201, real#11.532%-8, date#17/6/13, time#22:54} some_type</codebox><codebox char_offset="2324" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type enum {Topic#fruit, Topic#vegetables} some_type</codebox><codebox char_offset="2408" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type enum {JaneTasks:fruit, JaneTasks:vegetables} some_type</codebox><codebox char_offset="2540" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type enum Topic {JaneTasks:fruit, JaneTasks:vegetables} some_type</codebox><codebox char_offset="2645" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type enum Todo:Topic {JaneTasks:fruit, JaneTasks:vegetables} some_type</codebox></node><node name="Patterns" prog_lang="custom-colors" readonly="False" tags="" unique_id="137"><rich_text>Patterns are the most expressive way to choose which values are valid for the new type you define. Since Idan currently doesn't support set-builder notation, patterns are the way when unions and enums aren't enough. Unless you use ranges, which we'll explore in the next section.
A pattern is a </rich_text><rich_text weight="heavy">regular expression</rich_text><rich_text>. Values are matched against it, and are considered valid only if they match the pattern. Currently, patterns are possible only for number types (e.g. integer, real) and strings (e.g. text).
Here's an example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The type can be any type which has text values and/or integer values and/or real values. It means any type derived using text, integer and/or real.
The regular expression is delimited by [" and "].</rich_text><codebox char_offset="526" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type text ["[a-zA-Z0-9]{8}"] some_type</codebox></node><node name="Ranges" prog_lang="custom-colors" readonly="False" tags="" unique_id="136"><rich_text>Ranges are a way to specify which values are valid for a type. They work for types whose values are ordered, by specifying a minimum value and/or a maximum value. Ranges can apply to numbers, dates and times.
() denotes an open range. [) and (] denote a half-open range. [] denotes a closed range.
The special values </rich_text><rich_text style="italic">inf</rich_text><rich_text> and </rich_text><rich_text style="italic">-inf</rich_text><rich_text> can be used.
Examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is </rich_text><rich_text weight="heavy">illegal</rich_text><rich_text> to use </rich_text><rich_text style="italic">inf</rich_text><rich_text> and </rich_text><rich_text style="italic">-inf</rich_text><rich_text> with ] and [ respectively, because a number cannot be infinite. It's also illegal to use inf as a minimum or -inf as a maximum. But both are legal for dates, times and numbers (although times start from 00:00:00, so no time is smaller than that).</rich_text><codebox char_offset="357" frame_height="80" frame_width="1000" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type integer [0, inf) natural $ any natural number i.e. non-negative integer i.e. unsigned integer
type real [0, 1] some_type $ any real number between 0 and 1 including both
type real (-inf, 5) other_type $ any real number smaller than 5
type date [1/1/2013, 17/6/2013] a_type $ any date between 1/1 and 17/6 in 2013, including both</codebox></node><node name="Comments" prog_lang="custom-colors" readonly="False" tags="" unique_id="129"><rich_text>Each line may end with a comment. A comment begins with a $ (S with vertical bar) character, and everything after that line after the $ is ignored. If a $ appears inside a string, it's not considered a comment. Also, multi-line comments are currently not supported. It's possible to have comment-only lines by starting them with optional indentation and then $ and comment text.
For examples, see previous (and probably next) sections.</rich_text></node><node name="Graphs" prog_lang="custom-colors" readonly="False" tags="" unique_id="130"><rich_text>Let's go back to Jane! It's time to define more topics, and start defining tasks. Here's what we made so far:
</rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text style="italic">todo.idano</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
The above code will actually </rich_text><rich_text weight="heavy">not work</rich_text><rich_text>, because todo.idano doesn't declare the Topic class. It must declare it, and only then it's legal to use it. We'll see later how it's done.
Graphs are an easy convenient way to define groups of objects. They use a short simple notation, without the clutter of explicit syntax. First, here's an example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Graphs have their own file extension, idang, so Jane is creating a new file </rich_text><rich_text style="italic">todo.idang</rich_text><rich_text>.
The above example may not exactly match our Task and Topic definitions, but it demonstrates graph features. Here's a summary of useful graph features:
• Generate IDs from properties
• Use numeric IDs
• Have a header property
• Have a child/parent property for hierarchy
Before I explain these features, let's examine the unique syntax rules used by graphs.
A graph begins with the </rich_text><rich_text style="italic">graph</rich_text><rich_text> keyword, followed by the name of the class whose objects are to be described in the graph, and then the name of the graph. Under that line, all other graph lines are indented.
Under the graph declaration line you can define optional properties. The properties are:
• auto
• header
• child
• parent
In a moment we'll see what they do. Under the properties you can define objects. Instead of defining one by one, you define them as a hierarchy. You don't need the </rich_text><rich_text style="italic">object</rich_text><rich_text> keyword. Object names/IDs can be specified after the /, but can also be omitted and auto-generated. One property can appear after the name/ID, without specifying every time the property's name. It's possible to refer to IDs using the @ character.
This may seem confusing. Let's see a simple example. Here's the definition of some tasks, in the explicit object definition notation we already know:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Surprisingly at first, the following graph defines the same objects:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Let's see how it does that. First let's look at task #0 and compare it. In the explicit definition, we set the content property to "Do something". In the graph we don't use </rich_text><rich_text style="italic">content</rich_text><rich_text> directly for every task. How does the graph know which property to set?
One of the possible 4 graph properties is </rich_text><rich_text style="italic">header</rich_text><rich_text>. The header chooses a property to be set on the line defining the object in the graph hierarchy. Once we set the </rich_text><rich_text style="italic">header</rich_text><rich_text> to </rich_text><rich_text style="italic">content</rich_text><rich_text>, the content property is set using what we enter after the ID (e.g. /0). Multi-line strings are not supported.
Under the object definition line, indented property lines can appear. These work just like in explicit notation. Under the properties, it's possible to specify </rich_text><rich_text style="italic">subtasks</rich_text><rich_text>. More objects. How does the graph know these new objects are subtasks of the task? It knows because we use a graph property: the properties </rich_text><rich_text style="italic">parent</rich_text><rich_text> and </rich_text><rich_text style="italic">child</rich_text><rich_text> set the property which represents sub-objects or super-objects. parent and child cannot be used together. Only one can be used. If we have a subtask property we can use child, while if we have a supertask property we can use parent.
It's possible to refer to objects in the graph, which have already been defined. In the last example, Task #3 is used twice: once as the child of #2 and again as the child of #4. Since it's already defined in the graph under #2, all we want under #4 is to </rich_text><rich_text style="italic">refer</rich_text><rich_text> to it, not define it. It's done using the @ character followed by the ID.
Another useful property is </rich_text><rich_text style="italic">auto</rich_text><rich_text>. IDs can always be omitted by leaving a space after the slash /, but sometimes we do want some IDs to be auto-generated. It's possible to do so by setting the </rich_text><rich_text style="italic">auto</rich_text><rich_text> property to an object property, and then that property is used for ID generation. For example, we want to refer to topics by name. We don't care about IDs. On the other hand, we want some of them to have labels. The solution is conversion rules: The IDs are not taken directly from the property.
Wait a second... I need to think about it further. How do we refer to IDs and local names in general? Does using things from different namespaces make a difference? Does using things from other files make a difference? I need to choose clear rules first, and then go back here. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO</rich_text><rich_text>
Another useful graph feature is to specify task completion. This is done by adding a box [ ], i.e. [ then space then ], after and index and before the task text. This box supports a status property. This property can be specified by the </rich_text><rich_text style="italic">state</rich_text><rich_text> property under </rich_text><rich_text style="italic">graph</rich_text><rich_text>, together with </rich_text><rich_text style="italic">header</rich_text><rich_text> and </rich_text><rich_text style="italic">child</rich_text><rich_text>. If the specified property is of type </rich_text><rich_text style="italic">boolean</rich_text><rich_text>, then in addition to </rich_text><rich_text style="italic">true</rich_text><rich_text>/</rich_text><rich_text style="italic">false</rich_text><rich_text> it's possible to use space and X as false and true respectively.</rich_text><codebox char_offset="122" frame_height="404" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri http://www.jane-todo.org/todo/
property text content
property date creation_time
property boolean complete
class Topic:
text name
text description
Topic<> supertopic
class Task:
required content
creation_time
required complete
Topic<> topic
Task<> subtask
date start_date
time start_time
date finish_date
time finish_time</codebox><codebox char_offset="136" frame_height="294" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace JaneTasks:
uri private
date_order dmy
date_separator /
object Topic food:
name food
description Things people eat
object Topic fruit:
name fruit
supertopic food
object Topic vegetables:
name vegetables
supertopic food</codebox><codebox char_offset="484" frame_height="520" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">graph Topic topics:
auto name
parent supertopic
/ Software
/ FreeSoftware
/ Licenses
/ Freedom
/ Freedom of Speech
/ Sharing
@Music
@Movies
/ Music
/ Movies
graph Task tasks:
header content
child subtask
/0 Do something
due_date 31/08/2013
topic action, planning, software
/1 Do something else
/2 Say something
/3 Listen to music
/4 Do things
@3</codebox><codebox char_offset="1837" frame_height="348" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">object Task #3:
content Listen to music
object Task #4:
content Do things
subtask #3
object Task #1:
content Do something else
object Task #2:
content Say something
subtask #3
object Task #0:
content Do something
due_date 31/08/13
topic action, planning, software
subtask #1, #2, #4</codebox><codebox char_offset="1910" frame_height="240" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">graph Task tasks:
header content
child subtask
/0 Do something
due_date 31/08/2013
topic action, planning, software
/1 Do something else
/2 Say something
/3 Listen to music
/4 Do things
@3</codebox></node><node name="Default Property Values" prog_lang="custom-colors" readonly="False" tags="" unique_id="138"><rich_text>Properties may have default values. These values are used in case a property doesn't appear. It's also possible to give a default value to a property of cardinality 0, in which case the default value is used for all objects.
The syntax is adding the </rich_text><rich_text style="italic">default</rich_text><rich_text> keyord after the property name in the class definition, and then the default value. For example:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="357" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
text name default New Topic
text description default No Description
Topic<> subtopic</codebox></node><node name="Inheritance" prog_lang="custom-colors" readonly="False" tags="" unique_id="131"><rich_text>It's possible for classes to inherit other classes, and for properties to inherit other properties.
When class B inherits class A, it means B is a subclass of A. It's a "special case" of A. For example, if A is Person, B can be Male. The set of male humans is a subset of all people, therefore any Male has all the properties a Person has, plus maybe some specific properties.
When property S inherits property R, it means S is a subproperty of R. The relation described by S is a subset of the relation described by R. For example, the </rich_text><rich_text style="italic">brother</rich_text><rich_text> property can be a subproperty of </rich_text><rich_text style="italic">family_member</rich_text><rich_text>, because it's a special case of it. Any brother is also a family member, but a family member doesn't have to be a brother.
Inheritance is probably not very useful for plain text documents, but it's a very powerful tool when the file is used with special software. Many kinds of useful reasoning and querying become available.
Inheritance in Idan is declared using the </rich_text><rich_text style="italic">base</rich_text><rich_text> keyword. When you define a property or a class, you can choose the base properties or the base classes, respectively.
Examples:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1099" frame_height="242" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ada" width_in_pixels="True">class Person: base foaf:Person
required text name link "http://xmlns.com/foaf/0.1/name"
required text email
text jabber link foaf:jabberID
text irc
required date birthday
Person{} knows
class Male: base Person
integer strength
property text content
property text special_content base content</codebox></node><node name="URIs" prog_lang="custom-colors" readonly="False" tags="" unique_id="132"><rich_text></rich_text></node><node name="Linking" prog_lang="custom-colors" readonly="False" tags="" unique_id="133"><rich_text></rich_text></node></node><node name="Notes" prog_lang="custom-colors" readonly="False" tags="" unique_id="140"><rich_text>Here I'm keeping notes which I'm going to take into consideration when writing the next version of the tutorial.</rich_text><node name="Object IDs" prog_lang="custom-colors" readonly="False" tags="" unique_id="141"><rich_text>On the Graphs page I gave an example which compares explicit object with graph objects. The example uses numeric IDs in explicit object notation. Also, the Objects page mentions this feature and gives an example.
Before I get to whether I </rich_text><rich_text style="italic">need</rich_text><rich_text> this feature at all, I'd like to start from the basics. Two things I need to do are:
• Specify requirements and suggestions for usage of IDs in graphs
• Define rules for usage of namespaces and qualified IDs
Both have issues in the current version of the tutorial, so I'll have to fix things.
</rich_text><rich_text scale="h3">Rules for Qualified Names</rich_text><rich_text>
I already chose characters here: </rich_text><rich_text link="node 108">Object Names and References</rich_text><rich_text>. These are the rules I chose there:
</rich_text><rich_text foreground="#ffffffff0000">Partager::comm.leaders#JohnSmith</rich_text><rich_text>
</rich_text><rich_text style="italic">Namespace membership</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">::</rich_text><rich_text>
</rich_text><rich_text style="italic">Set membership</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">#</rich_text><rich_text>
</rich_text><rich_text style="italic">Object property</rich_text><rich_text>: </rich_text><rich_text foreground="#ffffffff0000" weight="heavy">.</rich_text><rich_text>
These rules were nice then, but I'm not sure I'm going to keep them. In some cases, they actually may be better than new rules, for example the colon (:) is already used frequently in the language, and using it in IDs may cause confusion and less readable code. I can use :: instead, as suggested above.
The rules I started with in the tutorial are:
Object names:
contain only digits, letters and underscores, and must start with a letter
unique per namespace
referred by specifying them directly
Graph object names:
May begin with a number
May have ID auto-generated from property
I'm going to change some rules. I have new ideas. Let's go over graph requirements first.
</rich_text><rich_text scale="h3">Graph Requirements</rich_text><rich_text>
In the Graphs pages I wanted to do two things: Refer to topics by name, and avoid duplication with ID and text being identical. The problem is that topic text is usually human-readable, and contains spaces. It's not a giid choice for an ID. The workaround solution I suggested was to define ID generation rules: all spaces are converted to underscores and all letters become lowercase.
This may sound like a good solution for the specific case I had in the code example, but it doesn't sound like a general-purpose one. What if all properties contain quotes? Or the # character? I may not be able to auto-generate IDs conveniently, and for no good reason I'll be duplicating IDs and names.
The new solution I have is as follows:
Generating IDs from anything, especially free text, is a bad idea. I can do it the other way: Generate something using the IDs. For example, use lowercase-with-underscored (what I call donkeycase) for topics, and then transform the names for usage in GUI by replacing underscores with spaces and converting to Title Case. Special software can also auto-generate these title-case names, and then no conversion is necessary when reading from the file, thus even simple software will display correct Title Case names.
So this issue is solved. Here's an example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The </rich_text><rich_text style="italic">auto</rich_text><rich_text> property can stay, but now it has a new meaning: instead of generating IDs, it specifies properties whose values are auto-generated from and IDs. Wait a second... the same thing can work for explicit definition.
</rich_text><rich_text weight="heavy">NEW FEATURE</rich_text><rich_text>: The </rich_text><rich_text style="italic">auto</rich_text><rich_text> property of graphs is still in use, but it's just in addition to the class-specific option to auto-generate properties from IDs.
This is how default values currently work:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's now possible to state that a property is auto-generated from the ID! This feature is meant to allow separation of labels from IDs and avoid the bad design in which software assumes IDs are human readable and uses them as labels when nothing else is provided.
The </rich_text><rich_text style="italic">auto</rich_text><rich_text> keyword means a property is auto-generated in case it's not specified. If a property has cardinality 0, then it can't appear and is always auto-generated. The usage is exactly like the above example, with </rich_text><rich_text style="italic">default</rich_text><rich_text> replaced by </rich_text><rich_text style="italic">auto</rich_text><rich_text>: (and without any default value, of course)
</rich_text><rich_text justification="left"></rich_text><rich_text>
Another graph requirement is the option to use Topic IDs directly in Tasks, in order to avoid the ugliness of specifying qualified names all the time, but before I get there I want to plan some rules for names.
</rich_text><rich_text scale="h3">Object Names</rich_text><rich_text>
This is how namespaces are imported currently:
</rich_text><rich_text style="italic">Now the usings can be added. First, they should be able to point to other local namespaces:</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text style="italic">Then, they should be able to point to a language namespace using a URI:</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text style="italic">And, they also should be able to point to RDF namespaces:</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now let's organize the mess into useful definitions and rules! I want to allow two things:
• Introduce a namespace
• Allow referring to entities without the namespace prefix
In RDF, when referring to an external entity, we need its URI. When defining an entity using a local name, this name is just the last part of its URI. This is fine because RDF is not meant to be written by hand. But in Idan, everything - classes, properties and objects - should be easily possible to write without any special tools. A text editor should be enough for effective work.
This is where </rich_text><rich_text style="italic">local names</rich_text><rich_text> fit in the big picture. They are a human-readable way to give names to entities, and can work alongside the URIs. In this matter, Idan somewhat combines concepts from data modeling (a gloabal URI for data objects) and programming (a human-readable name used by the programmer).
Since Idan is just a language, it doesn't provide data security. The data storage mechanism determines who has access to which data. But Idan does provide the tools and the foundations, which allow security mechanisms to function more easily on top of the plain text files.
Each entity you define has a URI. This URI is the globally unique name of the entity. The purpose of this name is to make software be able to detect appearance of one URI in different places, or determine identity using equality of URIs. Since any data may be private, and any public data may become private if the user decides so, the default in Idan is that all the entities are private.
The default mechanism for generating private URIs is currently UUID. Idan doesn't enforce that, but recommends using UUIDs. Version 4 UUIDs are random, and thus provide the best privacy, because they don't encode any information.
For the user's convenience, objects also have local names. These names are not meant to be used by any external entity. They can be referred to only from local namespaces. Software can protect local namespaces by blocking any access to them from outside. Inside the bubble of local namespaces, local names are a convenient way to refer to the entities you define.
How to we specify the kind of privacy we want? The tutorial has an example which uses the </rich_text><rich_text style="italic">uri</rich_text><rich_text> property of </rich_text><rich_text style="italic">namespace</rich_text><rich_text>. Such a URI can be set by hand, or to </rich_text><rich_text style="italic">auto</rich_text><rich_text> (public automatic) or to </rich_text><rich_text style="italic">private</rich_text><rich_text> (private automatic). This setting applies to the whole namespace.
We've already seen how local names are chosen: You choose a name composed of letters and digits and _ which starts with a letter, and then this name should be namespace-unique. The question is: Is this the right decision? Why not have it only be file-unique? It makes it much easier to avoid name collisions, and much easier to find a definition on the local system. In order to answer this question, let's examine the possible usage patterns. Then we'll be able to see which option suits them better. The usage patterns are:
• Direct Editing, Direct Viewing
• Direct Editing, Aided Viewing
• Aided Editing, Aided Viewing
Assume the first option. The user works only with the plain text files, directly. Then, does it matter whether the names are namespace-based or file-based? Probably not. Even if the user by mistake creates two objects with the same name, it won't interfere with the regular usage pattern. Software would get confused, but the user can easily detect the mistake as soon as it becomes clear and relevant.
Now let's examine the second option. The user edits the files directly, but uses software-generated reports and views. In this case, does file-based naming better than namespace-based? Assume we have a single file. Then naming rules don't matter. Now assume we have several files which use objects from each other. Then in order to detect connections between objects, the software will have to scan all the files and create a mapping between names and actual object property values. But if we make the names per-file, there are two options:
1. We import namespaces but use them for qualifying names
2. We import namespaces and we </rich_text><rich_text style="italic">using</rich_text><rich_text>ize them, so that we're able to refer to their members directly
Either the code becomes ugly, or we don't get any new advantage. Question: If we use the same namespace in several files, can we still refer to them directly using local names? Answer: Why not? It doesn't make a big difference anyway: If we can "import" a namespace into the local scope, then it's as if we use names from our own local namespace. If we can't, then not being able to directly refer to those objects will make it impossible to directly write their names unless they're in the same file. This would result in topic and tasks being in the same file. And that can easily lead to bad design, mess, huge files and inefficient workflow.
So the decision is: The user can always use separate namespaces for separate files. Without practical experience, I can't tell how useful it is to choose file-based names. For now, it seems not better than namespace-based. If some software needs to scan files, it will have to scan them anyway, fetch and connect all objects, and essentially do the same mapping in any case. The only issue is finding the right files, but the solution for that is to keep files in a folder, and let the programs find all files in that folder and scan them all.
</rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: Use namespace-based names.
As long as we refer to objects from our own namespace, we don't need to declare anything special. If software can't find those objects, it may complain, but we don't expect it to look for them on the web anyway. At least now right now. But assume we want to use entities from another namespace. How do we use classes, properties and objects from other namespaces?
Question: Currently, local namespaces must be declared before used. Is there a real good reason to enforce that? Hmmm good question. Why do I enforce that? If a namespace is used without declaring it, why not assume automatically it's a local namespace?
No reason not to. Great. Now here's another question: Is there a reason to specify explicilty a local namespace? No. But it may be useful in the future, maybe to help software find things.
</rich_text><rich_text style="italic" weight="heavy">DECISION</rich_text><rich_text>: Local namespaces can be used without </rich_text><rich_text style="italic">using</rich_text><rich_text>, but </rich_text><rich_text style="italic">using</rich_text><rich_text> may be used anyway, and its actual use is reserved for future features.
How do we refer to classes, properties and objects from other namespaces? I had a syntax idea, let's see if it's good enough. It may solve the problem of specifying both namespace and class in the same entity reference. As you probably have seen in the tutorial, the # character may be used for access to an object within a class. The class is like a set, and the object is like a member of the set. For example, </rich_text><rich_text style="italic">Person#john_smith</rich_text><rich_text>. We'll get back to this in a moment, after we explain how namespace members are accessed. We need some other "operator". I chose, at least for now, the :: operator. I replaced : with :: because : is already in use. For example, Todo::Task. This is the Task class from the Todo namespace.
For properties, I haven't planned anything yet. So here's the rule: exactly the same operator. For example, </rich_text><rich_text style="italic">Todo::due_date</rich_text><rich_text>.
Now, what do we do with objects? Do we really need the # character, or referring to object with :: is enough? With graph objects, if we allow numeric IDs, we may need the # character. But the question is: Do we need numeric IDs for anything at all?
I had an idea, as you can see on the Objects page, to allow numeric IDs with # in order to better support automatic mass object creation. But in fact, this is what UUIDs are for!!! The computer can generate UUIDs. It doesn't need to use local names. I can use the # for object URIs, but I don't need it for local names. Isn't using the namespace enough?
Let's give it another thought. Imagine you have tons of object. Unlike </rich_text><rich_text style="italic">john_smith</rich_text><rich_text>, it's possible to have an object whose local name isn't very clear. So mentioning the namespace may be quite useless. Also, mentioning the class would make finding the object faster. Why not allow that? For example, assume I have a rich multi-file namespace with an object </rich_text><rich_text style="italic">apple</rich_text><rich_text>. Then I can refer to it as NameSpace::apple. But I can also make sure users don't get confused with the conpany Apple by using the class: Fruit#apple. But... that's not all. What if </rich_text><rich_text style="italic">apple</rich_text><rich_text> belongs to another namespace? What if Fruit belongs to another namespace?
This is how we'd qualify Fruit:
SomeName::Fruit#apple
This is how we'd qualify apple:
Fruit#OtherName::apple
This is how we'd qualify both:
SomeName::Fruit#OtherName::apple
</rich_text><rich_text weight="heavy">Question</rich_text><rich_text>: Now, with the new rules, should we allow namespace name import? i.e. the equivalent of </rich_text><rich_text style="italic">using namespace</rich_text><rich_text> in C++?
Hmmm... good question. Using Topic names directly in Tasks may benefit from this. On the other hand, maybe importing specifically for a give graph may be better. On the third hand, it's possible to just write the graph in a separate file. TODO next time!!!!!!!
Hmmm indeed adding the ability to import for a specific graph is just an extra optional feature which makes the language more complicated. The question is, how do we make sure we don't get confused with the names.
Suggestion: Local names here are not like in a programming language. If two unrelated things get the same name, it's no big deal. In the task graph, when using topic names directly, the definition of Task makes it clear that the names are Topic objects, nothing else. So software can easily limit its search range to Topic objects from the same namespace or an imported namespace. This lowers collision chances to minimum.
</rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: Allow to import a namespace only per-file, not per-graph.
Next question: should we allow importing specific symbols from a file? For example, import only specific properties, or all properties, or a specific graph, or specific classes. Like </rich_text><rich_text style="italic">typedefs</rich_text><rich_text> or </rich_text><rich_text style="italic">using std::string;</rich_text><rich_text> in C++. Actually I'm not sure using std::string is allowed there, but you get the point.
Obviously this feature can reduce name collisions for large files, but well-written files are short and purpose-specific, so usually you want the whole file. If you want just a part of it, it usually means your file can be split into two.
Without seing usage patters, I can't say this feature can be useful sometimes, but I prefer to have a minimal set of features, therefore it is currently not possible to import specific entities. What is the syntax for that?
Suggestion: I still want to keep </rich_text><rich_text style="italic">using</rich_text><rich_text> reserved, but it means all I have is </rich_text><rich_text style="italic">import</rich_text><rich_text>. I want to keep the RDF keywords separate, so that it's clear when we use an Idan file and when we use an RDF file. The suggestion is, add a new keyword. This keyword will allow importing symbols into the file scope directly. But it will work only for Idan files, not RDF. I can change the keywords later, but currently this is my suggestion: Use </rich_text><rich_text style="italic">include</rich_text><rich_text> instead of </rich_text><rich_text style="italic">using</rich_text><rich_text>, and now </rich_text><rich_text style="italic">import</rich_text><rich_text> is still used for RDF, and </rich_text><rich_text style="italic">using</rich_text><rich_text> is used for direct scope import, like </rich_text><rich_text style="italic">using</rich_text><rich_text> is used in C++. Before I decide... any other keyword suggestions? Hmmm... no.
</rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: </rich_text><rich_text style="italic">include</rich_text><rich_text> is reserved, </rich_text><rich_text style="italic">import</rich_text><rich_text> still used for RDF like before and </rich_text><rich_text style="italic">using</rich_text><rich_text> adds foreign namespace symbols into the local scope for direct usage.
</rich_text><rich_text weight="heavy">Question</rich_text><rich_text>: I didn't take one thing into account: What if you do have short well-written files, but they all belong to the same namespace? Classes, properties and objects, all belong to one namespace. How do you import only the part you want?
Suggestion 1: Specify what you want to import: objects, properties, types or classes (or any combination).
Suggestion 2: Be able to import file-based: Choose both a namespace and a file.
The first suggestion sounds like a workaround. In many cases it's not good enough, especially for objects. The second suggestion ties the user with the internal arrangement of entities in files, so any change there breaks user files. Maybe I should allow defining a sub-namespace. Then file internals are not exposed.
Another question: I've been reserving the dot operator (.) for class/object properties. But when do I actually use that? Is there a reason to ever refer to a class property or to an object property? Hmmm... maybe not. But I'll keep reserving the dot operator for that.
Sub-namespaces can easily solve problems, but can also introduce tons of new complexity. For example, how do you divide your code into sub-namespaces? </rich_text><rich_text style="italic">When</rich_text><rich_text> is your code big enough? What's the difference between files and sub-namespaces?
Currently, all you can do is to import a namespace. It means all the namespace's symbols become accessible. If that namespace is big, which makes sense sometimes (like in RDF namespaces such as dc, foaf and others), there may be a high chance of collisions, and too many extra imports you don't need. Here are three suggestions:
1. </rich_text><rich_text style="italic">using</rich_text><rich_text>ize per file
2. </rich_text><rich_text style="italic">using</rich_text><rich_text>ize per entity
3. </rich_text><rich_text style="italic">using</rich_text><rich_text>ize per sub-namespace
In C and C++, it makes sense to import per-file. The reason is that the code is split into source and header, and the header is the "official" mechanism for using the powers offered by the source. But Idan is different. C and C++ are programming language, which means they focus on </rich_text><rich_text style="italic">execution of commands</rich_text><rich_text>. Idan is a data description language, so its focus is </rich_text><rich_text style="italic">modeling and data definition</rich_text><rich_text>. So the decision doesn't have to be similar. How do we make the best choice?
I have an idea. Let's try to answer the following question: What are the typical use cases for importing symbols from other namespaces?
The entities you may want to import are:
• type
• property
• class
• graph
• object
Where you may want to use them:
Define types using an existing type
Define properties using an existing type
Define -
Wait a second! I think I just realized something... The case of Topics in Tasks is special: it's a case of object definition! When you define the data model, there's no mass definition to do. The issue of importing symbols arises when you want to use many symbols from a namespace, and avoid typing prefixes all the time. So maybe I should allow importing </rich_text><rich_text style="italic">only objects</rich_text><rich_text>. What do you think? This can easily solve the problem.
</rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: Allow </rich_text><rich_text style="italic">using</rich_text><rich_text> to import names, but </rich_text><rich_text weight="heavy">only</rich_text><rich_text> object names.
That's not all! What do we do with graphs? Are there special cases with graph object IDs? No. Not at all.
</rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: Graph objects are just like any other object, and can be referred using class and namespace names, like regular objects. Maybe I'll add refer-by-graph later.
Mass definition of objects still introduces an issue. If we define may many objects, there's a chance we need to define a topic named "import" or "union" or "class" or something like that, or we define a topic with a name identical to the name of a class or an object.
What I'm saying is that maybe there should be some special syntax for object definition and references. Currently, objects are referred to by name, with optional class and namespace. But there's no shorthand notation, like prepending a # to the name. Then, specifying topics is still easy: </rich_text><rich_text style="italic">#software, #music, #good_people</rich_text><rich_text>. And there's no ambiguity: these have to be objects.
On the other hand, it doesn't help at all if two objects have the same name.
Idea: In this specific case, I want to use Topics only from a given graph. In general, any task can have any topic, but when I start defining my tasks and topics, it may be nice to be able to say "all the Topic objects I use here are defined in the given file" or "given graph".
Hmmm... this idea definitely solves the problem. The question is: How do we mark these things in the language? Assume I -
Wait a second. When I specify a Topic property value, it's obvious it's a topic, otherwise it's a user mistake and software should warn the user. So there's no need for the user to say anything: the problem arises only when two topics have the same name, and in this case the software can easily warn the user or let her choose a topic and add an explicit reference or change the name, etc.
</rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: No need for a new feature for object references.
</rich_text><rich_text scale="h3">Last Thing</rich_text><rich_text>
I believe I found answers and solutions for the issues I wanted to solve here. Now I can suggest syntax for the advanced features (inheritance and linking) and then write a second version of the tutorial.</rich_text><codebox char_offset="2758" frame_height="520" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">graph Topic topics:
auto name
parent supertopic
/software
/free_software
/licenses
/freedom
/freedom_of_speech
/sharing
@music
@movies
/music
/movies
graph Task tasks:
header content
child subtask
/0 Do something
due_date 31/08/2013
topic action, planning, software
/1 Do something else
/2 Say something
/3 Listen to music
/4 Do things
@3</codebox><codebox char_offset="3179" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
text name default New Topic
text description default No Description
Topic<> subtopic</codebox><codebox char_offset="3731" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
text name auto
text description No Description
Topic<> subtopic</codebox><codebox char_offset="4101" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
using Arbre local</codebox><codebox char_offset="4177" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
using Angel "freedom://iklein/angels/"</codebox><codebox char_offset="4239" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
import dc "http://purl.org/dc/elements/1.1/"</codebox></node><node name="Importing External Entities" prog_lang="custom-colors" readonly="False" tags="" unique_id="143"><rich_text>How do we import and use external entities? Good question.
Currently Idan doesn't allow to refer to external objects using the local name directly. The only options are to use the local name with a namespace prefix, or use the resource URI.
Prefixes must be declared before being used:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Then a prefix can be used like an Idan namespace. For example, once the FOAF namespace is declared, the Person class from the FOAF namespace can be used through the name foaf::Person.
Note that "external" does </rich_text><rich_text style="italic">not</rich_text><rich_text> mean or imply RDF. In theory, it's possible to support many tools and languages. RDF is just one of them.
RDF entities can be used in the following ways:
• have an Idan property which derives from an RDF property
• Have an Idan class which derives from an RDF class
But I'm considering adding these too:
• Have an Idan class which uses an RDF property
• Have an Idan class which matches to an RDF class
I'm not sure. It deserves a thought, doesn't it? First let's see how Idan entities can inherit external ones. The following code is what I wrote in the </rich_text><rich_text weight="heavy">first tutorial</rich_text><rich_text> and needs </rich_text><rich_text underline="single" weight="heavy">fixing</rich_text><rich_text>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The first problem here is the usage of : where :: is supposed to be. Let's fix it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The usage of </rich_text><rich_text style="italic">base</rich_text><rich_text> here is fine, but the usage of </rich_text><rich_text style="italic">link</rich_text><rich_text> deserves some attention.
Should there be a difference between an external URI and an Idan URI? Is it useful at all, to give just a URI? Should it be allowed to link an anonymous property with a property through a URI? Let's answer these questions.
First, it doesn't make sense to link an unnamed property with an Idan property. If you want to use an Idan property, specifying its type is duplication of information. The only thing specified should be its URI or local name. This example suggests syntax rules:
</rich_text><rich_text justification="left"></rich_text><rich_text>
I considered to have the last line start with a keyword, such as </rich_text><rich_text style="italic">property</rich_text><rich_text>, but then I realized all the lines are properties anyway, so it just adds unnecessary clutter to the code. Just use a URI string, and make it quoted (otherwise it will be interpreted as a type or a property name, and if none are found, the parser will report an error).
One problem which may arise here is the fact that the property link doesn't have to actually link to any web resource, and there's no way to validate the property values against the property's type if it's unknown. But that's fine: in any case, the best that software can do is to try to find the property on the local system or known connections, and just give up if it fails. There may also be an ability to look for it on the web, but this is a long term thing. For now, the important thing is to store the URI, and be able to identify other properties which have the same URI.
Now, how do we make an Idan property derive from an RDF property? Or link to an RDF property? And another question, should it be possible to use RDF objects as property values?
Before we get there, we need to answer other questions: </rich_text><rich_text style="italic">What does it mean</rich_text><rich_text> for a property or a class to link/derive from RDF? What are the implications of using RDF objects in Idan, and what are the rules for that?
Very good questions, indeed. Let's start.
• class links to class
• class derives from class
• property links to property
• property derives from property
• class has external object as a property value
When a class links to an external class, it means they represent the same set. For example, if Todo::Person links to the RDF class foaf::Person, it means both represent objects from the "set of all people". This allows conbining data. For example, when looking for "all the people on my database", software will be able to detect both Todo people and foaf people, because the </rich_text><rich_text style="italic">link</rich_text><rich_text> states they both represent the same class.
The question is whether the link requires, represents limits or implies any connection between the properties of the classes. For example, if I define Todo::Person to link to foaf::Person, how do I define Todo::Person's properties? Are there any special rules? Basically there are two options: Define properties without linking to RDF properties, or define them with linking.
This is why I decided to accept basing, but left linking in the "optional feature" state. Some RDF classes may have a restricted set of properties. RDFS doesn't support that, but OWL does. In such cases, you can't specify any extra properties for an RDF object. If you link an Idan class to such a restricted OWL class, you create a contradiction with the OWL class definition. On the other hand, maybe OWL or another language has classes whose restrictions apply to derived classes too. Or even prevent the definition of derived classes.
Since the external language is not known, and can be any language, it's the user's responsibility to make sure the code doesn't create contradictions. It's possiblt to link and base a class, but the user should pay attention to definitions and limitations.
What about the properties? When defining Todo::Person, you can use real foaf properties (or other RDF properties), or just use Idan properties without linking. Should it be possible to link well-defined Idan properties to RDF properties? I already wrote an example which uses an Idan property specified as a URI. Can I use an RDF property in a similar way? And can I define an Idan property and connect it to an RDF property?
Yes. It's possible to define an Idan property and link it with an external property:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Property and class linking means "</rich_text><rich_text weight="heavy">a</rich_text><rich_text> is a </rich_text><rich_text weight="heavy">A</rich_text><rich_text> iff </rich_text><rich_text weight="heavy">a</rich_text><rich_text> is a </rich_text><rich_text weight="heavy">B</rich_text><rich_text>". And inheritance means "if </rich_text><rich_text weight="heavy">a</rich_text><rich_text> is </rich_text><rich_text weight="heavy">Derived</rich_text><rich_text> then </rich_text><rich_text weight="heavy">a</rich_text><rich_text> is </rich_text><rich_text weight="heavy">Base</rich_text><rich_text>".
Let's define some syntax. The features for classes are:
• class derives from Idan class
• class derives from external class
• class links to external class
First let's suggest the syntax for each option used alone.
Deriving an Idan class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Deriving external class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Linking to external class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
The </rich_text><rich_text style="italic">import</rich_text><rich_text> keyword there can be replaced with a new keyword </rich_text><rich_text style="italic">external</rich_text><rich_text>, but using </rich_text><rich_text style="italic">import</rich_text><rich_text> has the advantage of not adding a new keyword. And one of the guidelines is to minimize the number of keywords.
Deriving an Idan class is simple, there's nothing to add there. You just use the </rich_text><rich_text style="italic">base</rich_text><rich_text> keyword as shown above. Inheritance means all the properties of the parent class can also be specified in the child class. So an object of class Derived can have the properties defined for class Base.
When deriving an external class, there are two issues: syntax issue and property issue. The syntax issue shows up when referring to the external class using a URI. How does the software know it's an external class? The answer is that in general the database shouldn't care about languages, and software should handle this issue, but I added the </rich_text><rich_text style="italic">base import</rich_text><rich_text> keyword combination, which allows to clearly state that the URI referes to an external URI and there's no need to expect it to be found in Idan files.
The property issue is as follows: If an Idan class derives an external class, does it inherit its properties? What happens when instances are defined for such a class?
I guess the answer somewhat depends on the language and the software. If you define an object of a class derived from an external class, you can use any property you defined for your class. But usage of other properties... this is the issue. I can let the implementation decide, or enforce a rule. The rule can be, for example, that each property must be a derived class property, or a linked property. The user is responsible for making sure only actual legal properties are used, and the software should do its best to verify the code.
So the question is: Do I allow these linked properties or not? </rich_text><rich_text style="italic" weight="heavy">Decision</rich_text><rich_text>: Yes, currently I do.
Now let's examine linking to an external class. How does it affect property usage? Same thing, it depends on the external language and on the software. But unlike with inheritance, you </rich_text><rich_text style="italic">can't</rich_text><rich_text> use properties without justification. All properties </rich_text><rich_text style="italic">must</rich_text><rich_text> be specified in the class definition. You may link them to external ones, but you have to specify them in the class before usage in objects.
Since this behavior is not consistent with all languages, or at least </rich_text><rich_text style="italic">may</rich_text><rich_text> not be, currently the whole feature of linking with external entities is </rich_text><rich_text underline="single" weight="heavy">experimental</rich_text><rich_text> and will be studied thoroughly by practical usage.
</rich_text><rich_text weight="heavy">Question</rich_text><rich_text>: How can these features be combined? Let's examine the options:
• class derives from an Idan class and from an external class
• class derives from an Idan class and links to external class
• class derives and links to external classes
Wait a second... these features raise a new issue: What if one class derives many classes? Is it a good idea to make all the </rich_text><rich_text style="italic">base</rich_text><rich_text>s and </rich_text><rich_text style="italic">link</rich_text><rich_text>s be on a single line? </rich_text><rich_text underline="single" weight="heavy">No</rich_text><rich_text>. Let's change that!
Here's a new suggested syntax for the 6 examples above:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
All I did is to move the </rich_text><rich_text style="italic">base</rich_text><rich_text>s and </rich_text><rich_text style="italic">link</rich_text><rich_text>s to a new line. Now many can be specified, each in a separate line.
So which combinations make sense?
The </rich_text><rich_text weight="heavy">first</rich_text><rich_text> one is perfectly valid:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The </rich_text><rich_text weight="heavy">second</rich_text><rich_text> one makes less sense. Hmmm... such a case may make sense if there's a simple rdfx::Person class and I have some complicated hierarchy with more properties. Then I want my Person class to be an rdfx::Person, but also have all the properties inherited from my base classes. </rich_text><rich_text weight="heavy">Decision</rich_text><rich_text>: Okay, it's allowed.
The </rich_text><rich_text weight="heavy">third</rich_text><rich_text> feature doesn't make sense. When is that useful? Deriving A and linking B implies B is, or should be, a subclass of A. If it really is, then there's no reason derive A. If it isn't, maybe the external tool should take care of that. Hmmm... this one deserves some thought. </rich_text><rich_text weight="heavy">Decision</rich_text><rich_text>: Currently not allowed, but will be examined.
Now let's take care of properties. The features are:
• property derives from Idan property
• property derives from external property
• property links to external property
Here are syntax suggestions for each, assuming explicit definition:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Wait a second, what if a property has several bases and links? All written on a single line.
</rich_text><rich_text underline="single" weight="heavy">New Syntax Rule</rich_text><rich_text>: A class or a property which doesn't need anything under it, can be defined on a single line without a colon:
</rich_text><rich_text justification="left"></rich_text><rich_text>
But when specifying anything for a class, and when specifying property base/link, you must use the colon:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we have an initial syntax plan. But what does property inheritance mean? How does it work?
When an Idan property derives another property, its type must be a subset of the base property's type. It's possible to specify the derived property's type explictly, or make it be the base property's type by using </rich_text><rich_text style="italic">auto</rich_text><rich_text> as the type. It's also possible to define an enum or pattern type for the derived property, using </rich_text><rich_text style="italic">auto</rich_text><rich_text> again to specfy the base's type. If there's more than once base, then </rich_text><rich_text style="italic">auto</rich_text><rich_text> is defined to be the intersection of all bases' types.
What about in-place property definition? Can such a property have a base? </rich_text><rich_text weight="heavy">Decision</rich_text><rich_text>: Currently, </rich_text><rich_text weight="heavy">no</rich_text><rich_text>. If the user cares about property hierarchies, she should explicitly define them. In-place properties are meant to be practical and simple.
Now let's handle deriving an external property. The syntax is simple: use the </rich_text><rich_text style="italic">base</rich_text><rich_text> keyword with a name or a URI, and optionally use </rich_text><rich_text style="italic">base import</rich_text><rich_text> with an external URI, like with classes. But how do we define the type of the property? </rich_text><rich_text weight="heavy">Decision</rich_text><rich_text>: We define whatever we want, but using values not legal for the external property is an error. For example, if the external property has a numeric type, deriving it with a textual property is an error. Sometimes due to encoding issues or other subtleties, such an error may not be detected in the declaration, and only be detected when defining objects, but this issue is specific to the external language used. We'll see later.
Note that </rich_text><rich_text style="italic">auto</rich_text><rich_text> is not possible in this case. The type must be specified.
There's also the property linking feature. Here again, the type should be stated, and the matching of values against the external language, if necessary, depends on the software and on the external language. Syntax: Just use an indented </rich_text><rich_text style="italic">link</rich_text><rich_text> line.
Now let's examine combinations.
• property derives Idan property and external property
• property derives Idan property and links to external property
• property derives and links to external properties
The first one makes sense. The type must be a subset of the bases' types and match the external properties' types.
The second one may make sense. You have a property hierarchy, and one of the properties happens to match some external property. Accepted.
The third one may make sense too, but for now it's </rich_text><rich_text weight="heavy">not</rich_text><rich_text> </rich_text><rich_text weight="heavy">allowed</rich_text><rich_text>. Just like with classes.
What about in-place linking? I said in-place base is not supported, but what about in-place linking? Or in-place usage of an Idan property?
Currently, for </rich_text><rich_text weight="heavy">simplicity</rich_text><rich_text>, in-place linking is </rich_text><rich_text weight="heavy">not allowed</rich_text><rich_text>. But it's possible to use an in-place property URI as shown in examples above.
</rich_text><rich_text weight="heavy">Last thing</rich_text><rich_text>, can objects be of external class? Can Idan objects have external object URIs as property values? In order to allow interconnection of data, Idan objects must be able to store URIs. But when not storing them as plain strings (which is a workaround), they must point to objects of a valid class. If an object has a property whose type is class A, then the property value has to be of type A, or any linked type, or any derived type.
But can a property's type be an external class? Answer: </rich_text><rich_text weight="heavy">Yes</rich_text><rich_text>. In this case, the value must be an object whose type is the specified class A, or any class linked with A (including external and local ones, if such exist), or any class derived from A (including external and local ones, if such exist).</rich_text><codebox char_offset="289" frame_height="64" frame_width="800" highlight_brackets="False" show_line_numbers="True" syntax_highlighting="cpp" width_in_pixels="True">namespace Sylva:
uri auto
import dc "http://purl.org/dc/elements/1.1/"</codebox><codebox char_offset="1101" frame_height="242" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ada" width_in_pixels="True">class Person: base foaf:Person
required text name link "http://xmlns.com/foaf/0.1/name"
required text email
text jabber link foaf:jabberID
text irc
required date birthday
Person{} knows
class Male: base Person
integer strength
property text content
property text special_content base content</codebox><codebox char_offset="1188" frame_height="242" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ada" width_in_pixels="True">class Person: base foaf::Person
required text name link "http://xmlns.com/foaf/0.1/name"
required text email
text jabber link foaf::jabberID
text irc
required date birthday
Person{} knows
class Male: base Person
integer strength
property text content
property text special_content base content</codebox><codebox char_offset="1758" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ada" width_in_pixels="True">property text my_prop
class MyClass:
my_prop
required SomeName::some_prop
"freedom://jane/todo/prop" <3:7></codebox><codebox char_offset="5398" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text {"yes", "no"} my_prop link http://www.gordf.org/prop</codebox><codebox char_offset="5759" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: base Bar
my_prop</codebox><codebox char_offset="5762" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: base "freedom://jane/todo/base" & must use quoted URI
my_prop</codebox><codebox char_offset="5791" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: base foaf::Person
my_prop</codebox><codebox char_offset="5794" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: base "http://jane.rdf.org/todo/person"
my_prop</codebox><codebox char_offset="5797" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: base import "http://jane.rdf.org/todo/person"
my_prop</codebox><codebox char_offset="5828" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: link "http://jane.rdf.org/todo/person"
my_prop</codebox><codebox char_offset="5831" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo: link foaf::Person
my_prop</codebox><codebox char_offset="8728" frame_height="62" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
base Bar
my_prop</codebox><codebox char_offset="8731" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
base "freedom://jane/todo/base" $ must use quoted URI
my_prop</codebox><codebox char_offset="8734" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
base foaf::Person
my_prop</codebox><codebox char_offset="8737" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
base "http://jane.rdf.org/todo/person"
my_prop</codebox><codebox char_offset="8740" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
base import "http://jane.rdf.org/todo/person"
my_prop</codebox><codebox char_offset="8743" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
link "http://jane.rdf.org/todo/person"
my_prop</codebox><codebox char_offset="8746" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Foo:
link foaf::Person
my_prop</codebox><codebox char_offset="8928" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class SmartPerson:
base foaf::Person
base Todo::SmartBeing</codebox><codebox char_offset="9827" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text my_base
property text my_prop1 base my_base
property text my_prop2 base rdfx::some_prop
property text my_prop3 link rdfx::other_prop</codebox><codebox char_offset="10051" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class C $ doesn't make any sense currently
property text p $ nothing has changed so far</codebox><codebox char_offset="10161" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class B:
base A
property text q:
base p</codebox></node><node name="URIs and UUIDs" prog_lang="custom-colors" readonly="False" tags="" unique_id="147"><rich_text>Done with the long issue of linking and basing. Now, before I plan how namespaces and URIs are related to privacy features, let's see what are URIs and UUIDs and where/how/why they are used in Idan.
Well, there isn't much to say. Basically UUIDs are just a special case of URIs. A URI is a machine-readable unique identifier of a resource or entity. Usually URIs have a resolver mechanism/service which can give you information about the resource, given its URI. Some URIs point to the location of the resource, while others just contain its name. Some URIs contain some information related to the resource, while others protect privacy by using an auto-generated name without any meaning.
Each entity,
• namespace
• type
• property
• class
• object
• (graph?)
has two names: a local name for the user, and a unique identifier for the computer. In any case, the language itself doesn't provide privacy, because privacy depends on who has access to the files. But the language provides the necessary features, which software can use to protect privacy. The user can control privacy and "tell" the software what exactly should be private/public, directly through the language.
It begins with namespaces. When defining a namespace, it's allowed to choose two things:
• Whether the namespace has a local name, and specify the name
• Whether the URI is public, private or entered manually
A suggested syntax:
Allow the namespace name to be omitted
If there's no property to choose, omit the colon
If there are properties, specify on indented lines
The </rich_text><rich_text style="italic">uri</rich_text><rich_text> property can be </rich_text><rich_text style="italic">public</rich_text><rich_text>, </rich_text><rich_text style="italic">private</rich_text><rich_text> or manually entered (string doesn't have to be quoted?)
Suggested new rule: In order to avoid confusion and inconsistency, I suggest URIs are </rich_text><rich_text style="italic">always</rich_text><rich_text> quoted.
Now let's explain what it means.
When a namespace doesn't have a name, other local namespaces cannot access it using the SomeName::MyClass mechanism, which means their only way to get access is by using the namespace's URI or the member entities' URIs. In simple words, the contents of the namespace are not accessible with the local fellow namespace access rules.
When a namespace has a manually written URI, it says nothing about privacy. Member entity URIs may be generated using the namespace URI using a mechanism speficied through the generator software.
When a namespace has a </rich_text><rich_text style="italic">private</rich_text><rich_text> URI, it means the URI is a unique name which doesn't encode any information, and doesn't point to the location of the data. It also implies that all member entities get such URIs too, and these URIs should not contain the namespace URI as a prefix to avoid creating a clue that the data is related.
Note that objects are </rich_text><rich_text weight="heavy">always considered private-URI</rich_text><rich_text> unless stated otherwise through software.
When a namespace has a </rich_text><rich_text style="italic">public</rich_text><rich_text> URI, the URI is generated using software mechanisms, and may encode relevant information, including the location of the data. All non-object entities are considered to have URIs which are generated by prefixing their local names with the namespace URI, possible with some extra characters such as / or #.
As to </rich_text><rich_text weight="heavy">graphs</rich_text><rich_text>: It's hard to tell at this point, whether graphs should always have private-URIs like objects, or use the rules of non-object entities. I will decide later.</rich_text></node><node name="Namespaces and Privacy" prog_lang="custom-colors" readonly="False" tags="" unique_id="144"><rich_text>Well, the issue is already explained in the previous page.
I know, making object always private-URI may not be the best choice, but since software can change that, no problem. The reason I choose that is simple: making object URIs private helps protect privacy. A resolver service can resolve any URI, including a private one. So keepping these URIs private limits information access to the extent of what software allows, and not further, thus allowing to block unwanted data mining.</rich_text></node><node name="Inheritance" prog_lang="custom-colors" readonly="False" tags="" unique_id="145"><rich_text>I already explained it. There are probably some points which still require new decisions, but I'll get there when I write a second version of the tutorial.</rich_text></node><node name="Linking" prog_lang="custom-colors" readonly="False" tags="" unique_id="146"><rich_text>Already explained.</rich_text></node><node name="Research" prog_lang="custom-colors" readonly="False" tags="" unique_id="142"><rich_text>This is a list of related technology worth examining and learning from.
[ ] TaskJuggler Especially the declaration language and the algorithm/report generators
[ ] GTG Read </rich_text><rich_text link="webs https://live.gnome.org/gtg/DataModel">data model</rich_text><rich_text> docs on Gnome Live, and property comparison: </rich_text><rich_text link="file L2hvbWUvYW5hdG9seS/XpNeo15XXmden15jXmdedL9eq15nXm9eV158g157Xoteo15vXldeqINeZ16LXmdec15XXqiDXkNeZ16nXmdeqL1Rhc2slMjBTZW1hbnRpY3Mub2Rz">Comparison</rich_text></node></node><node name="Tutorial Draft" prog_lang="custom-colors" readonly="False" tags="" unique_id="148"><rich_text></rich_text><node name="Intro" prog_lang="custom-colors" readonly="False" tags="" unique_id="149"><rich_text>This tutorial will teach you how to define models and data using the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> computer language.
It contains an a "quick start" section which demonstrates the language basics on action and allows you to start working quickly. The rest of the tutorial covers the aspects of the language in greater depth.</rich_text><node name="Purpose" prog_lang="custom-colors" readonly="False" tags="" unique_id="150"><rich_text>Currently, 25/06/2013, the common way to create computer representation of knowledge is the following process:
1. A programmer writes a program which takes user input, entered through a GUI application, and writes to a file
2. The user uses the GUI application
Common examples are text editors, word processors, presentation editors, spreadsheet editors and database managers. These tools are commonly supplied as a bundle, usually called an Office Suite. Software exists for many other data models: Mind maps, graphs, electrical circuits, blogs, project outlines, to-do lists, 3D models and so on. But in most cases, the model is defined by the creator of the software, and users must use the predefined models.
As long as the model does the job, everyone is satisfied. But this method creates some inequality: The programmer has the power to control the model, and the uset is limited to what is offered. A company can also keep the software source code private, and thus be able to do actions the users may not like, without the users knowing about it. It also means a wide range of fields and professions uses common software tools developed an controled by a single company, and thus the company has significant power to limit these users and the efficiency of the work they do.
The </rich_text><rich_text style="italic">Idan</rich_text><rich_text> language aims to solve these problems. This is how:
• The language is open for everyone to use
• The provided software is free (libre) software
• The language aims to be easy to use, including to non-programmers
• The provided software supplied tools which make it easy to manipulate the data
• The language allows defining both the model and the data itself, making it independent
• The language and the data are human readable and easily edited by hand
• For editing and writing by hand, all you need is a text editor (such as Gedit)</rich_text></node><node name="The Idea" prog_lang="custom-colors" readonly="False" tags="" unique_id="151"><rich_text>Here I'll try to explain the concepts of model and data definition.
In general, what is data? How do we describe concepts and ideas using a computer? The process of obtaining useful human-readable useful results from a computer usually consists of the following abstract process:
1. Define or get </rich_text><rich_text weight="heavy">data</rich_text><rich_text>, i.e. the computer representation of concepts and objects
2. Convert it into </rich_text><rich_text weight="heavy">information,</rich_text><rich_text> i.e. give it meaning
3. Deduce </rich_text><rich_text weight="heavy">knowledge</rich_text><rich_text> from interconnected information, i.e. the useful outcome we wanted to get
Therefore, </rich_text><rich_text weight="heavy">data</rich_text><rich_text> is the computer representation of concepts, objects and entities. The processes of generation of </rich_text><rich_text weight="heavy">information</rich_text><rich_text> and </rich_text><rich_text weight="heavy">knowledge</rich_text><rich_text> may be done by a computer or a human, but the first step - generation of a computer representation - is always done by a computer. A human may enter data through a user interface, but the computer is always responsible for converting it into an effective representation.
Recent developments in data representation technologies led a shift from complex binary representation to text-based ones. The computer used to be the only entity able to work with the data, and thus indirectly the software developers had full control. With text based formats, a user can see and edit the data using any text-based visual interface, such as a text editor.
This makes data human-editable, but only for very simply data. XML, RDF and related technologies are popular users of text-based formats, but creation of complex documents and models with them by hand, through a simple text editor, is practically impossible. Editing or debugging an existing document may be convenient, but creation of documents usually requires special software which makes the work easy and convenient enough for humans to do.
Some languages, such as the </rich_text><rich_text style="italic">Turtle</rich_text><rich_text> format used for RDF files and the declarative language used by </rich_text><rich_text style="italic">TaskJuggler</rich_text><rich_text>, get somewhat close. They allow non-programmers to define data models and data itself. But they aren't exactly there: Turtle syntax is written for RDF, and not as a general purpose modeling language, and TaskJuggler's language is used for definition of tasks and projects, and has specific tools for the job, while some general purpose tools are natually missing.
</rich_text><rich_text style="italic" weight="heavy">Idan</rich_text><rich_text> aims to provide a solution. It is a general-purpose model, and a language based on that model, aimed directly at easy convenient definition of models and objects, to be used by human beings. Programmers and non-programmers alike. It can also link to external models, possible defined with other tools and languages, which allows easily using it in existing projects and less painful migration from other tools.</rich_text></node><node name="Concepts" prog_lang="custom-colors" readonly="False" tags="" unique_id="180"><rich_text>The model used by the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> language is quite simple, and if you have any experience with other computer languages, you'll probably feel at home.
Data in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> follows the following concept: Information can be described through sets (in the mathematical sense), and the elements of these sets. Also, relations (in the mathematical sense) can be used to describe relations between sets, and between objects, both from the same set and from different sets. Thus, in the mathematical level, the concepts are:
• Sets
• Elements
• Relations
Of course, these are mathematical abstract concepts. They have practical equivalents in </rich_text><rich_text style="italic">Idan</rich_text><rich_text>:
• Classes
• Objects
• Properties
Each class represents a set, and has a list of properties. This list defines the relations which objects (elements) of this class (set) can have to other objects. For example:
"Anne is the daughter of John".
Let's break it into </rich_text><rich_text underline="single">simple facts</rich_text><rich_text>:
"Anne and John are people."
"Anne is a woman."
"John is a man."
"John has a daughter, Anne."
</rich_text><rich_text underline="single">Mathematically</rich_text><rich_text>:
P = {the set of all people}
M = {the set of all men}, M⊆P
W = {the set of all women}, W⊆P
R = {<f, d> : fϵM, dϵW, f is the father of d}
Now we can define:
John ϵ M
Anne ϵ W
<John, Anne> ϵ R
</rich_text><rich_text underline="single">In </rich_text><rich_text style="italic" underline="single">Idan</rich_text><rich_text>:
We define a class Person, which describes a person.
Then we define two subclasses, Mane and Woman.
Finally, we define objects.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Computer representation has some unique aspects beyond abstract mathematics, and this results in the existence of another three concepts:
• Namespaces
• Types
• Graphs
Namespaces are a mechanism which allows easily giving names and unique identifiers to your definitions, and refering to them from any file, any time and any location. For example, two people can define a person class in two different namespaces, </rich_text><rich_text style="italic">namex</rich_text><rich_text> and </rich_text><rich_text style="italic">namey</rich_text><rich_text>, and then these two classes may be referred as </rich_text><rich_text style="italic">namex::Person</rich_text><rich_text> and </rich_text><rich_text style="italic">namey::Person</rich_text><rich_text>. These classes would have the same namespace-local name, but are different unrelated classes.
Types are a mechanism which defines how basic abstract units of information are encoded in text. They allow you to specify values of variables effectively and conveniently, and let the computer take care of the rest. For example, the value 29.6 may be a date (June 29th) or a decimal number or simply plain text. The intepretation depends on the type you chose: </rich_text><rich_text style="italic">text</rich_text><rich_text>, </rich_text><rich_text style="italic">real</rich_text><rich_text> or </rich_text><rich_text style="italic">date</rich_text><rich_text>. More types are available, and users can define their own types.
Graphs introduce a short-hand notation for object definition, and allow easy and intuitive definition of object lists and object hierarchies.
Each definition in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> must belong to one of these 6 concepts. Each such definition is called an </rich_text><rich_text style="italic">entity</rich_text><rich_text>, and the concepts are also called </rich_text><rich_text style="italic">entity types</rich_text><rich_text>.</rich_text><codebox char_offset="1353" frame_height="222" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person
class Woman:
base Person
class Man:
base Person
Woman daugher
object Woman Anne
object Man John:
daugher Anne</codebox></node><node name="Example" prog_lang="custom-colors" readonly="False" tags="" unique_id="152"><rich_text foreground="#ffff00000000" weight="heavy">TODO fix the example if my recent decisions change existing features/syntax, and add new features for demonstration</rich_text><rich_text>
$ Namespace
namespace Todo:
visibility shared
date_order dmy
date_separator /
$ Types
type integer [0, 16_FFFFFF] rgb_integer $ Could also define as a string pattern
type enum text {"red", "green", "blue", "black", "white", "yellow", "orange", "purple", "pink", "grey"} color_name
$ Properties
property text name
property text description
property date start_date
property date due_date
property boolean complete
property union {rgb_integer, color_name} color
$ Classes
class Topic:
required name
color
Topic<> subtopic
class Task:
required description
start_date
due_date
required complete
Task<> subtask
$ Objects
$ Graphs
graph Topic topics:
auto name
child subtopic
state color
/books [red]
/movies [blue]
/documentary_movies
/drama_movies
/action_movies
/psychological_movies
/thriller_movies
/comedy_movies
/music [green]
/classic_music
/jazz
/rock
/latin
/movie_soundtrack_music
/work [black]
/home [white]
/family [pink]
/food [yellow]
/fruit
/vegetables
/meat
/nature [orange]
graph Task tasks:
header description
child subtask
state complete
/0 [ ] Save the world
due_date 31/12/2015
/1 [ ] Create a moneyless society
/2 [ ] Gather people to work with me
/3 [X] Start discussions on Diaspora
/4 [ ] Start a local content sharing server
/5 [X] Decide which software to use
@3</rich_text></node></node><node name="Quick Start" prog_lang="custom-colors" readonly="False" tags="" unique_id="153"><rich_text>This page guides you through the process of creation of a simple model and writing data based on it.
For large systems, a complicated model may be necessary, and may require some planning. But </rich_text><rich_text style="italic">Idan</rich_text><rich_text> tries to be suited for incremental on-demand definition and updates for the model. So you can start with what you have in mind, and update it whenever you have new ideas. However, note that incompatible changes may invalidate existing data definitions. If you expect to make such changes, be careful.
Let's start.
We're going to define a model for </rich_text><rich_text weight="heavy">task management</rich_text><rich_text>. It's like a to-do list, but supports task dependencies. You can call it a "to-do tree". We will define the classes we need, and then go define some tasks.
</rich_text><rich_text scale="h2">The Model</rich_text><rich_text>
Create a new empty plain text file. Call it </rich_text><rich_text style="italic">todo.idanc</rich_text><rich_text>. In this file, we'll start be defining the namespace:
</rich_text><rich_text justification="left"></rich_text><rich_text>
• We've given the namespace a name, so that we're able to refer to it from other namespaces.
• We specified the URI is auto-generated and is public, i.e. we intend that other people enjoy our work
• We also specified the way we're going to write dates. In this case, we're probably not going to have any dates, but it doesn't hurt to write these lines in case we'll have dates in the file.
Note that the </rich_text><rich_text weight="heavy">indentation</rich_text><rich_text> here is tabs, but you are free to use spaces, as long as consecutive lines with the same indentation level are indented with the same number of spaces.
Now let's define a Topic class, so that we're able to categorize and filter tasks by topic. Add this code at the bottom of your file (you can insert empty line(s) first, to separate it from the namespace declaration).
</rich_text><rich_text justification="left"></rich_text><rich_text>
Good. Now we have a Topic class with two properties: a required </rich_text><rich_text style="italic">name</rich_text><rich_text> property, and an optional </rich_text><rich_text style="italic">description</rich_text><rich_text> property. In </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, a property is </rich_text><rich_text style="italic">optional</rich_text><rich_text> be default, i.e. it can appear exactly once or not at all. </rich_text><rich_text style="italic">required</rich_text><rich_text> means a property </rich_text><rich_text style="italic">must</rich_text><rich_text> appear, and it must appear </rich_text><rich_text style="italic">exactly</rich_text><rich_text> once.
Now let's define the Task class. Add this code to the file:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The <> in the last two properties denotes unlimited number of appearances: These properties may appear any number of times, including not at all.
The file now should look more or less like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Save the file. We're done with the model.
</rich_text><rich_text scale="h2">The Data</rich_text><rich_text>
</rich_text><rich_text scale="h3">Topics</rich_text><rich_text>
Create a new empty plain text file, and call it </rich_text><rich_text style="italic">topics.idano</rich_text><rich_text>. In this file we're going to define some topics. First the namespace:
</rich_text><rich_text justification="left"></rich_text><rich_text>
We give it a name because we want to use it later, but the URI will be private, so that our topics are not shared with other users or any other people.
Now let's define some topics. We'll ignore the optional description property, and define just the name.
</rich_text><rich_text justification="left"></rich_text><rich_text>
For long lists of topics, this syntax may be cumbersome. Let's use the graph syntax to define more topics:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now the file should look like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The graph syntax is much more convenient in this case, isn't it? The </rich_text><rich_text style="italic">auto name</rich_text><rich_text> line specifies that the </rich_text><rich_text style="italic">name</rich_text><rich_text> property should be generated automatically from the object ID. Since we refer to topics by name, the name is identical to the ID anyway, it saves us typing everything twice.
As you may notice, the topics freedom_of_speech is not exactly what we'd like it to be: We would probably prefer to call it a more human readable name, like Freedom of Speech. This is not a problem at all, since software can easily convert the name to what we want, and even be prepared to do that specifically with the </rich_text><rich_text style="italic">auto</rich_text><rich_text> parameter of graphs.
Save the file. We're done with topics.
</rich_text><rich_text scale="h3">Tasks</rich_text><rich_text>
Create a new empty plain text file, and call it </rich_text><rich_text style="italic">tasks.idano</rich_text><rich_text>. In this file, define an anonymous namespace:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The namespace doesn't have a local name, and therefore cannot be referred locally, unless the URI is used. But URIs are private, so nothing can refer to this file from the outside (unless you command your software to expose private URIs for local usage, which is fine).
The </rich_text><rich_text style="italic">using</rich_text><rich_text> parameter indicates we import names from another namespace. By </rich_text><rich_text style="italic">using</rich_text><rich_text> the Topics namespace, we can specify topics by name directly, without a namespace prefix. For example, we'll use </rich_text><rich_text style="italic">love</rich_text><rich_text> instead of the longer </rich_text><rich_text style="italic">Topics::love</rich_text><rich_text>.
Now let's define some tasks:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is quite cumbersome for large task dependency hierarchies. Let's use a graph again:
</rich_text><rich_text justification="left"></rich_text><rich_text>
As you can see, graphs allow using numeric IDs for objects. We also have other new features here: The optional [ ] box may contain a value for the property specified by the </rich_text><rich_text style="italic">state</rich_text><rich_text> parameter. The </rich_text><rich_text style="italic">child</rich_text><rich_text> parameter specifies the property which defines the hierarchy. If our tasks had a </rich_text><rich_text style="italic">supertask</rich_text><rich_text> property, we'd specify it using the </rich_text><rich_text style="italic">parent</rich_text><rich_text> parameter instead of </rich_text><rich_text style="italic">child</rich_text><rich_text>. Also, the </rich_text><rich_text style="italic">header</rich_text><rich_text> parameter specifies the property defined by the part of the line after the [ ] (or after the ID, if the [] is not used). In this case it is the task content, so we define </rich_text><rich_text style="italic">header</rich_text><rich_text> to be </rich_text><rich_text style="italic">content</rich_text><rich_text>.
The @ character, followed by an ID if the existing task, is a reference to that task. If you want a tasl to have a subtask which has already been defined, use @.
</rich_text><rich_text scale="h2">Final Word</rich_text><rich_text>
Save the file, and you're done. You can add tasks to the graph as much as you want, and remove the ones you don't need (or keep them for the record). When a boolean property is used as the </rich_text><rich_text style="italic">state</rich_text><rich_text>, space and X can be used instead of </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text>, so you can fill the box with X when you finish a task. Or you can define another graph, and move complete tasks to the new graph.
This quick start tutorial doesn't mention two important features, inheritance and linking, and some other features, such as type and property definitions. But don't worry, for a quick start and/or plain text editing of the files, you usually don't need them. Anyway you're welcome to read about them on their tutorial pages.
Have fun!</rich_text><codebox char_offset="843" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri public
date_separator /
date_order dmy</codebox><codebox char_offset="1635" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
required text name
text description</codebox><codebox char_offset="1980" frame_height="150" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
required boolean complete
required text content
date creation_date
data start_date
date finish_date
Topic<> topic
Task<> subtask</codebox><codebox char_offset="2180" frame_height="314" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Todo:
uri public
date_separator /
date_order dmy
class Topic:
required text name
text description
class Task:
required boolean complete
required text content
date creation_date
date start_date
date finish_date
Topic<> topic
Task<> subtask</codebox><codebox char_offset="2376" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Topics:
uri private
date_separator /
date_order dmy</codebox><codebox char_offset="2637" frame_height="150" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic freedom:
name freedom
object Topic peace:
name peace
object Topic love:
name love</codebox><codebox char_offset="2748" frame_height="260" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
auto name
/free_software
/licenses
/freedom_of_speech
/sharing
/music
/movies
/food
/writing
/horses
/laptop
/work</codebox><codebox char_offset="2788" frame_height="510" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace Topics:
uri private
date_separator /
date_order dmy
object Topic freedom:
name freedom
object Topic peace:
name peace
object Topic love:
name love
graph Topic topics:
auto name
/free_software
/licenses
/freedom_of_speech
/sharing
/music
/movies
/food
/writing
/horses
/laptop
/work</codebox><codebox char_offset="3575" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace:
uri private
date_separator /
date_order dmy
using Topics</codebox><codebox char_offset="4113" frame_height="260" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Task a:
complete false
content Do something
object Task b:
complete false
content Do something else
object Task c:
complete false
content Do more things
topic freedom
subtask a, b</codebox><codebox char_offset="4206" frame_height="260" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Task tasks:
header content
child subtask
state complete
/0 [ ] Do something
due_date 31/08/2013
topic action, planning, software
/1 [ ] Do something else
/2 [ ] Say something
/3 [ ] Listen to music
/4 [ ] Do things
@3</codebox></node><node name="Entities and Privacy" prog_lang="custom-colors" readonly="False" tags="" unique_id="154"><rich_text>The six types of </rich_text><rich_text style="italic">entities</rich_text><rich_text> in </rich_text><rich_text style="italic" weight="heavy">Idan</rich_text><rich_text> are:
• types
• namespaces
• properties
• classes
• objects
• graphs
Unlike on the world wide web, where the page content is publicly available to everyone, desktop user data is usually private. Your mail, photos, documents, diaries, notes, etc. Much content is private. Some shared with friends, some not shared at all.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> itself is just a language, and thus cannot directly control access to data, but it provides means to specify privacy levels, so that any software can protect your data according to the privacy settings you choose. Software-specific settings are still useful, for example when choosing friends to share with, but privacy level can be specified directly from </rich_text><rich_text style="italic">Idan</rich_text><rich_text>.
The three privacy levels are:
</rich_text><rich_text weight="heavy">private</rich_text><rich_text> the data is only yours, and available only to your local user or any remote account you confirm as safe
</rich_text><rich_text weight="heavy">shared</rich_text><rich_text> the data is yours and can be shared with friends you choose
</rich_text><rich_text weight="heavy">public</rich_text><rich_text> the data is public, and can be published and shared with everyone
There are two ways to refer to an entity:
1. Using its identifier
2. Using its local name
The identifier is a </rich_text><rich_text style="italic">unique</rich_text><rich_text> ID which can be used by anyone to refer to the entity from anywhere. The local name is a human-readable name given by you, the human creator of the file, and allows refering to other local definitions in a convenient manner. The code is much more readable when using local names.
Privacy levels are specified per </rich_text><rich_text style="italic">namespace</rich_text><rich_text>. A namespace declaration may appear at the beginning of each file (as we'll see in the Namespaces section), and that declaration allows specifying the privacy level for the whole file, and it must match all other uses of the same namespace in other files.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> assumes two methods for generation of identifiers. One method encodes the location of the data, and possibly more details, while the other encodes a minimal amount of information and can be used for any non-public entity. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> doesn't enforce any specific method, but may make assumptions when providing defaults for certain features.
Providing an identifier for each entity is unnecessary. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> realizes you're not a computer, and cannot generate long random identifiers. It's the responsibility of software, to generate these IDs. Idan has 3 mechanisms for specifying identifiers:
1. Not specify them all all
2. Specify a namespace id
3. Specify specific id for an entity
When not specifying IDs at all, the software generates them. Usually they would be random for non-public data, and for public data a public ID would be generated for the namespace, maybe according to some rules which the user can define or edit, and all other entity IDs would be generated by appending the entity's local name to the namespace ID.
When specifying a namespace ID, it works the same way, but the namespace ID is the specified one, instead of auto-generated.
When specifying entity IDs, all entities not given an ID are given an ID as explained above, while entities given an ID get this ID, and ignore all the other rules. Usually you don't need to give IDs manually, but </rich_text><rich_text style="italic">Idan</rich_text><rich_text> allows you to specify them in case you do.
The ID of any entity can be given by defining its </rich_text><rich_text weight="heavy">uid</rich_text><rich_text> parameter. If not defined, the rules explained above are used by software to generate an ID.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> also allows omission of the local name, when defining entities in-place, i.e. where they are used. It also allows to omit the local name of a namespace. This means you cannot refer to that namespace from any other namespace. Software may use it as a sign for an extremely private resource (or warn you before it makes this assumption, to make sure you meant to omit the name, and not just forgot to specify it).
In most cases, the model definition can be public, and you are strongly encouraged to share your models. Unless your model exposes private information, you can freely define it as public, and not worry at all. Data, on the other hand, is usually private. You can make all your data private and shared, and later change to public, if you decide to publish some data.</rich_text></node><node name="Files" prog_lang="custom-colors" readonly="False" tags="" unique_id="155"><rich_text scale="h3">Extensions</rich_text><rich_text>
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> files are plain text files. They don't have to have any extension at all. But </rich_text><rich_text style="italic">Idan</rich_text><rich_text> defines several recommended extensions to use when creating </rich_text><rich_text style="italic">Idan</rich_text><rich_text> files. The extensions are:
.idan
.idant
.idanp
.idanc
.idano
.idang
The .idan extension is a general-purpose extension for Idan files. You can use it for all Idan files and ignore the other extensions, if you wish.
The other 5 extensions correspond to entity types: type, property, class, object, graph. Such an extension implies the entity type of the entities defined in the file. For example, in an .idano file we will expect to find object definitions. It doesn't mean we won't find other things, such as properties and types, but in an .idano we expect most definitions to be objects.
Another two extensions are:
.idanm
.idand
These mean "model" (types, properties and classes) and "data" (objects and graphs).
Note that there is no limitation and no validation: You can write anything in any </rich_text><rich_text style="italic">Idan</rich_text><rich_text> file, regardless of the extension you use. Extensions just help you have a quick overview of files, without opening them. It's much like being able to #include a header file in C and C++, regardless of whether it has an .h extension, or .hpp or hxx or no extension at all, or any other random extension. The extensions in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> are there for convenience.
Also note than some software tools may give further importance for extensions, and make deductions and assumptions based on them, or limit the things you can have in a file, based on extension. This is fine - just make sure you're aware of the specific tool's guidelines and rules, and remember than in general, </rich_text><rich_text style="italic">Idan</rich_text><rich_text> doesn't define any such limitations.
Benefits from usage of the extensions may be:
• Make it easy for the file browser to tell you what kind of file it is
• Make it easy for a text editor to auto-detect the language and apply syntax highlighting and other features
• Make it easy for the computer to decided which programs can open Idan files for editing, and which is the best default
</rich_text><rich_text scale="h3">Location</rich_text><rich_text>
In the previous section, we leart about local names. If I could always refer to an entity using its local name, I wouldn't need IDs at all. But IDs do exist, because the usage of local names is, as you'd expect from their name, local.
There are three ways to use local names:
1. Refer to members from the same namespace
2. Refer to members of local namespaces
3. Refer to members of imported namespaces, or used remote namespaces
Local namespaces don't require any extra steps to import. They can be used directly, as we'll see in the next sections, but only as long as they're known to the system, to be local namespaces. So how does the system know?
The two common options for software are:
1. Have a specific folder in which local namespaces and entitied are looked up, or
2. Insert all entities and data into a database, and find local entities through database query
Either way, the system has a specific storage mechanism to which you deposit your local files, and all queries and links are done through this local mechanism. It's also possible to translate </rich_text><rich_text style="italic">Idan</rich_text><rich_text> definitions into other definition systems, such as RDF, and then insert the data into a semantic desktop datastore, such as Tracker. Everything depends on the software you choose.
</rich_text><rich_text scale="h3">Model and Data</rich_text><rich_text>
Generally speaking, the definitions your write in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> can be divided into two categories: </rich_text><rich_text style="italic">model</rich_text><rich_text> and </rich_text><rich_text style="italic">data</rich_text><rich_text>. The model is the set of rules, which determine </rich_text><rich_text style="italic">how</rich_text><rich_text> to write the data, and gives </rich_text><rich_text style="italic">meaning</rich_text><rich_text> and </rich_text><rich_text style="italic">structure</rich_text><rich_text> to the data. The data is the actual information you define, and you define data according to your model.
The usual division into model and data is:
</rich_text><rich_text weight="heavy">Model</rich_text><rich_text>:
• types
• properties
• classes
</rich_text><rich_text weight="heavy">Data</rich_text><rich_text>:
• objects
• graphs
Software may provide separate folders, or separate storage mechanisms to model and data files. Or it may let you put everything in one place, and handle the rest by itself. It especially makes sense for software which encrypts private data, to handle data (usually private) and model (usually public) files through separate mechanisms, or at least have somewhat different treatment.</rich_text></node><node name="Definition Concept" prog_lang="custom-colors" readonly="False" tags="" unique_id="182"><rich_text>An </rich_text><rich_text style="italic">Idan</rich_text><rich_text> file is composed of a series of </rich_text><rich_text style="italic">entity definitions</rich_text><rich_text>. Each definition may define one or more entities (some definitions cannot define more than one). Most definitions share a common structure. This structure may be called the "entity definition syntax".
The line starts with the </rich_text><rich_text style="italic">entity type</rich_text><rich_text>, then the name, possibly with some optional settings. If no parameters are needed, and definition ends here.
[type] [name]
If parameters are necessary, the name is followed by a column, and the next indented lines are parameters. Each parameter has a name and a value, and possibly some other syntactic additions.
[type] [name]:
[param] [value]
[param] [value]
[param] [value]
In the next sections we will see how this structure is used for nearly all definitions.
Before we start talking about the actual entities and their definitions, in the next sections, I'd like to explain how spaces and tabs work.
</rich_text><rich_text underline="single">Indentation</rich_text><rich_text>: Spaces and tabs can be used for indentation. It's even possible to use a combination of spaces and tabs. The only rule is that the same indentation is used for consecutive lines on the same indentation level. For example, all the [param] [value] lines in the example above must have the same indentation, i.e. an identical sequence of spaces and tabs.
Common indentations are:
• tab
• 4 spaces
• 8 spaces
</rich_text><rich_text underline="single">Extra space</rich_text><rich_text>: Except for some special cases, such as quoted strings, additional space or tabs at the end of the line doesn't matter. Also, empty lines and lines containing only spaces and tabs are ignored (including lines in multiline strings).
Note that whenever you copy </rich_text><rich_text style="italic">Idan</rich_text><rich_text> code, make sure the paste target takes the indentation into account and does not remove it, otherwise the resulting pasted code will be invalid. The best way to make sure your indentation is preserved, is to use </rich_text><rich_text style="italic">code boxes</rich_text><rich_text> when they are provided (e.g. in forum software).
All entity local names must begin with a letter, and contain only digits, English letters and underscores (_). The exception is objects IDs defined in graphs, which we'll see later.</rich_text></node><node name="Namespaces" prog_lang="custom-colors" readonly="False" tags="" unique_id="156"><rich_text>Namespaces are like sets, and entities are their members. If all entities belong to a single namespace, there's a high chance for collision. So we use namespaces as unique boxes, into which we throw our entity definitions. Namespaces also provide privacy settings, and a convenient way to refer to remote ad external entities.
</rich_text><rich_text scale="h2">Syntax</rich_text><rich_text>
Each namespace has three basic parameters:
• visibility
• identifier
• prefix
A namespace definition may also specify these properties:
• date_separator
• date_order
In each file, and namespace definition may appear only once, or not at all. If the definition appears, it must be the first definition in the file. If a namespace is defined in different files, then the visibility, identifier and prefix parameters must be identical in all files.
If there is no namespace definition in an </rich_text><rich_text style="italic">Idan</rich_text><rich_text> file, the default values are used. If the namespace is defined but some parameters are not defined, their default values are used. Although the namespace definition is optional, it is highly recommended to have it in all files, even if the default values are desired. This helps reduce the chance of surprising results due to implicit values, not specified in the file.
A minimal namespace definition looks like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Then the other definitions can follow, for example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
A full definition looks like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
All namespace parameters may be defined inside double quotes. For example we can put them all in quotes: </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO update the </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">uid</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> details after I decide if </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">uid</rich_text><rich_text foreground="#ffff00000000" weight="heavy">s will be specified inside "" or inside <> or something else.</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION the above example is legal</rich_text><rich_text>, but in the future </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO add a string type for </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">uid</rich_text><rich_text foreground="#ffff00000000" weight="heavy">s</rich_text><rich_text>
</rich_text><rich_text scale="h2">Semantics</rich_text><rich_text>
Let's examine the contents of the definition and what they mean.
</rich_text><rich_text scale="h3">Prefix</rich_text><rich_text>
The prefix is the name set after the </rich_text><rich_text style="italic">namespace</rich_text><rich_text> keyword. Like all other entity names, it must begin with a letter and contain only letters, digits and underscores. Later, when we see how the prefix is used, you'll understand why it's called a </rich_text><rich_text style="italic">prefix</rich_text><rich_text>. If you know XML, RDF or C++, you can guess. It's exactly what you expect.
A prefix can be omitted, in which case the namespace and its contents cannot be refered using local names at all, from outside the namespace. Most of the time you do want to give the namespace a prefix, even if it's private.
A minimal namespace definition with a prefix looks like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
If parameter(s) follow, it may look like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is also possible to omit the prefix when parameters are specified, like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h3">Visibility</rich_text><rich_text>
The visibility parameter decides who has access to the data. Who can see it. Who can have it. In other words, it is the </rich_text><rich_text style="italic">privacy level</rich_text><rich_text> of the namespace and all its contents. There are 3 privacy levels:
• private
• shared
• public
The exact interpretation of these levels may depend on the software you use, but </rich_text><rich_text style="italic">Idan</rich_text><rich_text> defines the meaning of each level, and all software should follow the definition. If all software conforms to the definition, the behavior is consistent and expected, and passing the files to different programs will always result in expected results, and will minimize the risk of a private entity being shared by mistake.
</rich_text><rich_text underline="single" weight="heavy">Private</rich_text><rich_text> visibility means the content is only yours, and the definitions belong only to your user on the local system, and to any additional personal services to whom you gave permission for the file.
For example, you may have a private personal to-do list, and you want to synchronize the list with your cellphone, so you can see it and edit it from the cellphone when you're not at home. Then you define the namespace visibility to </rich_text><rich_text weight="heavy">private</rich_text><rich_text> and add your cellphone as a trusted user of the private list.
Usually you want the </rich_text><rich_text style="italic">data</rich_text><rich_text> part of your definitions to be </rich_text><rich_text weight="heavy">private</rich_text><rich_text>. Changing to shared or public later is easy, but making a public definition private won't save you if it has already "leaked" to the public. It is recommended to start with </rich_text><rich_text weight="heavy">public</rich_text><rich_text> and change later to a more permissive setting if necessary.
</rich_text><rich_text underline="single" weight="heavy">Shared</rich_text><rich_text> visibility means your definition can be shared, but only with friends you choose. Whether these friends can share it too, depends on the software you use and its settings. The definition is treated as private, but is allowed to be shared with any user or remote contact which you authorize and declare as a trusted party.
Shared visibility may be useful if you decide to share a personal creation with friends, or want to have your work peer-reviewed before you make it public.
</rich_text><rich_text underline="single" weight="heavy">Public</rich_text><rich_text> visibility means anyone may see your definition. Use public visibility if you intend to publish your work, or don't mind anyone sees it. But be careful: once the file is publicly available, you can no longer ensure its privacy in case you regret publishing it, so you can't revert your decision. Make sure you really want to publish and content and have everyone see, and only then set the visibility to public.
The </rich_text><rich_text style="italic">model</rich_text><rich_text> part of your definitions can usually be public. It is strongly recommended that you share your models with other users, and on the web, so that everyone can enjoy them and reuse existing common models. In the same manner, you can use existing models made by other users, instead of writing your own. If you can't find what you need, then you're welcome to write a model and share it.
Sharing models also allows for standardization of models: If many people use one shared model for a specific purpose, this model has a high chance to be declared as the standard model for that purpose. Sharing itself provides data model compatibility, but a mode becoming standard means that new software can be written for it, and it will be able to handle everyone's definitions without any special modifications.
</rich_text><rich_text scale="h3">Identifier</rich_text><rich_text>
The identifier is a universally unique name, which can be used everywhere when refering to our namespace. It is specified through the </rich_text><rich_text style="italic">uid</rich_text><rich_text> parameter. All entity types can have the an identifier specified this way.
The identifier doesn't have to match any specific rules, but it is recommended to make it a URI. For public namespaces, you can use a URL which points to your website, or some other useful locator. For public or shared namespaces, I suggest to use a UUID.
Of course, you don't need to enter identifiers manually into the code. If you export the definitions into a database using software, let the software create the identifiers. It is recommended that the software auto-generates UUIDs for non-public entities, and generates URLs or other public locators/names for public entities. Either public IDs are generated by some rules you specify, or you can enter them directly in the code.
Most of the time, you'll want to give a </rich_text><rich_text style="italic">uid</rich_text><rich_text> only to the namespace, which is easy enough to do by hand. But since a human cannot generate UUIDs, you can let the computer generate them, and specify the </rich_text><rich_text style="italic">uid</rich_text><rich_text> only if it's for a public namespace. If your software offers to generate public IDs too, then you don't need to specify any </rich_text><rich_text style="italic">uid</rich_text><rich_text>s.
If IDs are not specified for namespace members, their IDs will be auto-generated, possible using the namespace ID. Usually this is what you want, but it's possible to give a </rich_text><rich_text style="italic">uid</rich_text><rich_text> to any entity, regardless of the namespace </rich_text><rich_text style="italic">uid</rich_text><rich_text> or </rich_text><rich_text style="italic">visibility</rich_text><rich_text> settings.
</rich_text><rich_text scale="h3">Date Order and Separator</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider replacing dmy and allowing to specify the date format using a specific date, e.g. you have to specify the date 1948-01-30 in any </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">Idan</rich_text><rich_text foreground="#ffff00000000" weight="heavy">-legal way you wish, and the date order and separator(s) are deduced from that.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently only 30/1/1948 works, using the </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">date_format</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> parameter, and later I may bring back the order and separator</rich_text><rich_text>
Later we'll see exactly how to specify dates in </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> is very flexible in this area: It's doesn't enforce a date specification format. The date "July second 2013" can be written as 2013-07-02 or 2/7/13 or 7/2/2013 or even 2-2013-7 if you wish.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> provides this flexibility by allowing the user to specify two parameters in the namespace declaration. Unlike the other parameters, these two parameters can differ from one namespace defintion to another, i.e. you can define the same namespace in different files, and use different date parameters. They are not really namespaces characteristics, but are just a way to state per-file the date format you prefer.
The two parameters are:
• date_order
• date_separator
The date_order parameter may be any permutation of d, m, and y, i.e. the letters (d,m,y) specified in any order the user chooses. d stands for </rich_text><rich_text weight="heavy">day</rich_text><rich_text>, m stands for </rich_text><rich_text weight="heavy">month</rich_text><rich_text> and y stands for </rich_text><rich_text weight="heavy">year</rich_text><rich_text>. The date_order chooses the order in which these components appear in the date.
For example, common formats are ymd (2013-03-20), mdy (03/20/2013) and dmy (20/03/2013).
The date_separator specifies the separator used in dates. The possible separators are slash (/), dot (.) and hyphen (-). For example, 20-03-2013 uses hyphens, 20/03/2013 uses slashes and 20.03.2013 uses dots.
Any combination of separator and order is possible and valid. You are encouraged to use your local date format, and let software do any conversions when sending files to people in other countries. Software may also set these parameters for you automatically, using the parameters of your locale.
</rich_text><rich_text scale="h2">Default Values</rich_text><rich_text>
If no name is specified, then the namespace is "unnamed", as explained above.
If no uid is given, then a uid is auto-generated as explained above.
The default visibility level is </rich_text><rich_text style="italic">private</rich_text><rich_text>.
The default date order is </rich_text><rich_text weight="heavy">ymd</rich_text><rich_text> and the default date separator is hyphen, </rich_text><rich_text weight="heavy">-</rich_text><rich_text>. These settings match the ISO international date format, but naturally you'll prefer to use your local favorite format.</rich_text><codebox char_offset="1254" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace</codebox><codebox char_offset="1310" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace
class Person
text name
text address</codebox><codebox char_offset="1349" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace:
uid http://my-name-space.org/
visibility public
date_order dmy
date_separator /</codebox><codebox char_offset="1569" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace:
uid "http://my-name-space.org/"
visibility "public"
date_order "dmy"
date_separator "/"</codebox><codebox char_offset="2359" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace</codebox><codebox char_offset="2410" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace:
visibility private
date_order dmy
date_separator /</codebox><codebox char_offset="2495" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace:
visibility private
date_order dmy
date_separator /</codebox></node><node name="Types" prog_lang="custom-colors" readonly="False" tags="" unique_id="157"><rich_text>Before we can define any data using the computer, we need to have a common language with the computer. When we write 123, how does the computer know whether we refer to the number "one hundren twenty three" or to the text "one two three"?
</rich_text><rich_text style="italic">Types</rich_text><rich_text> are the basis for the common language which both humans and computers speak. Before there can be any structure, we must be able to communicate the small stand-alone pieces of data. Types provide the rules for communication of these pieces.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> provides sevral </rich_text><rich_text style="italic">primitive</rich_text><rich_text> types, which are part of the language and aren't defined anywhere in the language itself. But these types serve as a basis for the definition of all other types. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> tries to keep the number of primitive types minimal, and define most of the common types through the language itself, rather than providing "primitive" existence of types.
The primitive types in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> are:
• text
• real
• integer
• boolean
• date
• time
There exist mechanisms which allow extending and restricting these types, thus defining new types. The mechanisms are:
• union
• enumeration
• pattern
• range
The subsection Primitive Types explains how to use the primitive types, and the next subsection Type Definition explains how to define new types based on existing types.
So what are types exactly? </rich_text><rich_text style="italic">Idan</rich_text><rich_text> types are types of </rich_text><rich_text style="italic">data</rich_text><rich_text>. All the definitions you write in plain text is... plain text! But you don't always </rich_text><rich_text style="italic">mean</rich_text><rich_text> plain text. The text "2489523" may be an ID, but it can also be a number. The text "2.7" may be a decimal number, but it may also be a date. The text "13/50" may be a date, but also may be a mathematical formula. The text "John" may be a name, but may also be a name of an object you defined.
The </rich_text><rich_text style="italic">type</rich_text><rich_text> of a data element doesn't say anything about the </rich_text><rich_text style="italic">meaning</rich_text><rich_text> of the data, but it determines the </rich_text><rich_text style="italic">interpretation</rich_text><rich_text> of the data. An integer may represent a size, a length and many many other things, but all meaning have one thing in common: the representation chosen for them is an </rich_text><rich_text style="italic">integer</rich_text><rich_text>.
A type is therefore a </rich_text><rich_text style="italic">mapping</rich_text><rich_text> between sequences of characters (also known as </rich_text><rich_text style="italic">strings</rich_text><rich_text>), and other sets, which may be strings too, or numbers, or any abstract set you want. For example, you can define a type </rich_text><rich_text style="italic">complex</rich_text><rich_text> to be a mapping between strings and complex numbers.
It is important to note the difference between interpretation and meaning. For example, you could theoretically have a type </rich_text><rich_text style="italic">person</rich_text><rich_text> which maps strings to people. This type would define a mechanism for specifying a person using its unique official ID. But this type does not conform to the rule: It does convey meaning. A type should be related to </rich_text><rich_text style="italic">the</rich_text><rich_text> </rich_text><rich_text style="italic">way the data is specified</rich_text><rich_text>, and not to </rich_text><rich_text style="italic">what it means</rich_text><rich_text>. Instead of the person type, you should define a </rich_text><rich_text style="italic">person_id</rich_text><rich_text> type, which maps strings to valid ID numbers (e.g. all sequences of 9 digits). Then, you can define a </rich_text><rich_text style="italic">property</rich_text><rich_text> called </rich_text><rich_text style="italic">leader</rich_text><rich_text> or </rich_text><rich_text style="italic">parent</rich_text><rich_text> or </rich_text><rich_text style="italic">brother</rich_text><rich_text> or </rich_text><rich_text style="italic">member</rich_text><rich_text>, etc., and this property can be of the type </rich_text><rich_text style="italic">person</rich_text><rich_text>.
Therefore, types determine </rich_text><rich_text style="italic">interpretation</rich_text><rich_text> while properties determine </rich_text><rich_text style="italic">meaning</rich_text><rich_text>.
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO add two more types: a type which can take only valid entity names, and a type for valid UIDs</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO see if I can use the following text too, which explains the same things explained above and under Type Definition:</rich_text><rich_text>
</rich_text><rich_text foreground="#aee0cd443b15">Types can be defined explicitly, using the </rich_text><rich_text foreground="#aee0cd443b15" style="italic">type</rich_text><rich_text foreground="#aee0cd443b15"> keyword, or in-place where properties are defined. This allows for the following three options to define a class property, as we've already seen:
• define type explicitly, define property explicitly, use in class
• define type explicitly, define property in-place
• define type and property in-place
As a result of this variety, it is sometimes confusing to decide which option to take. For example, you can define a type </rich_text><rich_text foreground="#aee0cd443b15" style="italic">size</rich_text><rich_text foreground="#aee0cd443b15"> as a non-negative </rich_text><rich_text foreground="#aee0cd443b15" style="italic">integer</rich_text><rich_text foreground="#aee0cd443b15"> and then define properties of type </rich_text><rich_text foreground="#aee0cd443b15" style="italic">size</rich_text><rich_text foreground="#aee0cd443b15">. Or, instead, you can define a property called </rich_text><rich_text foreground="#aee0cd443b15" style="italic">size</rich_text><rich_text foreground="#aee0cd443b15">, whose type is a non-negative integer. When adding </rich_text><rich_text foreground="#aee0cd443b15" style="italic">inheritance</rich_text><rich_text foreground="#aee0cd443b15"> or properties to the picture, it adds even more variety of options and confusion.
The key to effective work with data models and reusable types, properties and classes, is to understand the concepts behind the entities defined in Idan. In some cases it's ambiguous and any choice can be as good as any other, but in most cases it's possible to get one clear decision based on simple rules. If you stick to the rules, you'll achieve better design in less sleepless nights.
Types and properties, like we just saw, can basically do the same role in some cases. The following rule helps decide which entity should be a type, and which should be a property:
A </rich_text><rich_text foreground="#aee0cd443b15" weight="heavy">type</rich_text><rich_text foreground="#aee0cd443b15"> is a mapping between a textual representation of an entity, to the entity space itself. Types exist because we need to be able to express abstract concepts in a written manner. Types don't always represent the most efficient computer representation of an entity, but they do try to provide a readable convenient representation. Types don't deal with the meaning of the data - only with the mapping and representation.
A </rich_text><rich_text foreground="#aee0cd443b15" weight="heavy">property</rich_text><rich_text foreground="#aee0cd443b15"> represents a relation between entities. Both entities are represented through a computer representation, i.e. each has a type, but the property itself is the </rich_text><rich_text foreground="#aee0cd443b15" style="italic">meaning</rich_text><rich_text foreground="#aee0cd443b15"> of the relation. It doesn't deal with technical mapping or representation issues, and only focuses on the semantics of the relation.
Let's see an example. The </rich_text><rich_text foreground="#aee0cd443b15" style="italic">size</rich_text><rich_text foreground="#aee0cd443b15"> entity we mentioned conveys a </rich_text><rich_text foreground="#aee0cd443b15" style="italic">meaning</rich_text><rich_text foreground="#aee0cd443b15">: it's not just a non-negative integer, but it's also a size. Natural numbers can also represent mass, length, speed, ID, dimension and so on. Many many things which aren't called </rich_text><rich_text foreground="#aee0cd443b15" style="italic">size</rich_text><rich_text foreground="#aee0cd443b15">. So a size is a specific meaning we can give to a natural number. But a natural number, as a type, has no meaning. It's just a computer representation of an integer, restricted to non-negative values. It's onlt technical. So in this case, we define a type </rich_text><rich_text foreground="#aee0cd443b15" style="italic">natural</rich_text><rich_text foreground="#aee0cd443b15"> (or </rich_text><rich_text foreground="#aee0cd443b15" style="italic">unsigned_integer</rich_text><rich_text foreground="#aee0cd443b15">, whichever we prefer), and then define a property </rich_text><rich_text foreground="#aee0cd443b15" style="italic">size</rich_text><rich_text foreground="#aee0cd443b15"> to be of type </rich_text><rich_text foreground="#aee0cd443b15" style="italic">natural</rich_text><rich_text foreground="#aee0cd443b15">.
One of the technical key differences between types and properties, is that properties may have sub-properties ad super-properties, and thus form a property hierarchy. This feature may help choose between type and property in ambiguous cases. We'll examine property inheritance later.</rich_text><node name="Primitive Types" prog_lang="custom-colors" readonly="False" tags="" unique_id="158"><rich_text>In this section the primitive types are introduced:
• text
• real
• integer
• boolean
• date
• time
I will use object definitions for demonstration of features of the types. We haven't covered object definition yet, but don't worry. You don't have to know how to define objects, to understand the examples. Also, the examples are simple, and the object definitions are very clear.</rich_text><node name="Strings" prog_lang="custom-colors" readonly="False" tags="" unique_id="160"><rich_text>The </rich_text><rich_text style="italic">text</rich_text><rich_text> type simply matches strings to strings. The match is not exactly one-to-one, as we'll see immediately. But the </rich_text><rich_text style="italic">text</rich_text><rich_text> type is the basic free-text type. For example, the content of a note can be of </rich_text><rich_text style="italic">text</rich_text><rich_text> type.
A </rich_text><rich_text style="italic">string</rich_text><rich_text> in computing is a sequence of characters. It is a computer representation of </rich_text><rich_text style="italic">text</rich_text><rich_text>.
Typing string directly, just like that, is not always what you want, but in many cases it is. We'll see all the special cases which require surrounding strings with double quotes, but when no special case applies, you can just type in the text without quotes. Example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When strings are specified like that, the actual string starts from the first non-space-non-tab character and ends with the last character before the line ends, dropping any spaces and tabs from the line's end. It means the last example contains the string "John". But sometimes you want your string to be " some string here ". Or you want your string to be multiline.
These cases require different treatment. The direct simple string notation shown above is meant for use with short simple strings, and is not recommended for longer ones. It's great for names or addresses, but probably not so good for sentences or paragraphs.
It's also possible your string happens to contain a language keyword. For example, </rich_text><rich_text style="italic">some text here</rich_text><rich_text> contains the word </rich_text><rich_text style="italic">text</rich_text><rich_text> which is a keyword and cannot be used as a local name. In the last example, it may be possible to detect and ignore it, and treat is as a string, but with some keywords and usage patterns, it does matter whether the keyword is meant to be the actual language keyword or it belongs to the string. So </rich_text><rich_text style="italic">some text here</rich_text><rich_text> is not allowed. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO Decide if usage of a keyword in a non-quoted string is allowed, if it doesn't cause any ambiguity.</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">Solution</rich_text><rich_text>: Values are specified in object definitions and in graphs:
object MyClass my_obj:
my_prop value
graph MyClass my_graph:
/my_obj value
my_prop value
</rich_text><rich_text foreground="#0000ffff0000" weight="heavy">Decision</rich_text><rich_text>: When specifying values, non-keywords (e.g. types) are allowed. For keywords, we'll see later.
The special cases which require quotes are:
• strings which begin and/or end with space
• strings which contain a keyword </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO Decide if legal, see above</rich_text><rich_text>
• multi-line strings
• strings which begin with a double quote
• strings which contain the $ sign (which is used to mark a comment)
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently non-quoted strings are </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">not supported!</rich_text><rich_text>
The solution to all these problems is surrounding the string with double quotes:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This also allows the string to start and end with spaces and tabs, and contain keywords:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to have multi-line strings. It's done by starting a new string on the next line. All the string's lines must be indented, and have the same indentation. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note the indentation of the lines 2-4 of the string: they're indented further than the </rich_text><rich_text style="italic">content</rich_text><rich_text> line, and all have the same indentation.
Unfortunately, qouted strings also have some extra issues, which the simple strings don't have. If you want your string to contain a quote, what do you do? Or what if you want it so </rich_text><rich_text style="italic">start</rich_text><rich_text> with a quote?
The second is simple: You have to use quoted strings. If the quote is inside the string, then a simple string like </rich_text><rich_text style="italic">this string has an " embedded quote</rich_text><rich_text> is fine. But if the string begins with a quote, the language will treat the quote as the beginning of a quoted string, so you'll need the string to be quoted.
For example, this will generate an error:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Once we decided we need a quoted string, how do we embed a quote inside it? Any quote inside a string will be regarded as a closing quote, so this code won't work:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The actual string is "This string contains ", and the rest of the line then generates an error. The answer is: we use an escape sequence. It is a sequence of characters with a special meaning: usually the sequence is made of 2 characters or more, and translates into a single character. This feature is present in many languages, with many possible sequences, but in the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> language there's only a single sequence: \". It's a backslash followed by a double quote.
In a quoted string, all appearances of \" are treated as the " character and allow to embed " in a string. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The resulting string is </rich_text><rich_text style="italic">This string contains " a quote</rich_text><rich_text>. If you want your string to contain a quote, you don't have to make the string quoted. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
But if you want it to </rich_text><rich_text style="italic">begin</rich_text><rich_text> with a quote, you must use a quoted string:
</rich_text><rich_text justification="left"></rich_text><rich_text>
What if you want your string to end with \? In the following example, the string is not closed:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The solution to this problem in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> is to remove the \ from the string, and add it right after the closing quote. Then the string is correctly treated and the \ is included too. This is how we fix the last example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Our problems haven't been solved yet. What if we want to have the sequence \" in the string? And what if we want the string to end with \\ or \\\ or \\\\?
The first problem is solved by always adding an extra backslash. For example, assume we want to have the sequence \" in the string, as is. Then in the plain string we type \\", and the two last characters are escaped to a single ", and the result is \". In the same manner \\\" converts to \\" and so on. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The second problem is solved by appending as many \s as we want. For example, "hello"\\\ is interpreted as the text </rich_text><rich_text style="italic">hello\\\</rich_text><rich_text>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Non-ASCII characters (e.g. non-English letters) are possible too. What if you want to type a string in your language? It could be French or Hebrew or Japanese. In </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, the default encoding is UTF-8. It's up to you, the user, to make sure the plain-text files you create are in UTF-8 encoding. Then, you can directly use any unicode character in the text.
The following example contains a strings which have Hebrew, Japanese and mathematical notations:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is a good habit to always use quoted strings when your text is more than few words. If it's just a name, like "John", omitting the quotes is safe enough. But if it's free text which contains whole sentences, like "This is some text I decided to write", then you may consider surrounding it with quotes, so that if a future change makes the quotes required, they will already be there.</rich_text><codebox char_offset="579" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Person john_smith:
first_name John</codebox><codebox char_offset="2469" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Person john_smith:
first_name "John"</codebox><codebox char_offset="2562" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content " some text went to bar, and danced with a required boolean "</codebox><codebox char_offset="2751" frame_height="100" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "This is a very long note, and also a useless one."
"At least it has a second line!"
"And even a third line!"
"And this is the last line of the string."</codebox><codebox char_offset="3450" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "my string begins with a quote</codebox><codebox char_offset="3618" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "This string contains " a quote"</codebox><codebox char_offset="4209" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "This string contains \" a quote"</codebox><codebox char_offset="4368" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content This string contains \" a quote</codebox><codebox char_offset="4444" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "\"Where is my pen?\" asked Jane."</codebox><codebox char_offset="4546" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "This string contains \" a quote\"</codebox><codebox char_offset="4766" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "This string contains \" a quote"\</codebox><codebox char_offset="5246" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Note note:
content "Here's backslash-and-quote: \\""
"And here's two-backslashes-and-quote: \\\""</codebox><codebox char_offset="5376" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Message love_letter:
content "hello"\\\</codebox><codebox char_offset="5836" frame_height="84" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Page page:
line This line contains Japanese letters: 平和および愛.
line .שלום לכולם! אני מקווה שאתם נהנים
line Here's a mathematical equation: ∫(⅓ + ⅔)∂𝑥 ≡ 𝑥</codebox></node><node name="Boolean Numbers" prog_lang="custom-colors" readonly="False" tags="" unique_id="161"><rich_text>Boolean numbers are very simple: A boolean number has only two possible values. In </rich_text><rich_text style="italic">Idan,</rich_text><rich_text> these values are denoted by the special objects </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text>. Nothing else is accepted.
Note that "true" and "false" are strings, and thus cannot be used as boolean values. </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text> are the only allowed values.
For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider allowing yes/no as boolean values, because "has children? no" is very convenient</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION for now not allow that, but in the future consider defining aliases for true and false, and consider allowing the match of any two-value type, e.g. {yes, no}, to the [X] and [ ] boxes in graphs, e.g. [X] for "yes" and [ ] for "no"</rich_text><codebox char_offset="324" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Person john_smith:
married true
has_children false</codebox></node><node name="Integers" prog_lang="custom-colors" readonly="False" tags="" unique_id="162"><rich_text>Integer values are exactly what you expect in mathematics. They can be specified exactly as you'd expect: a sequence of digits 0-9 and an optional minus sign. For example:
0
-123
4329384213
234
-3
999881
In some cases, it's more convenient to use a specific numeric base than to use the traditional decimal numbers. For example, it's common to use binary numbers (base 2), octal numbers (base 8) and hexadecimal numbers (base 16) in some cases. In some programming languages, prepending 0 or 0x to a number denotes base 8 or 16. In </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, language, any base between 2 and 36 (including both) can be used. Bases are specified by prepending the base number (in decimal) and an underscore to the number. For bases larger than 10:
A or a denotes 10
B or b denotes 11
C or c denotes 12
...
Z or z denotes 35
For example:
2_10010010100100111110
8_73271
10_2958105
16_1a87b1fd981e89
36_28rhc103210ndjxh
23_874AEJ98L87
13_A87BbC98c9bAa7
Negative integers are allowed too, by putting a minus sign after the underscore:
10_-2958105
16_-1a87b1fd981e89
36_-28rhc103210ndjxh
Lowercase and uppercase letters can be mixed, but a number is probably much more readable if the letter case is consistent.
The ability to specify a base is probably not useful most of the time, but it's quite common to specify user permissions on Linux as octal numbers, and use binary numbers in low-level computing and in electronics, and specify RGB colors using hexadecimal numbers. Since the choice of bases for specific usage is arbitrary, Idan supports arbitrary bases to ensure convenience.</rich_text></node><node name="Real Numbers" prog_lang="custom-colors" readonly="False" tags="" unique_id="163"><rich_text>Real numbers also have the expected syntax used in other languages, and again also the ability to use an arbitrary base, which is unique to </rich_text><rich_text style="italic">Idan</rich_text><rich_text>.
All integers are also valid real numbers. So real numbers are an extension to integers (this is a natural consequence of Z being a subset of R). In addition to what integer allow, it's possible with real numbers to specify a fractional part and an exponent. For example:
1 = 1.0 = 1.0%0 = 1%0 = 17_1 = 23_1%0
23.329%72
0.283
32%-239
31_2.3%5
The exponent part is a bit tricky: In decimal numbers (base 10), the exponent part means "multiply by the given power of ten", for example 2%3 = 2 * 10^3 = 2000. But in other bases, the exponent means multiply by a power of the base, which isn't ten anymore. For example, take 2_101%101. What does it mean? The way to avoid getting confused is using the following rule: After the underscore, assume the only base in the world is the base specified before the underscore. So the number we have is 101 in base 2 (which is 5 decimal) multiplied by the base (2 decimal) raised to power 101 (5 decimal). In other words, this number in decimal means 5 * 2^5.
In many programming languages and systems e or E denote the exponent part, while % is used in some languages as the modulo operator. Since Idan is a data modeling language and doesn't have "operations", while it focuses on definition of classes and objects, the characters e and E are used as digits of numbers in base 15 and above, and the % character isn't used anywhere else and is free to be used as an exponent marker.</rich_text></node><node name="Date and Time" prog_lang="custom-colors" readonly="False" tags="" unique_id="164"><rich_text>Date and time can be described in many ways, in computers just like on paper. Since Idan aims to be easy to write by hand, it doesn't enforce a date representation format. Instead, you can choose the format you want.
The time format is always hh:mm:ss and the default date format is y-m-d so these would be legal:
2013-17-6
16:32:00
But you probably don't really use this date format in real life. Idan allows you to set the date format per-file by setting the namespace parameters </rich_text><rich_text style="italic">date_order</rich_text><rich_text> and </rich_text><rich_text style="italic">date_separator</rich_text><rich_text>.
date_order is a 3-letter string containing y, m and d. Each exactly once. This property chooses the order in which you write day, month and year in all your dates within a file. The default value is </rich_text><rich_text style="italic">ymd</rich_text><rich_text>. You'll probably want to use </rich_text><rich_text style="italic">mdy</rich_text><rich_text> or </rich_text><rich_text style="italic">dmy</rich_text><rich_text>, but any order is possible.
date_separator chooses the separator character which separates the year, month and day parts of the date. The default value is - (hyphen). The possible values are -, / and . (hyphen, slash, dot).
Example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's possible to omit any part of the date by leaving the field blank. But the separator must remain. The following date values are legal, when used with the namespace declaration above:
3//
03//
/6/
/06/
//13
//2013
//02
//2002
17/6/
6/2013
17/6/13
17/06/13
17/06/2013
17/6/2013
These are </rich_text><rich_text weight="heavy">illegal</rich_text><rich_text>:
17//13
3//13
03//13
3//2013
03//2013
Some dates may make less sense than others. But Idan doesn't add limitations, so that the same built-in type </rich_text><rich_text style="italic">date</rich_text><rich_text> can be used for any partial date value without defining new types and objects. The only limitation is that specifying only day and year without month is </rich_text><rich_text weight="heavy">illegal</rich_text><rich_text>. In some cases it's probably desired to limit the date values, but currently Idan doesn't provide a built-in solution. Ranges can help, but the way to do it is probably defined a restricted string type containing three numbers and two separators between them. We'll see later how it's done.
Time parts can be omitted too, but only from the least-significant part. Seconds may be omitted from the hh:mm:ss value. If seconds are omitted, then minutes can be omitted too. Hourse cannot be omitted. It's possible to drop leading zeros, e.g. 1:2:3 is a legal value. But it's probably much more readable to include them: 01:02:03, at least in some cases.
Examples:
1:2:3
01:2:3
1:02:3
01:2:03
01:02:03
16:43:17
16:43
16
00:00:00
0:0:0
0:0
0
Note that the colon is omitted when seconds or minutes are omitted, unlike the date separator, which must remain in all cases.</rich_text><codebox char_offset="996" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace SomeName:
uri auto
date_order dmy
date_separator /</codebox></node></node><node name="Type Definition" prog_lang="custom-colors" readonly="False" tags="" unique_id="159"><rich_text>We've seen how values for primitive types are specified. Are the primitive types enough?
Assume you want a number to represent the </rich_text><rich_text style="italic">length</rich_text><rich_text> of something. Then </rich_text><rich_text style="italic">integer</rich_text><rich_text> is too wide, because it allows negative values. If you specify a negative value, it will be accepted by software and used as if it's perfectly valid. The solution is to define a new type, which allows only non-negative integers.
Assume you want a word to represent task state: todo, wip (work in progress) or done. You can use the </rich_text><rich_text style="italic">text</rich_text><rich_text> type, but then any string will be accepted. The solution is to define a type which accepts only three strings as valid values: </rich_text><rich_text style="italic">todo</rich_text><rich_text>, </rich_text><rich_text style="italic">wip</rich_text><rich_text> and </rich_text><rich_text style="italic">done</rich_text><rich_text>.
There are two kinds of type definition mechanisms: </rich_text><rich_text style="italic">restriction</rich_text><rich_text> and </rich_text><rich_text style="italic">extension</rich_text><rich_text>. The 4 definition mechanisms are:
</rich_text><rich_text weight="heavy">Extension</rich_text><rich_text>:
• union
</rich_text><rich_text weight="heavy">Restriction</rich_text><rich_text>:
• enumeration
• pattern
• range
</rich_text><rich_text style="italic">Extension</rich_text><rich_text> means conbining existing types into a new type, while </rich_text><rich_text style="italic">restriction</rich_text><rich_text> means taking an existing type and defining a type whose valid values are a subset of values of the existing type, i.e. restricting a type to a specific subset of its allowed values.
There are two ways to define a type:
1. Define a type explicitly, much like a namespace definition
2. Define a type directly where it is used, i.e. in a property definition
Since we haven't covered properties yet, I won't go into details of the in-place type definition, but I will give examples.
Explicit definition is done using the </rich_text><rich_text style="italic">type</rich_text><rich_text> keyword:
</rich_text><rich_text style="italic">type</rich_text><rich_text> [definition] [name]
For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And there's an optional </rich_text><rich_text style="italic">uid</rich_text><rich_text> parameter, which allows you to manually set the unique identifier:
</rich_text><rich_text style="italic">type</rich_text><rich_text> [definition] [name]:
</rich_text><rich_text style="italic">uid</rich_text><rich_text> [id]
For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When defining a property, which we'll cover later in detail, it's possible to define the type in-place:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is also possible to define the type in-place when defining a property in-place:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In this case, cardinality specification in <> appears after the type, and </rich_text><rich_text style="italic">required</rich_text><rich_text> or </rich_text><rich_text style="italic">optional</rich_text><rich_text> appear before it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The last example may not give much information right now. We'll discuss all these features when we talk about properties and classes.</rich_text><codebox char_offset="1481" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type text {yes, no} answer</codebox><codebox char_offset="1631" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type integer [0, inf) natural:
uid http://www.types.org/natural</codebox><codebox char_offset="1739" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property integer [0, inf) length</codebox><codebox char_offset="1826" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Rope:
integer [0, inf) length</codebox><codebox char_offset="1943" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
required integer [0, inf) prop1
optional integer [0, inf) prop2
integer [0, inf) <3:7> prop3</codebox><node name="Union" prog_lang="custom-colors" readonly="False" tags="" unique_id="166"><rich_text>Union types in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> are much like unions of sets in mathematics. When a type is a union of other types, its range of legal values is the union of these types' ranges. It can have any value valid for at least one of these types. For example, a union of </rich_text><rich_text weight="heavy">text</rich_text><rich_text> and </rich_text><rich_text weight="heavy">integer</rich_text><rich_text> can have any integral number and string as a value.
As the text and integer example shows, sometimes there's a conflict between types. For example 1234 can be a number but can also be a string. So does 17/06/2013. The solution for that is </rich_text><rich_text style="italic">precedence</rich_text><rich_text>: There's an ordering of the types, which determines how a value is matched to a type. In particular, </rich_text><rich_text weight="heavy">text</rich_text><rich_text> is the last type in the ordering, which means 1234 will be considered as a number, and 17/06/2013 will be considered as a date. In many cases, using confusing or ambiguous unions doesn't make much sense. Make sure you have a good reason to mix types.
The ordering of types doesn't matter to </rich_text><rich_text style="italic">Idan </rich_text><rich_text>itself, but it is specified because the usage of the same ordering by all software guarantees corrent and consistent interpretation of your files. The precedence is:
1. boolean
2. time
3. date
4. integer
5. real
6. text
Types are defined using the </rich_text><rich_text style="italic">type</rich_text><rich_text> keyword, and unions can use the </rich_text><rich_text style="italic">union</rich_text><rich_text> keyword right after </rich_text><rich_text style="italic">type</rich_text><rich_text>, although </rich_text><rich_text style="italic">union</rich_text><rich_text> is optional and exists mainly for readability. After that, in braces {}, we list the types we want to unite. Then the name of the new type, and we're done.
Let's see an example. Assume we want to have a </rich_text><rich_text style="italic">duration</rich_text><rich_text> type, which can be a time expressed as hh:mm:ss, or an integer in millisecond units. Then we want to make a union of </rich_text><rich_text style="italic">date</rich_text><rich_text> and </rich_text><rich_text style="italic">integer</rich_text><rich_text>. Using the union keyword for best readability, this is how we do it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
We can also omit the </rich_text><rich_text style="italic">union</rich_text><rich_text> keyword, in which case the {} containing types serve as the indicator, indicating we're creating a union:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now, any property with the </rich_text><rich_text style="italic">duration</rich_text><rich_text> type can have both dates and integers as valid values.
It's also possible to use more than three types. Actually, any number of types is valid:
</rich_text><rich_text justification="left"></rich_text><rich_text>
You can define types using other types you defined:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Like any other entity type, types can have </rich_text><rich_text style="italic">uid</rich_text><rich_text>s:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's possible to define a type as an alias of another type. It can be done with the union syntax, with a single type inside the braces, but there's also an alternative syntax which makes it clear we're defining an alias. This is the regular union syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And this is the </rich_text><rich_text style="italic">alias</rich_text><rich_text> syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Defining a type alias may seem strange: Why use it? Why not use the original type directly? Doesn't it just add unnecessary definitions and complexity to the code? Well, actually, type aliases can be quite useful. Assume you want to use several existing types very often, or introduce them in your public model, and you don't want to write the full names everywhere. For example, assume you use a type called </rich_text><rich_text style="italic">duration</rich_text><rich_text> from a namespace called </rich_text><rich_text style="italic">system</rich_text><rich_text>. As we'll see later, you'll need to refer to it as </rich_text><rich_text style="italic">system::duration</rich_text><rich_text> every time.
If you declaring </rich_text><rich_text style="italic">using</rich_text><rich_text> the </rich_text><rich_text style="italic">system</rich_text><rich_text> namespace, you can directly use </rich_text><rich_text style="italic">duration</rich_text><rich_text>, but it also means you import all other definitions from </rich_text><rich_text style="italic">system</rich_text><rich_text>, which may not be what you want. If a definition there creates a name conflict with your own, this solution may not work for you.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> provides clean simple solution: type aliasing. Define a new type locally as an alias of an existing type, and use the type alias in your code. Quick and simple.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> also allows declaring two existing types as alias types. Assume there are two types already defined, possibly by different people in different projects. Each project wants to have its own definition, but semantic-database software may benefit from knowing these types are the same.
It may become even more useful if the two types are defined in different languages, e.g. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> and RDF, in which case some software may not be able to easily detect identical types, but the user can easily give the sotware a hint.
This kind of hint is possible in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> by giving a value to the </rich_text><rich_text style="italic">alias</rich_text><rich_text> parameter of the </rich_text><rich_text style="italic">type</rich_text><rich_text>. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Specifying alias types like this is probably not very useful when using types defined purely in </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, becase the six-primitive-type is very simple and software deduction of identical types should be easy. But </rich_text><rich_text style="italic">Idan</rich_text><rich_text> supports usage of external definitions from other languages, in which case alias hints may be more useful and provide software with information otherwise not trivial to deduce.
Union types can be defined directly where they are used. This is how a minimal property definition may look like:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Instead of defining </rich_text><rich_text style="italic">duration</rich_text><rich_text> explicitly, we can instead define it in-place:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Or we can omit </rich_text><rich_text style="italic">union</rich_text><rich_text>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
A union type can also be defined in-place where a property is defined in-place. This is what an in-place property defintion looks like, in a class definition:
</rich_text><rich_text justification="left"></rich_text><rich_text>
We can define the type in-place:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And we can omit the </rich_text><rich_text style="italic">union</rich_text><rich_text> keyword:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide if it's legal to define an empty union, and whether it makes sense or can be useful anywhere</rich_text><rich_text>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Also possible in-place, and applies to enum and maybe to ranges too:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Also what if we use empty braces and don't use </rich_text><rich_text style="italic">union</rich_text><rich_text> or </rich_text><rich_text style="italic">enum</rich_text><rich_text>? Actually it doesn't matter, since anyway we refer to the empty type, like the empty set in math:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION for now I don't have use cases for it, so it won't exist. But I'll add it later if I find use cases.</rich_text><codebox char_offset="1674" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {date, integer} duration</codebox><codebox char_offset="1811" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type {date, integer} duration</codebox><codebox char_offset="1996" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {boolean, date, time} type_a
type union {boolean, date, time, integer} type_b
type union {boolean, date, time, text, real} type_c</codebox><codebox char_offset="2052" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {type_c, type_b, type_a} type_d
type union {type_a, real, type_d} type_e</codebox><codebox char_offset="2105" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type {date, integer} duration:
uid http://www.types/org/duration</codebox><codebox char_offset="2364" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type {date} type_a
type union {date} type_b</codebox><codebox char_offset="2398" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type alias date type_c</codebox><codebox char_offset="3993" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type {date, integer} my_type_1:
alias system::duration</codebox><codebox char_offset="4503" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property duration work_time</codebox><codebox char_offset="4583" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property union {date, time} work_time</codebox><codebox char_offset="4609" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property {date, time} work_time</codebox><codebox char_offset="4772" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person:
duration work_time</codebox><codebox char_offset="4809" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person:
union {date, time} work_time</codebox><codebox char_offset="4848" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person:
{date, time} work_time</codebox><codebox char_offset="4958" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {} empty_type</codebox><codebox char_offset="5031" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property union {} empty_prop
type enum {} empty_enum
property enum {} empty_prop2</codebox><codebox char_offset="5194" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type {} empty_type
propety {} empty_prop</codebox></node><node name="Type References" prog_lang="custom-colors" readonly="False" tags="" unique_id="165"><rich_text>Type references allow you to refer to types which are defined in-place, and don't have a name. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The type of the work_time property is unnamed, but can still be used and refered as </rich_text><rich_text style="italic">typeof (work_time)</rich_text><rich_text>. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide finally if the </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">typeof</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> feature is supported.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION for now, for simplicity of implementation it's not supported, but later I want to support </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">typeof</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> for properties and </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">classof</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> for objects and graphs.</rich_text><rich_text>
Types can also be defined in-place in an in-place property definition. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Since the work_time property is defined in-place, we refer to it as </rich_text><rich_text style="italic">Person.work_time</rich_text><rich_text>. Then we can refer to the type of work_time as </rich_text><rich_text style="italic">typeof (Person.work_time)</rich_text><rich_text>. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO see above</rich_text><rich_text>
</rich_text><rich_text style="italic">typeof</rich_text><rich_text> can be used when you need to specify a type. For example, when defining a union or an alias. Here are some examples:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="109" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property union {date, time} work_time</codebox><codebox char_offset="515" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person:
union {date, time} work_time</codebox><codebox char_offset="818" frame_height="96" frame_width="900" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text my_prop $ Define a simple property
type union {typeof (my_prop), time} my_type $ Define a union using typeof
type alias typeof (my_prop) my_alias $ Define an alias of a type specified with typeof
type union {date, time} duration:
alias typeof (my_prop) $ Define an typeof-specified alias hint for a type</codebox></node><node name="Enumeration" prog_lang="custom-colors" readonly="False" tags="" unique_id="167"><rich_text>Enumerations are a way to explicitly specify the values a type can have. For example, the </rich_text><rich_text style="italic">boolean</rich_text><rich_text> type has two values: </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text>.
In order to ensure type safety, </rich_text><rich_text style="italic">Idan</rich_text><rich_text> allows the user to specify the type of all enumeration members. If not specified, they are determined automatically, according to the same type precedence used for unions. Sometimes it's not what you want. Sometimes it is. That's why </rich_text><rich_text style="italic">Idan</rich_text><rich_text> lets you specify types explicitly.
An enumeration is defined as follows. First, the usual </rich_text><rich_text style="italic">type</rich_text><rich_text> keyword. Then the optional </rich_text><rich_text style="italic">enum</rich_text><rich_text> keyword and an optional existing type. Then, a list of values inside braces {}, and finally the name of the new type. For example, we can define an </rich_text><rich_text style="italic">answer</rich_text><rich_text> type like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note that strings must be quoted, and cannot be multi-line. Then, </rich_text><rich_text style="italic">yes</rich_text><rich_text> and </rich_text><rich_text style="italic">no</rich_text><rich_text> can be used without quotes when assigning values to properties.
These examples are the same as the one above, but omit optional details:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Special care must be taken when not specifying the type. If we omit </rich_text><rich_text style="italic">text</rich_text><rich_text> from the definition, how will any software know which type we want to derive our new type from? Well, in this case it may seem obvious: we derive the </rich_text><rich_text style="italic">text</rich_text><rich_text> type. But this first thought is misleading: What if we already have a type </rich_text><rich_text style="italic">word</rich_text><rich_text> and we want to use the values "yes" and "no" from type </rich_text><rich_text style="italic">word</rich_text><rich_text> and not from type </rich_text><rich_text style="italic">text</rich_text><rich_text>?
In other cases it's more critical: 2342 can be an integer or a time (in hours). How will software know?
There are two ways to specify the type. One way is to set the type for the whole enum, which we used above. The other way is to choose the type for each value individually. This is done by prepending the type name to the value, separated from the value by a # character. The # character more-or-less means "set membership" in </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When using this notation, </rich_text><rich_text weight="heavy">strings without spaces</rich_text><rich_text> </rich_text><rich_text weight="heavy">and commas</rich_text><rich_text> can be written without the quotes:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And again it's possible to omit the </rich_text><rich_text style="italic">enum</rich_text><rich_text> keyword:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to easily mix values from different types:
</rich_text><rich_text justification="left"></rich_text><rich_text>
So far we've seen only primitive types in use by enumerations. How do we use other types? For types derived from primitive types, there's no difference: just like text#yes is used, answer#yes can be used. But for classes it's different.
The values of class objects, i.e. the objects themselves, are represented by their local names. It's also possible to use object IDs, but we'll get there in a later section. Local names can be specified right after the # in a similar manner to primitive types. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Instead, it's possible to specify the names using the namespace they come from:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In this case, it's also possible to specify the type before the braces, to make it clear (and allow testing) which type we use:
</rich_text><rich_text justification="left"></rich_text><rich_text>
When a class comes from an external namespace, or just for readability, it's possible to specify it:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Note, however, that namespaces must be </rich_text><rich_text style="italic">imported</rich_text><rich_text> or </rich_text><rich_text style="italic">using</rich_text><rich_text>ed before their names can be used. Later we'll see how it's done, and what it means.</rich_text><codebox char_offset="712" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum text {"yes", "no"} answer</codebox><codebox char_offset="931" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum {"yes", "no"} answer
type text {"yes", "no"} answer
type {"yes", "no"} answer</codebox><codebox char_offset="1780" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type enum {text#"yes", text#"no"} answer</codebox><codebox char_offset="1879" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type enum {text#yes, text#no} answer</codebox><codebox char_offset="1933" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="verilog" width_in_pixels="True">type {text#yes, text#no} answer</codebox><codebox char_offset="1999" frame_height="24" frame_width="870" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type enum {text#hello, integer#3_201201, real#11.532%-8, date#17/6/13, time#22:54} some_type</codebox><codebox char_offset="2517" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type enum {Topic#fruit, Topic#vegetables} some_type</codebox><codebox char_offset="2601" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum {Food::fruit, Food::vegetables} some_type</codebox><codebox char_offset="2733" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum Topic {Food::fruit, Food::vegetables} some_type</codebox><codebox char_offset="2838" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum Todo::Topic {Food::fruit, Food::vegetables} some_type</codebox></node><node name="Pattern" prog_lang="custom-colors" readonly="False" tags="" unique_id="168"><rich_text>Patterns are the most expressive way to choose which values are valid for the new type you define. Since </rich_text><rich_text style="italic">Idan</rich_text><rich_text> currently doesn't support set-builder notation, patterns are the way when unions and enums aren't enough. Unless you use ranges, which we'll explore in the next section.
A pattern is a </rich_text><rich_text weight="heavy">regular expression</rich_text><rich_text>. Values are matched against it, and are considered valid if and only if they match the pattern. Currently, patterns are possible only for number types (e.g. integer, real) and strings (e.g. text).
Here's an example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The type can be one of the three types </rich_text><rich_text style="italic">integer</rich_text><rich_text>, </rich_text><rich_text style="italic">real</rich_text><rich_text> or </rich_text><rich_text style="italic">text</rich_text><rich_text>. Types derived from them may be supported too in a later version.
The regular expression is delimited by [" and "].
It's also possible to define pattern types in-place:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide finally whether it's going to be possible:</rich_text><rich_text> It's also possible to add the </rich_text><rich_text style="italic">pattern</rich_text><rich_text> keyword before the type:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION yes, it is possible.</rich_text><codebox char_offset="533" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type text ["[a-zA-Z0-9]{8}"] some_type</codebox><codebox char_offset="769" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text ["[a-zA-Z0-9]{8}"] my_prop
class MyClass
text ["[a-zA-Z0-9]{8}"] my_prop</codebox><codebox char_offset="891" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type pattern text ["[a-zA-Z0-9]{8}"] some_type</codebox></node><node name="Range" prog_lang="custom-colors" readonly="False" tags="" unique_id="169"><rich_text>Ranges are a way to specify which values are valid for a type. They work for types whose values are ordered, by specifying a minimum value and/or a maximum value. Ranges can apply to numbers, dates and times.
() denotes an open range. [) and (] denote a half-open range. [] denotes a closed range.
The special values </rich_text><rich_text style="italic">inf</rich_text><rich_text> and </rich_text><rich_text style="italic">-inf</rich_text><rich_text> can be used.
Examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is </rich_text><rich_text weight="heavy">illegal</rich_text><rich_text> to use </rich_text><rich_text style="italic">inf</rich_text><rich_text> and </rich_text><rich_text style="italic">-inf</rich_text><rich_text> with ] and [ respectively, because a number cannot be infinite. It's also illegal to use inf as a minimum or -inf as a maximum. But both are legal for dates, times and numbers (although times start from 00:00:00, so no time is smaller than that).
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide if negative times are legal, e.g. -02:53:21.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION right now not, maybe I'll add it later.</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide if a keyword </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">range</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> can be used for readability</rich_text><rich_text>: </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION yes, it can.</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="357" frame_height="80" frame_width="1000" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="ooc" width_in_pixels="True">type integer [0, inf) natural $ any natural number i.e. non-negative integer i.e. unsigned integer
type real [0, 1] some_type $ any real number between 0 and 1 including both
type real (-inf, 5) other_type $ any real number smaller than 5
type date [1/1/2013, 17/6/2013] a_type $ any date between 1/1 and 17/6 in 2013, including both</codebox><codebox char_offset="832" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type range integer [3, 81] my_type</codebox></node><node name="Compound Definitions" prog_lang="custom-colors" readonly="False" tags="" unique_id="183"><rich_text foreground="#ffff00000000" weight="heavy">TODO</rich_text><rich_text> this section is supposed to describe how to use one definition mechanism inside another, assuming I decide to support this feature. For example: </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Without this feature, you'd have to use two definitions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Also, what if my definition becomes too long to fit in a screen-long line? Can't I split it? </rich_text><rich_text foreground="#ffff00000000" weight="heavy">Suggestion</rich_text><rich_text>: allow specifying union/enum members like property values: </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Or maybe like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This also allows easily putting them all on a single like, so maybe the existing one-line syntax can be totally removed for simplicity:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide if </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">local</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> can be used to define private helper definitions, for example</rich_text><rich_text>:
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
This way, if the </rich_text><rich_text style="italic">member</rich_text><rich_text>-property syntax is not supported, or we just prefer not to use it, we can define helper definitions and declare them local, so that they're not accessible from outside the file.</rich_text><codebox char_offset="184" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {date, enum {"yesterday", "today", "tomorrow"}} my_date</codebox><codebox char_offset="245" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type enum {"yesterday", "today", "tomorrow"} date_text
type union {date, date_text} my_date</codebox><codebox char_offset="445" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union duration:
date
time</codebox><codebox char_offset="469" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union duration:
member date
member time</codebox><codebox char_offset="609" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union duration:
member date, date</codebox><codebox char_offset="730" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">local type enum {"yesterday", "today", "tomorrow"} date_text
type union {date, date_text} my_date</codebox></node></node></node><node name="Properties" prog_lang="custom-colors" readonly="False" tags="" unique_id="170"><rich_text foreground="#ffff00000000" weight="heavy">TODO</rich_text><rich_text foreground="#ffff00000000"> consider allowing in-place defined properties to be just like explicitly defines ones, and be refered using syntax like </rich_text><rich_text foreground="#ffff00000000" style="italic">MyClass.my_prop</rich_text><rich_text foreground="#ffff00000000">. It may be useful when e.g. defining a task class by hand: It's much easier to define all properties in-place, but still be able to export to RDF and/or use in other classes.</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000">This issue is already mentioned in the sub-sections under Type Definition.</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION yes, this is supported. In-place properties can't have parameters (e.g. uid) specified, but do get an auto-generated uid and can be used like any explicitly-defined property.</rich_text><rich_text>
We've seen how types work. We are able to choose a set of values, and define a type which takes these values. But the values themselves are not enough to describe things. 5 can be "5 meters" or "5 flowers" or "the 5th person in the list". We need to add </rich_text><rich_text style="italic">meaning</rich_text><rich_text> to our definitions.
Properties are like relations. They represent a relation between objects, or between an object and a value. For example, take the sentence "John is a designer". This sentence specifies a relation between "John" and "designer". The relation is "occupation". Or more specifically, "the given person has the following occupation". In </rich_text><rich_text style="italic" weight="heavy">Idan</rich_text><rich_text>, we'll define a property and call it </rich_text><rich_text style="italic">occupation</rich_text><rich_text>.
In simple words, a property is a combination of a type and a meaning. Properties are used with classes, which we'll talk about in the next section.
Assume we have a model which describes people. We have a Person class, through which we define Person objects and say things about them. We can define a person </rich_text><rich_text style="italic">john_smith</rich_text><rich_text> and say "John's occupation is design". We can say "designer" is the value of a property "occupation" of a person object "john_smith".
Properties can be defined explicitly, or in-place when defining a class. Explicit definition starts with the </rich_text><rich_text style="italic">property</rich_text><rich_text> keyword, then the type, and then the name of the property:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This property takes the </rich_text><rich_text style="italic">time</rich_text><rich_text> type, and combines it with a meaning: </rich_text><rich_text style="italic">start_time</rich_text><rich_text>. Now, for example, we can define a task (e.g. "water the flowers") and define its start time (e.g. 16:00). We can also define the </rich_text><rich_text style="italic">uid</rich_text><rich_text> of the property, like any other entity:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we can define a Task class with the start_time property, so tasks will have a start time:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to define the type in-place when defining the property. The previous section, Types, shows many examples. And it's possible to define the property in-place when defining the class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to use the </rich_text><rich_text style="italic">uid</rich_text><rich_text> of a property in the class definition:
</rich_text><rich_text justification="left"></rich_text><rich_text>
But the uid has to be quoted, otherwise it will be treated as an invalid local entity.</rich_text><codebox char_offset="1880" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property time start_time</codebox><codebox char_offset="2136" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property time start_time:
uid http://www.properties.org/start_time</codebox><codebox char_offset="2234" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
start_time</codebox><codebox char_offset="2438" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
time start_time</codebox><codebox char_offset="2515" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
"http://www.properties.org/start_time"</codebox></node><node name="Classes" prog_lang="custom-colors" readonly="False" tags="" unique_id="171"><rich_text>A class represents a set, in the mathematical sense. For example, "the set of all people". When we need to work with certain objects on the computer, we naturally try to define how the information about these objects is represented in computer memory and files. We define the </rich_text><rich_text style="italic">computer representation</rich_text><rich_text> of a set of objects, so that we can describe them using computer tools. This is where classes help us.
A class represents a set, but is more than the abstract representation. A class also defines the </rich_text><rich_text style="italic">computer representation</rich_text><rich_text> of the set's members. For the "set of all people", the </rich_text><rich_text style="italic">Person</rich_text><rich_text> class could define the properties we want to store on the computer, about each person. We would then choose properties according to our usage pattern. A bank may not care how tall a person is, but a shoe designer may care.
Let's create a model which describes tasks. Then we can manage a to-do list (or a whole project breakdown) with exactly the propeties we want it to have. Each task is going to have a list of topics (which are somewhat like tags, but not exactly the same), so let's define the Topic class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The </rich_text><rich_text style="italic">class</rich_text><rich_text> keyword declares a new class. Then we specify the name of the class and a colon. All the lines after that are property lines and must be indented with exactly the same indentation level. Like any other entity, it's possible to define the </rich_text><rich_text style="italic">uid</rich_text><rich_text> parameter.
The third property has three new features we haven't seen yet:
• Its type is a class type, not a built-in type
• Its type is the class being defined
• Its type contains cardinality specification
Classes serve as types, just like </rich_text><rich_text weight="heavy">text</rich_text><rich_text> and </rich_text><rich_text weight="heavy">boolean</rich_text><rich_text> are. And a class can have a property of self type, so that a topic can have sub-topics, a graph node can have neighbor nodes, etc.
A cardinality specification decides the number of times a property can be specified for a given object. By default, each property is </rich_text><rich_text style="italic">optional</rich_text><rich_text>, which means it can appear once or not at all. In many cases this default is enough, but in many other cases we want a different setting. For example, assume we have a Community class and we want it to have a </rich_text><rich_text style="italic">leader</rich_text><rich_text> property. According to the rules of the community, there must be 3-5 leaders, so we want the number of leaders to be 3, 4 or 5.
Instead of specifying the limits as numbers, it is possible to use the </rich_text><rich_text style="italic">required</rich_text><rich_text> keyword in simple cases. This keyword means a property must appear, i.e. the cardinality is exactly 1.
Let's see some examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The following examples are possible too:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is also possible to state exactly which cardinality values are allowed:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It is also possible to use several ranges, not necessarily disjoint, separated by commas:
</rich_text><rich_text justification="left"></rich_text><rich_text>
As you can see, some definitions may be difficult to read, and quite confusing. Software should warn the user if the same value is specified more than once or in more than one range, but it is not an error. This way, dymanically generated ranges can be safely used without worrying about other ranges conflicting with them. The warning helps users find typos and other "bugs".
For clarity and readability of the code, the keyword </rich_text><rich_text style="italic">optional</rich_text><rich_text> may be used as a clear way to indicate a property may appear once or not appear at all. It's exactly identical to not declaring cardinality at all, or declaring it using <0:1> or <0,1> or <:1>. For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now let's go back to our plan. The Topic class has a </rich_text><rich_text style="italic">Topic<> subtopic</rich_text><rich_text> propety, which means a topic can have any number of subtopics, including zero. Now, using the Topic class, we can define our Task class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
As you can see, we can use predefined properties by writing the property name. If we need to specify a cardinality constraint, we specify it before the name:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Class properties can have </rich_text><rich_text style="italic">default values</rich_text><rich_text>. A default value is a value used when it's not explictly specified. The rules are:
• If a default value is specified for a 0-cardinality property, then it's always used
• If a default value is specified for a non-0 property, it's used when a value is not specified
• If a property cannot be specified exactly once, then a legal number of default values must be specified
• It's thus possible to define more than one default value
• Default values are specified only in class definitions
Default values are specified after the property name. First the </rich_text><rich_text style="italic">default</rich_text><rich_text> keyword, then the values separated by commas. For example:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1101" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
text name
text description
Topic<> subtopic</codebox><codebox char_offset="2445" frame_height="154" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text my_prop_1 $ May appear once, or not appear at all
required text my_prop_2 $ Must appear exactly once
text<> my_prop_3 $ May appear any number of times, including zero
text<3:5> my_prop_4 $ May appear 3-5 times, i.e. 3 or 4 or 5
text<4> my_prop_5 $ Must appear exactly 4 times
text<:7> my_prop_6 $ May appear up to 7 times
text<2:> my_prop_7 $ Must appear at least twice</codebox><codebox char_offset="2490" frame_height="168" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text<0:> a $ identical to text<>
text<1> b $ identical to required text
text<1:1> c $ identical to required text
text<4:4> d $ identical to text<4>
text<0> e $ indicates the property must not appear
text<0:0> f $ identical to text<0>
text<0:5> g $ identical to text<:5>
text<0:1> h $ identical to text</codebox><codebox char_offset="2569" frame_height="120" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text<0, 3> a # Appear exactly 0 or 3 times
text<0, 1> b # Identical to text and text<0:1> and text<:1>
text<2, 5, 9> c # Appear 2 or 5 or 9 times
text<0, 1, 3, 6, 34> d # Appear 0 or 1 or 3 or 6 or 34 times
text<3, 54, 16, 68, 1, 0> e # Order of cardinalities doesn't matter</codebox><codebox char_offset="2663" frame_height="168" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
text<0, 1:> a
text<0, 3, 5:8, 10> b
text<:4, 7:9, 12:> c
text<1:2, 4:8, 16:32, 0, 13, 7, 55:67> d
text<0, 0:0, 0> e
text<0:0, 0:3, 1:2, 3:3, 1, 2> f
text<0:5, 1:6, 2:7, 8, 4:10> g
text<:4, 0:2, 3:5, 2:8, 7:> h</codebox><codebox char_offset="3314" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
optional text a</codebox><codebox char_offset="3527" frame_height="190" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
required content
creation_time
required complete
Topic<> topic
Task<> subtask
date start_date
time start_time
date finish_date
time finish_time</codebox><codebox char_offset="3689" frame_height="82" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text my_prop
class MyClass:
text <3:5> some_prop
<3:5> my_prop</codebox><codebox char_offset="4354" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
<3:7> prop1 default a, b, c, d
<0> prop2 default e
<0, 3> prop3 default f, g, h
<1:4> prop4 default i</codebox></node><node name="Objects" prog_lang="custom-colors" readonly="False" tags="" unique_id="172"><rich_text>So far we've been describing the data model, i.e. which entities we want to define, and what we want to say about them. But we haven't touched the actual data. </rich_text><rich_text style="italic">Objects</rich_text><rich_text> are the actual data. Once we define classes, we can start defining objects.
In the math metaphor, a class is a set, and an object is a member of the set. For example, we can have a Person class which represents the "set of all people" and an object john_smith which describes a specific person.
There are two ways to define objects: explicit definition, and graph definition. In this section we'll see only the explicit definition, and graphs will be introduced later in the Graphs section. Graphs allow defining large groups of objects quickly and conveniently.
We're going to define objects of the following class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
An object definition begins with the </rich_text><rich_text style="italic">object</rich_text><rich_text> keyword, then the type of the object (must be a class, but </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider allowing definition of constants</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported</rich_text><rich_text>), then the object's local name. Then optionally a colon and property lines. Let's define a topic "food":
</rich_text><rich_text justification="left"></rich_text><rich_text>
We haven't used the optional </rich_text><rich_text style="italic">uid</rich_text><rich_text> parameter, but it's possible like with any other entity. We defined the required name property, and the optional description. We didn't specify any super-topics. Property values are set by starting the line with the property name, and then the value. The Primitive Types section explains in detail how to specify values.
If we don't want to define any properties, we drop the colon and have a single line:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The object's local name must begin with a letter and contain only English letters, digits and underscores. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider full i18n of the language.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION accepted! discussed in the i18n subpage.</rich_text><rich_text>
Let's define more objects:
</rich_text><rich_text justification="left"></rich_text><rich_text>
As you probably have noticed, the object name is identical to the </rich_text><rich_text style="italic">name</rich_text><rich_text> property. It doesn't have to be like that, but in some cases it makes sense, and as a result we type all names twice. One of the things graph definition provides is avoiding this duplication.
The order in which we specify the properties doesn't matter:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The cardinality of supertopic is unlimited. How do we specify more than one value? We can specify them all or a single line with commas, or on separate lines, or combine both options:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The names used in the supertopic property are local object names, not </rich_text><rich_text style="italic">name</rich_text><rich_text> property values.
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO I'm considering to make it possible to define local IDs which are not limited to the rules of local names. These IDs are only local, and are NOT the URIs/UUIDs for global use, but can make it easier to use serial IDs for mass creation of objects.
If it gets supported, the syntax will be:</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported; only graph objects can have uids starting with a digit</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
And refering to these objects using the ID will be possible </rich_text><rich_text style="italic">only</rich_text><rich_text> by using the class name Topic#42pf83j.</rich_text><codebox char_offset="789" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
required text name
text description
Topic<> supertopic</codebox><codebox char_offset="1081" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic food:
name food
description Things people eat</codebox><codebox char_offset="1525" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic food</codebox><codebox char_offset="1755" frame_height="170" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic fruit:
name fruit
description Tasty and healthy
supertopic food
object Topic vegetables:
name vegetables
description Healthy and tasty
supertopic food</codebox><codebox char_offset="2084" frame_height="170" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic fruit:
description Tasty and healthy
supertopic food
name fruit
object Topic vegetables:
supertopic food
name vegetables
description Healthy and tasty</codebox><codebox char_offset="2272" frame_height="314" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic x:
name x
supertopic a, b, c, d, e
object Topic y:
name y
supertopic a
supertopic b
supertopic c
supertopic d
supertopic e
object Topic z:
name z
supertopic a, d
supertopic b
superropic c, e</codebox><codebox char_offset="2759" frame_height="80" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object Topic #42pf83j:
name pears
supertopic fruit
supertopic entities, things</codebox><node name="i18n" prog_lang="custom-colors" readonly="False" tags="" unique_id="184"><rich_text>This page discusses the plan to support i18n in two things
1. The language keywords
2. Entity UIDs
Currently language keywords and entity UIDs can contain only English letters, digits and underscores. I suggest to add all the other unicode non-space </rich_text><rich_text style="italic">non-Idan </rich_text><rich_text>characters, i.e. names can have any characters except for the ones which have a special meaning in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> and some other ones reserved (e.g. + - * & ^ ! ~ | ?), and cannot start with an underscore.
For the language itself, there will have to be translation, and each </rich_text><rich_text style="italic">Idan</rich_text><rich_text> file will have to begin by specifying the language on the first line. I'll study locales in more detail, but something like "</rich_text><rich_text style="italic">lang he_IL</rich_text><rich_text>" or "</rich_text><rich_text style="italic">lang hebrew</rich_text><rich_text>" can do.
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider using </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">locale</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> instead of </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">lang</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> and allowing extra deductions from locale, e.g. the way numbers are written, dates, time, etc.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION the keyword will be </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">language</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">, specified as a locale like in gettext (see link below), and only the translations are used, i.e. usage for dates, numbers, etc. currently not supported</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO plan infrastructure for storing the translationss of keywords for each language</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION see link below, I'm going to read how gettext works and take a similar approach</rich_text><rich_text>
This page from gettext manual explains language codes and locales:
</rich_text><rich_text link="webs http://www.gnu.org/software/gettext/manual/html_node/Setting-the-POSIX-Locale.html#Setting-the-POSIX-Locale">http://www.gnu.org/software/gettext/manual/html_node/Setting-the-POSIX-Locale.html#Setting-the-POSIX-Locale</rich_text><rich_text>
Suggested Hebrew translations of keywords and parameters:
text טקסט
boolean בוליאני
integer שלם
real ממשי
date תאריך
time זמן
language שפה
namespace מרחב_שם
type טיפוס
property תכונה
class מחלקה
object עצם
graph גרף
union איחוד
enum מניה
range טווח
pattern תבנית
alias כינוי
visibility ראות
public פומבי
shared משותף
private פרטי
date_order סדר_תאריך
dmy יחש
date_separator מפריד_תאריך
date_format מבנה_תאריך
uid מזהה
include כלול
import יבא
using בשימוש
header כותרת
state מצב
child ילד
parent הורה
base בסיס
link קשר
default ברירת_מחדל
</rich_text><rich_text underline="single" weight="heavy">Default Location Of Translations</rich_text><rich_text>:
It's going to be possible to pass translation files and their location, but I want to have a default system location for them. Where is the right place? Let's see where software translations are kept...
The gettext mo files are in /usr/share/locale/, which has a folder for each locale, and inside there's an LC_MESSAGES folder which contains all programs' translations for the specific locale.
Currently I'm not going to use gettext, so I won't throw my translations there. Instead, I'll have a folder under /usr/share/ which will contain all translations. The translations will have a </rich_text><rich_text style="italic">separate repo</rich_text><rich_text>. Idan data will probably be under /usr/share/idan/ and translations in a </rich_text><rich_text style="italic">translations</rich_text><rich_text> or </rich_text><rich_text style="italic">intl</rich_text><rich_text> or </rich_text><rich_text style="italic">l10n</rich_text><rich_text> subfolder. The library will probably be called </rich_text><rich_text style="italic">libidan</rich_text><rich_text> and have its own data folder if necessary.</rich_text></node></node><node name="Comments" prog_lang="custom-colors" readonly="False" tags="" unique_id="173"><rich_text>Each line may end with a comment. A comment begins with a $ (S with vertical bar) character, and everything after that line after the $ is ignored. If a $ appears inside a string, it's not considered a comment. Also, multi-line comments are currently not supported. It's possible to have comment-only lines by starting them with optional indentation and then $ and comment text.
For example:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="394" frame_height="132" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass: $ A comment here
text a $ This is a comment
real b $ This is another comment
$ Comment with indentation
integer c $ And this is a comment too
$ And this is the last comment</codebox></node><node name="Graphs" prog_lang="custom-colors" readonly="False" tags="" unique_id="174"><rich_text>In the Objects section we saw the explicit object definition syntax. But when defining many objects, especially hierarchies/graphs of objects, the explicit definition becomes cumbersome and hard to read. You can't figure out the relations between objects just by looking at a long list of object definitions.
Graphs solve at least most of these issues, and offer other convenient features by allowing you to easily:
• Avoid the </rich_text><rich_text style="italic">object</rich_text><rich_text> keyword and the class name for each object repeatedly
• Define a property to be auto-generated from the object's identifier i.e. local name
• Define a property to be read from the object definition's first line, without specifying its name every time
• Define an object hierarchy in a visually convenient manner, not as a linear hard-to-read list of objects
• Define a property (especially useful for boolean) to be set as a "check box" on the object definition line
• Use numeric object names, allowing to use serial numbers as names when names don't matter
An graph definition begins with the </rich_text><rich_text style="italic">graph</rich_text><rich_text> keyword, then the type of the objects in the graphs (they all must be of the same class) and the graph name. Here's a definition of an empty graph:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide if graphs can have a </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">uid</rich_text><rich_text foreground="#ffff00000000" weight="heavy">.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently they're not used when refering to objects, and </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">don't</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> have their own uids.</rich_text><rich_text>
Under the first line, we do two things. First, we specify parameters. Then, we define the objects. The parameters you can specify are:
• child/parent
• auto
• header
• state
Each object definition begins with a slash (/) followed by the object's ID. The ID has the same rules as regular objects, with one exception: It may begin with a digit.
Here's a Topic class we'll use for the examples:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Here's a (cumbersome) graph with one simple object and no parameters:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Not very different from a regular object definition, is it? It does make the first line shorter, but doesn't use all the graph features.
Graphs can auto-generate a property using the ID of an object. This is usually useful for generating a human-visible label, and removes duplication. Let's use it here. We'll set the </rich_text><rich_text style="italic">auto</rich_text><rich_text> parameter to </rich_text><rich_text style="italic">name</rich_text><rich_text>, so that the name is copied from the ID:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Excellent. Now names are auto-generated. You may ask a relevant question: What if my object's name is tasty_food, while what I want to see on the screen is "Tasty Food"? The answer is: don't worry. Let the auto-generated name be tasty_food, and let your software scan and edit it, and change it to be nicer for humans to read. Software can easily do that.
Many classes have a "primary" property, such as content or description, which is defined for all objects. But typing "description" every time is cumbersome. It's possible to set a value for a property on the first line of the object definition, after the ID, and omit the property's local name. The property is chosen using the </rich_text><rich_text style="italic">header</rich_text><rich_text> parameter. Here's an example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now defining topics is much easier. Let's define some more:
</rich_text><rich_text justification="left"></rich_text><rich_text>
But haven't used the </rich_text><rich_text style="italic">supertopic</rich_text><rich_text> property yet. How do we define a hierarchy? This is how we'd do it without the special graph hierarchy features:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Maybe it's not that bad in this simple example, but if we had a long list of objects we wouldn't be able to see the hierarchical structure easily, and adding or moving objects would be very difficult. In graphs, it's possible to arrange the objects in a hierarchy using indentation levels. We need to define the </rich_text><rich_text style="italic">child</rich_text><rich_text> or the </rich_text><rich_text style="italic">parent</rich_text><rich_text> parameter for that. If we had a </rich_text><rich_text style="italic">subtopic</rich_text><rich_text> property, we'd define </rich_text><rich_text style="italic">child</rich_text><rich_text>. But since we have </rich_text><rich_text style="italic">supertopic</rich_text><rich_text>, we'll use </rich_text><rich_text style="italic">parent</rich_text><rich_text> and the result will look like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now indentation indicates the parent-child relations between objects. When you want to refer to an object already defined, append @ to its name, like in the example. We want </rich_text><rich_text style="italic">tomatos</rich_text><rich_text> to be a child (i.e. subtopic) of </rich_text><rich_text style="italic">red_things</rich_text><rich_text>, but it's already defined, so we refer to it in the hierarchy as </rich_text><rich_text style="italic">@tomatos</rich_text><rich_text>.
When defining properties for an object, they must be defined (</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide finally if I enforce this</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION yes, but I may remove this rule in the future if other orders seem useful</rich_text><rich_text>) before all child objects.
There are two more features to see: IDs which begin with a digit, and the </rich_text><rich_text style="italic">state</rich_text><rich_text> property. We'll see these IDs in the next examples, where we'll use the Task class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Let's define some tasks:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The topics and the due dates are going to remain there, but we're going to move the </rich_text><rich_text style="italic">complete</rich_text><rich_text> property somewhere else, and make it use less space and less text. In graphs it's possible to choose a property to be defined in a "box", between the ID and the </rich_text><rich_text style="italic">header</rich_text><rich_text> property value. For example, task 4 from the graph above would look like this with an empty box:
</rich_text><rich_text justification="left"></rich_text><rich_text>
This is illegal because the </rich_text><rich_text style="italic">complete</rich_text><rich_text> property is required, so we have to specify it in the box:
</rich_text><rich_text justification="left"></rich_text><rich_text>
For boolean properties, there's an alternative to true and false: X and space, respectively. We'll see it in the next example.
The "box"-defined property is specified through the </rich_text><rich_text style="italic">state</rich_text><rich_text> parameter. In the graph above, we need to add it like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we can define </rich_text><rich_text style="italic">complete</rich_text><rich_text> in boxes. Actually, we </rich_text><rich_text weight="heavy">have</rich_text><rich_text> to define it in boxes. It also applies to the other parameters: we have to define them in the special way, if they're specified by parameters. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide if it's a </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">have to</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> or just a recommendation and software should just warn about it.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION we can't use the regular property value syntax, but we can omit the value if it's not </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">required</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">, for example leave an empty box or omit the box, leave the header empty, have no child/parent objects, etc.</rich_text><rich_text>
When not specifying the state property, we can omit the box or leave it empty, i.e. [], but in our case </rich_text><rich_text style="italic">complete</rich_text><rich_text> is </rich_text><rich_text style="italic">required</rich_text><rich_text>, so we have to choose a value, true or false. In general we just put the values between [ and ], but for booleans there's an alternative: we can use [X] and [ ] instead of [true] and [false] respectively.
Here's our updated graph:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1188" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics</codebox><codebox char_offset="1719" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Topic:
required text name
text description
Topic<> supertopic</codebox><codebox char_offset="1793" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
/food
name food
description Things people eat</codebox><codebox char_offset="2183" frame_height="114" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
auto name
/food
description Things people eat</codebox><codebox char_offset="2909" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
auto name
header description
/food Things people eat</codebox><codebox char_offset="2973" frame_height="170" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
auto name
header description
/food Things people eat
/fruit Tasty food
/vegetables Very tasty food
/red_things Things whose color is... red!
/tomatos The red vegetables</codebox><codebox char_offset="3122" frame_height="222" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
auto name
header description
/food Things people eat
/fruit Tasty food
supertopic food
/vegetables Very tasty food
supertopic food
/red_things Things whose color is... red!
/tomatos The red vegetables
supertopic vegetables, red_things</codebox><codebox char_offset="3611" frame_height="204" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Topic topics:
auto name
header description
parent supertopic
/food Things people eat
/fruit Tasty food
/vegetables Very tasty food
/tomatos The red vegetables
/red_things Things whose color is... red!
@tomatos</codebox><codebox char_offset="4292" frame_height="114" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Task:
date due_date
required text content
Task<> subtask
Topic<> topic
required boolean complete</codebox><codebox char_offset="4321" frame_height="510" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Task tasks:
header content
child subtask
/0 Change the world
due_date 1/1/15
topic change, world, freedom
complete false
/1 Find people to help me
due_date 2/3/17
topic people, help
complete false
/2 Ask friends on Diaspora
due_date 7/12/14
topic social, friends, diaspora, ask
complete true
/3 Eat breakfast
topic food, morning
complete false
@1
/4 Make breakfast
topic cooking
complete false</codebox><codebox char_offset="4683" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True"> /4 [] Make breakfast
topic breakfast</codebox><codebox char_offset="4783" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True"> /4 [false] Make breakfast
topic breakfast</codebox><codebox char_offset="5033" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Task tasks:
header content
child subtask
state complete</codebox><codebox char_offset="5900" frame_height="420" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph Task tasks:
header content
child subtask
/0 [ ] Change the world
due_date 1/1/15
topic change, world, freedom
/1 [ ] Find people to help me
due_date 2/3/17
topic people, help
/2 [X] Ask friends on Diaspora
due_date 7/12/14
topic social, friends, diaspora, ask
/3 [ ] Eat breakfast
topic food, morning
@1
/4 [ ] Make breakfast
topic cooking</codebox></node><node name="Inheritance" prog_lang="custom-colors" readonly="False" tags="" unique_id="175"><rich_text weight="heavy">Class</rich_text><rich_text> </rich_text><rich_text weight="heavy">inheritance</rich_text><rich_text> is a way to define an "is a" relationship between classes, and enjoy some features and automation following the declarion of a class inheriting another class. More specifically, "B inherits A" means that B objects have all the properties that A objects have, and possibly more properties of their own.
For example, assume we have a Person class and a Programmer class. The following three things make sense and may be useful to us:
1. When a class has a property of type Person, we'd like to be able to use a Programmer object as its value.
2. When querying our model or doing some deduction, we'd like to assume that every programmer is person.
3. A programmer has all the properties of a person, plus some specific properties.
We can achieve such results by declaring that Programmer inherits Person. Other technical terms are "Programmer derives Person", "Programmer is a subclass of Person", "Person is a superclass of Programmer", "Programmer is a derived class of Programmer". And probably a more common term is "base class": "Person is a base class of Programmer". In </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, the </rich_text><rich_text style="italic">base</rich_text><rich_text> keyword specifies a base class in a class definition.
</rich_text><rich_text weight="heavy">Property</rich_text><rich_text> </rich_text><rich_text weight="heavy">inheritance</rich_text><rich_text> is a way to define an "implies" relationship between properties, and enjoy some features and automation following the inheritance declaration. "</rich_text><rich_text style="italic">b</rich_text><rich_text> implies </rich_text><rich_text style="italic">a</rich_text><rich_text>" means that a class property </rich_text><rich_text style="italic">b</rich_text><rich_text> implies the existence of a class property </rich_text><rich_text style="italic">a</rich_text><rich_text>.
For example, assume we have an </rich_text><rich_text style="italic">Organism</rich_text><rich_text> class, and we want to specify organs of a person using that class. We define properties:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now we can define a Person class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now, assume we want to take a Person object </rich_text><rich_text style="italic">john_smith</rich_text><rich_text>, and get a list of John's organs. How can we get such a list?
Solution 1: Get the values of the </rich_text><rich_text style="italic">heart</rich_text><rich_text>, </rich_text><rich_text style="italic">lung</rich_text><rich_text> and </rich_text><rich_text style="italic">eye</rich_text><rich_text> properties.
Problem: If we add organ properties, we'll have to update the query. It doesn't take </rich_text><rich_text style="italic">all</rich_text><rich_text> the organs into account, just the specific three ones we already defined.
Solution 2: Get the values of all Organism objects refered by properties of Person.
Problem: Organism doesn't have to be an organ. For example, we could define a </rich_text><rich_text style="italic">bacteria</rich_text><rich_text> property of type </rich_text><rich_text style="italic">Organism</rich_text><rich_text>, to indicate the healthy bacteria a person has in the body. But these property does not represent organs.
So what do we do? We'll define a new property, </rich_text><rich_text style="italic">organ</rich_text><rich_text>, and make the three existing properties be </rich_text><rich_text style="italic">sub-properties</rich_text><rich_text> of </rich_text><rich_text style="italic">organ</rich_text><rich_text>. Now we can get a list of organs by requesting a list of all property values of type </rich_text><rich_text style="italic">organ</rich_text><rich_text>. Every </rich_text><rich_text style="italic">heart</rich_text><rich_text>, </rich_text><rich_text style="italic">lung</rich_text><rich_text>, </rich_text><rich_text style="italic">eye</rich_text><rich_text> and any other organ we define is also an </rich_text><rich_text style="italic">organ</rich_text><rich_text>, because of the inheritance, so we'll get exactly the list we want.
Instead we could define a dummy class, </rich_text><rich_text style="italic">Organ</rich_text><rich_text>, and make it inherit </rich_text><rich_text style="italic">Organism</rich_text><rich_text>. But if </rich_text><rich_text style="italic">Organ</rich_text><rich_text> doesn't need any extra properties, it is recommended you use the suggested solution. Dummy classes add unnecessary clutter to the class hierarchy and complicate the model, which properties are simple type+meaning declarations. However, </rich_text><rich_text weight="heavy">this is a design issue</rich_text><rich_text>, and there's no one right thing to do. Sometimes a dummy class may convey better design. Hopefully other documents explain design topics, which this tutorial doesn't.
Let's see some code. Here's an example of class inheritance:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It'a also possible for a class to inherit more than one class:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide whether it's going to be possible to specify bases like this</rich_text><rich_text>:
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider doing something new with the colon. If bases are specified on the first line, it's easier to omit it or leave it by mistake, so maybe it should at least move to the end of the line</rich_text><rich_text>:
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION the second option (colon after bases) is currently the supported syntax</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">Or do something like this</rich_text><rich_text>:
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">pass</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> is not supported</rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Property bases are defined in a similar way:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider the same things as for classes (</rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">base</rich_text><rich_text foreground="#ffff00000000" weight="heavy"> params).</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently not supported, just like in classes</rich_text><rich_text>
In property inheritance, the derived property's type must be a subtype of the base's type, or be the same type. For example, if </rich_text><rich_text style="italic">base_prop</rich_text><rich_text>'s type is </rich_text><rich_text style="italic">text</rich_text><rich_text>, then </rich_text><rich_text style="italic">derived_prop</rich_text><rich_text>'s type must be text, or an enumeration of text values, or a union of text subtypes, etc.
Class inheritance passes the properties of the base to the derived class. What happens if classes B and C have a common base A, and there's a class D derived from B and C?
</rich_text><rich_text justification="left"></rich_text><rich_text>
This situation is called "the diamond problem". Does D have two copies of each property of A (one inherited from B and the other from C), or the copies are merged in D into a single instance of each?
Since properties have a specific meaning, there should not be two copies. In </rich_text><rich_text style="italic">Idan</rich_text><rich_text> the copies are merged, and D will have a single instance of each. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide finally, and think about allowing to have two copies, and whether it makes sense.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently a single copy, maybe later I'll add an option to change this behavior</rich_text><rich_text>
It's possible to have a name collision. Assume classes A and B are defined in different namespaces, and have properties with the same name. Now assume class C derives both. When we refer to the inherited property, how do we specify which property we refer to? The answer is: It's ambiguous and thus illegal to refer using the local name. The property name must be prefixed by the namespace. In the next sections we'll see how to do it.</rich_text><codebox char_offset="1552" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property Organism heart
property Organism lung
property Organism eye</codebox><codebox char_offset="1590" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person:
<1> heart $ Must have a heart
<1:2> lung $ Can donate one lung
<0:2> eye $ Can be blind, or have one eye, or have both</codebox><codebox char_offset="3174" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person
class Programmer base Person
class Designer: base Person
integer skill_level</codebox><codebox char_offset="3241" frame_height="114" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class A
class B
class C
class D base A, B, C
class E: base A, B, C
my_prop</codebox><codebox char_offset="3352" frame_height="170" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class A
class B
class C
class D:
base A, B, C
class E:
base A
base B, C
my_prop</codebox><codebox char_offset="3633" frame_height="114" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class A
class B
class C
class D base A, B, C
class E base A, B, C:
my_prop</codebox><codebox char_offset="3695" frame_height="132" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class A
class B
class C
class D base A, B, C:
pass
class E base A, B, C:
my_prop</codebox><codebox char_offset="3747" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property text a
property text b
property text c
property text d base a
property text e base a, b, c</codebox><codebox char_offset="4304" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class A
class B base A
class C base A
class D base B, C</codebox></node><node name="External References" prog_lang="custom-colors" readonly="False" tags="" unique_id="177"><rich_text scale="h2">Referring to Entities</rich_text><rich_text>
So far we've been writing definitions in a single file, single namespace. How do we refer to definitions from other namespaces?
References use three special characters:
• dot (.)
• hash (#)
• double-colon (::)
And as a reminder, these are the entity types:
• namespace
• type
• property
• class
• object
• graph
Before we can refer to a namespace, we must make sure it's </rich_text><rich_text weight="heavy">known</rich_text><rich_text> locally. Soon we'll see how to do that.
Once a namespace is known, all entities defined inside that namespace can be refered by prepending the namespace's local name, followed by a double-colon. For example, if we have a namespace called </rich_text><rich_text style="italic">Todo</rich_text><rich_text> and inside it a class called </rich_text><rich_text style="italic">Task</rich_text><rich_text>, we can refer to it as </rich_text><rich_text style="italic">Todo::Task</rich_text><rich_text>.
We can also refer to objects by prefixing the name with the class name, followed by #. For example, </rich_text><rich_text style="italic">Person#john_smith</rich_text><rich_text>. This also applies to graph object IDs which begin with a digit: </rich_text><rich_text style="italic">Task#1</rich_text><rich_text>. If the class is not in the local namespace, we prefix the class name with the namespace name, for example </rich_text><rich_text style="italic">Todo::Task#1</rich_text><rich_text>.
Properties and property values can also be refered by the class or object they belong to, respectively. We use the dot (.) character for that. For example, for a class </rich_text><rich_text style="italic">Person</rich_text><rich_text> with a property </rich_text><rich_text style="italic">name</rich_text><rich_text> we can write: </rich_text><rich_text style="italic">Person.name</rich_text><rich_text>. We can also refer to the value of </rich_text><rich_text style="italic">name</rich_text><rich_text> in a given object. For example: </rich_text><rich_text style="italic">john_smith.name</rich_text><rich_text>. If the object is not in the local namespace, we can refer to it as shown above. For example: </rich_text><rich_text style="italic">Person#john_smith.name</rich_text><rich_text>, </rich_text><rich_text style="italic">Todo::Task#1.content</rich_text><rich_text>.
This syntax can be used everywhere, when refering to entities:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h2">Making a Namespace Known</rich_text><rich_text>
All this works only if the external namespace is </rich_text><rich_text weight="heavy">known</rich_text><rich_text>. How do we make sure it's known? Namespaces can be divided intp three categories:
• Foreign namespaces
• Local namespaces
• Remote namespaces
</rich_text><rich_text weight="heavy">Foreign</rich_text><rich_text> namespaces are ones defined in other languages (not </rich_text><rich_text style="italic">Idan</rich_text><rich_text>) and require some special treatment. We'll talk about them in the Linking section.
</rich_text><rich_text weight="heavy">Local</rich_text><rich_text> namespaces are the ones recognized by the system and whose contents (i.e. definitions) are stored locally. There's no need to do any extra steps for them: If they are considered local by the system, they are considered to be </rich_text><rich_text weight="heavy">known</rich_text><rich_text> automatically. How namespaces are made local, is software-dependent. Your software may use a dedicated folder for all local definitions, or manage some database which points to them.
</rich_text><rich_text weight="heavy">Remote</rich_text><rich_text> namespaces are non-local namespaces defined in </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. It doesn't mean they are necessarily defined on a remote computer. It just means they're not in the local repository of definitions. These namespaces cannot be referred without making them </rich_text><rich_text weight="heavy">known</rich_text><rich_text> to the system first. It's done by adding the </rich_text><rich_text style="italic">include</rich_text><rich_text> parameter to the namespace declaration.
For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h2">Directly Importing Names</rich_text><rich_text>
It is also possible to import the names from a namespace into the local name dictionary. For example, refer to </rich_text><rich_text style="italic">People::john_smith</rich_text><rich_text> simply as </rich_text><rich_text style="italic">john_smith</rich_text><rich_text>, as if it was defined in the current namespace. It is useful when using many references to a namespace, but otherwise may result in name collisions, so use it with care. We import a namespace's contents into our current name resolution scope using the </rich_text><rich_text style="italic">using</rich_text><rich_text> parameter.
However, not all names are imported. </rich_text><rich_text weight="heavy">Only objects</rich_text><rich_text> are imported. Foe everything else you still have to use a namespace prefix. So </rich_text><rich_text style="italic">using</rich_text><rich_text> functions like </rich_text><rich_text style="italic">include</rich_text><rich_text> for non-object entities.
For example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h2">Using UIDs</rich_text><rich_text>
It's possible to refer to entities using their </rich_text><rich_text style="italic">uid</rich_text><rich_text>s. If an entity doesn't have a </rich_text><rich_text style="italic">uid</rich_text><rich_text>, naturally it can be referred only by its local name. If the </rich_text><rich_text style="italic">uid</rich_text><rich_text> is auto-generated, you need to get the generated uid before you can use it.
The following examples demonstrate the usage of </rich_text><rich_text style="italic">uid</rich_text><rich_text>s to refer to entities. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO consider adding some prefix character before </rich_text><rich_text foreground="#ffff00000000" style="italic" weight="heavy">uid</rich_text><rich_text foreground="#ffff00000000" weight="heavy">s, so there's never ambiguity with strings or local names.</rich_text><rich_text> </rich_text><rich_text foreground="#ffff00000000" weight="heavy">Maybe use <>.</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000">Let's see</rich_text><rich_text>. Using <> may cause issues, but only where <> is used in classes:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now let's use a </rich_text><rich_text style="italic">uid</rich_text><rich_text> with <>:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Before we discuss visual issues, does this syntax allow correct parsing? </rich_text><rich_text weight="heavy">Yes</rich_text><rich_text>. If a line contains only <>, it has to be a </rich_text><rich_text style="italic">uid</rich_text><rich_text>. If it contains just <> <>, it has to be a </rich_text><rich_text style="italic">uid</rich_text><rich_text> and a cardinality spec. If it also contains a property name, then the first <> is the type and the second is the spec.
WAIT A SECOND! If the line contains <> and then some name, there are two options:
1. spec and property
2. type uid and property
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO read about URI rules and see if there's a legitimate way to limit uids, e.g. can't start with : or digit</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION they currently cannot </rich_text><rich_text foreground="#3d3dc5c53d3d">end</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> with : and cannot contain spaces</rich_text><rich_text>
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO think of some other syntax, e.g. making [] or () not be used anywhere and assign it to UIDs</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION the %x syntax is chosen, see UIDs subpage</rich_text><rich_text>
In type definitions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In property definitions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In class definitions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In object definitions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In graphs:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="1546" frame_height="440" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">$ Types
type union {NameSpace::type_a, type_b} type_c
type enum {val_a, MyClass#my_obj} type_d
$ Properties
property NameSpace#my_type prop
$ Classes
class MyClass:
NameSpace::prop1
MyClass.prop2
$ Objects
object MyClass my_obj:
prop SomeClass#some_obj
prop2 some_obj.some_prop
$ Graphs
graph MyClass my_graph:
header prop1
child prop2
state prop3
/my_obj [SomeClass#some_obj] some_obj.some_prop</codebox><codebox char_offset="2707" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace:
uid http://my-name-space.org/
visibility public
include Todo http://namespaces.org/Todo/</codebox><codebox char_offset="3355" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace:
uid http://my-name-space.org/
visibility public
using Todo http://namespaces.org/Todo/</codebox><codebox char_offset="3876" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
my_type <3:7> my_prop1
<5:9> my_prop2
my_prop3</codebox><codebox char_offset="3909" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
<http://types.org/my_type/> <3:7> my_prop1
<5:9> <http://prop.org/my_prop2>
<http://prop.org/my_prop3></codebox><codebox char_offset="4684" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">type union {text, http://example.org/type} my_type</codebox><codebox char_offset="4713" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property http://example.org/type my_prop base http://example.org/prop
class MyClass:
http://example.org/type <3:7> my_prop</codebox><codebox char_offset="4739" frame_height="42" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass base http://example.org/class:
http://example.org/prop</codebox><codebox char_offset="4766" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object http://example.org/class my_obj:
http://example.org/prop1 11/07/2013
http://example.org/prop2 http://example.org/obj</codebox><codebox char_offset="4781" frame_height="186" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph http://example.org/class my_graph:
parent http://example.org/prop1
header http://example.org/prop2
state http://example.org/prop3
/0 [http://example.org/obj1] some text
http://example.org/prop4 21:17:00
/1 [http://example.org/obj2] more text
/2 [http://example.org/obj3] again text</codebox><node name="UIDs" prog_lang="custom-colors" readonly="False" tags="" unique_id="185"><rich_text>Suggested characters for surrounding UIDs:
"x"
'x'
<x>
(x)
[x]
{x}
|x|
%x
&x
!x
Some of these characters have problems:
"x" Already used for strings
'x' Too much like strings, may cause confusion
<x>
(x) Makes it look like background information
[x]
{x}
|x| Not widely-used character
%x May be hard to see without syntax hiliting
&x Same
!x Same
A standard URI must begin with a scheme, which must begin with a letter. So using % is fine. But before I decide to take %, I'd like to try freeing one of the bracket types. Currently the usage is:
<> for cardinality
() for range
[] for range and pattern
{} for union and enum
How can I free one of them? I can have range use only [], and choose some other way to specify []. For example, using &[ and ]& instead of (). Or something else, e.g. =[x]=, +[x]+, -[x]-, ![x]!, ~[x]~, ^[x]^.
Or I can leave (), and free [] for UIDs. Or use () for ranges, etc., use [] for cardinality and <> for UIDs.
Hmmm... not a simple decision. Keeping [] and () for ranges makes them more intuitive. </rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide!</rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">Let's try each option.</rich_text><rich_text> Currently this is correct syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
With the [x] syntax the result may be:
</rich_text><rich_text justification="left"></rich_text><rich_text>
With the %x approach, the result will be:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION: since most of the time UIDs aren't use, I prefer to preserve the convenience of (] and [) for ranges, so for now the %x syntax is supported, meaning that UIDs </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">must</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> start with a % everywhere except for their definition in the </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">uid</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> parameter of entity definitions.</rich_text><rich_text>
Also note that if a UID ends with a colon, there should be a space between the UID and the colon, like in the first line of the example above.</rich_text><codebox char_offset="1108" frame_height="350" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass base http://example.org/class :
prop1
my_type prop2
union {text, boolean} prop3
union {http://example.org/type_a, http://example.org/type_b} prop6
http://example.org/prop
http://example.org/type prop5
range integer [0, 100) prop7
<3:7> prop8
my_type <3:7> prop9
union {http://example.org/type a, http://example.org/type_b} <3:7> prop10
<3:7> http://example.org/prop
pattern ["abc"] propx
pattern ["abc"] <3:7> propy
http://example.org/type <3:7> prop11
range integer [0, 100) <3:7> prop13
object MyClass my_obj:
prop http://example.org/obj</codebox><codebox char_offset="1151" frame_height="350" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass base <http://example.org/class> :
prop1
my_type prop2
union {text, boolean} prop3
union {<http://example.org/type_a>, <http://example.org/type_b>} prop6
<http://example.org/prop>
<http://example.org/type> prop5
range integer +(0, 100) prop7
[3:7] prop8
my_type [3:7] prop9
union {<http://example.org/type_a>, <http://example.org/type_b>} [3:7] prop10
[3:7] <http://example.org/prop>
pattern ("abc") propx
pattern ("abc") [3:7] propy
<http://example.org/type> [3:7] prop11
range integer +(0, 100) [3:7] prop13
object MyClass my_obj:
prop <http://example.org/obj></codebox><codebox char_offset="1197" frame_height="350" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass base %http://example.org/class :
prop1
my_type prop2
union {text, boolean} prop3
union {%http://example.org/type_a, %http://example.org/type_b} prop6
%http://example.org/prop
%http://example.org/type prop5
range integer [0, 100) prop7
<3:7> prop8
my_type <3:7> prop9
union {%http://example.org/type_a, %http://example.org/type_b} <3:7> prop10
<3:7> %http://example.org/prop
pattern ["abc"] propx
pattern ["abc"] <3:7> propy
%http://example.org/type <3:7> prop11
range integer [0, 100) <3:7> prop13
object MyClass my_obj:
prop %http://example.org/obj</codebox></node></node><node name="Linking" prog_lang="custom-colors" readonly="False" tags="" unique_id="176"><rich_text scale="h2">Importing a Namespace</rich_text><rich_text>
Linking allows connecting </rich_text><rich_text style="italic">Idan</rich_text><rich_text> definitions with definitions made in other languages and systems, such as RDF. These definitions are called </rich_text><rich_text style="italic">foreign definitions</rich_text><rich_text> or </rich_text><rich_text style="italic">foreign entities</rich_text><rich_text>. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> allows linking in the following ways:
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO update, fix and finalize this list</rich_text><rich_text>
• have an Idan property which derives from a foreign property
• have an Idan property which matches a foreign property
• Have an Idan class which derives from a foreign class
• Have an Idan class which uses a foreign property
• Have an Idan class which matches to a foreign class
• Have an Idan object which has a property value that is a foreign object
Linking can be done using unique identifiers, or by introducing a foreign namespace. When using identifiers, they're specified just like </rich_text><rich_text style="italic">Idan</rich_text><rich_text> </rich_text><rich_text style="italic">uid</rich_text><rich_text>s. When using a foreign namespace, it needs to be introduced first, using the </rich_text><rich_text style="italic">import</rich_text><rich_text> property:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h2">Foreign Classes</rich_text><rich_text>
Two things can be done between classes: </rich_text><rich_text style="italic">basing</rich_text><rich_text> and </rich_text><rich_text style="italic">linking</rich_text><rich_text>. Basing is like inheritance, for example "every B is an A", and linking declares classes to be equivalanet, i.e. represent the same set. So it works like "every B is an A, and every A is a B".
Linking is done through the </rich_text><rich_text style="italic">link</rich_text><rich_text> parameter, and basing through </rich_text><rich_text style="italic">base</rich_text><rich_text>. But if an identifier is used, </rich_text><rich_text style="italic">base import</rich_text><rich_text> must be used:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text style="italic">base import</rich_text><rich_text> can be used with imported names too (first line of last example), but it's the same as </rich_text><rich_text style="italic">base</rich_text><rich_text> alone.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> itself has only one requirement: Linking and base-import must be done only with foreign classes. But other languages and systems may have requirements which make your definitions invalid. For example, ExtName::Person may have some required properties, and if your linked class doesn't define them too, you can't export objects to the other language/system.
It is up to you to define any required properties and link them to foreign properties as necessary. But as general advice, common formal models should probably be written and managed by experts, and users can ignore linking most of the time. </rich_text><rich_text style="italic">Idan</rich_text><rich_text> is meant to be easy to use when defining models on the fly, and linking only complicates things. Linking is an advanced feature, meant to be used mostly by technical people.
</rich_text><rich_text scale="h2">Foreign Properties</rich_text><rich_text>
Classes can't use foreign properties directly, but it's possible to link and base properties, like we did with classes. The type of the property in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> doesn't have to perfectly match the foreign property's type, but the values specified in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> must be valid in the target language/system, otherwise that system won't accept them.
The syntax is very similar to class linking:
</rich_text><rich_text justification="left"></rich_text><rich_text>
It's also possible to specify links when defining properties in-place:
</rich_text><rich_text justification="left"></rich_text><rich_text>
In </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, property inheritance hierarchies must not contain cycles. When linking is involed, you need to make sure you don't create such a cycle. Since the cycle involves both </rich_text><rich_text style="italic">Idan</rich_text><rich_text> and foreign definitions, it may be harder to detect and not all software will verify the hierarchy. So be careful.
</rich_text><rich_text scale="h2">Foreign Objects</rich_text><rich_text>
It's possible to refer to foreign objects when specifying property values. For a property whose type is an </rich_text><rich_text style="italic">Idan</rich_text><rich_text> class </rich_text><rich_text style="italic">A</rich_text><rich_text>, the legal values are:
• Objects of class A
• Objects of subclasses of A
• Objects of classes linked with A
The </rich_text><rich_text style="italic">import</rich_text><rich_text> keyword must be used when specifying an identifier. Here are examples which demonstrate the syntax:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Graphs objects support linking too. Properties values specified as </rich_text><rich_text style="italic">header</rich_text><rich_text> or </rich_text><rich_text style="italic">state</rich_text><rich_text> begin with </rich_text><rich_text style="italic">import</rich_text><rich_text> when an indentifier is specified. For example:
</rich_text><rich_text justification="left"></rich_text><codebox char_offset="883" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">namespace MyNameSpace:
uid http://my-name-space.org/
visibility public
import ExtName http://namespaces.org/foreign/ext/</codebox><codebox char_offset="1282" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class Person1 base ExtName::Person
class Person2 link ExtName::Person
class Person3 base import http://foreign.org/person/
class Person4 link http://foreign.org/person/</codebox><codebox char_offset="2582" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">property my_type prop1 base ExtName::prop
property my_type prop2 link ExtName::prop
property my_type prop3 base import http://foreign.org/prop/
property my_type prop4 link http://foreign.org/prop/</codebox><codebox char_offset="2657" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">class MyClass:
my_type prop1 base ExtName::prop
my_type prop2 link ExtName::prop
my_type prop3 base import http://foreign.org/prop/
my_type prop4 link http://foreign.org/prop/</codebox><codebox char_offset="3315" frame_height="60" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">object MyClass my_obj:
my_prop1 ExtName::jane_smith
my_prop2 import http://foreign.org/obj/</codebox><codebox char_offset="3467" frame_height="132" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="python" width_in_pixels="True">graph MyClass my_graph:
header prop1
state prop2
child prop3
/0 [ExtName::my_obj] ExtName::other_obj
/1 [import http://foreign.org/my_obj/] import http://foreign.org/other_obj/</codebox></node><node name="List of Special Characters" prog_lang="custom-colors" readonly="False" tags="" unique_id="178"><rich_text>digits 0-9
lowercase letters a-z
uppercase letters A-Z
colon :
double-colon ::
dot .
hash #
slash /
double-quote "
backslash \
curly brackets {}
angle brackets <>
square brackets []
parentheses ()
hyphen -
at sign @
S-with-vertical-bar $
underscore _
percent %
comma ,
all other unicode non-space characters</rich_text></node><node name="List of Keywords" prog_lang="custom-colors" readonly="False" tags="" unique_id="179"><rich_text foreground="#ffff00000000" weight="heavy">TODO decide whether it is legal to use these words as names or in unquoted strings, etc.</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION currently non-keywords are allowed but I need to choose which ones are considered keywords and which aren't, e.g. </rich_text><rich_text foreground="#3d3dc5c53d3d" style="italic" weight="heavy">text</rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy"> doesn't need to be a keyword</rich_text><rich_text> Maybe separate them into keywords and identifiers like in C++ (class, int, throw VS override, default, final).
</rich_text><rich_text foreground="#ffff00000000" weight="heavy">TODO decide which keywords can't be used in which situations</rich_text><rich_text> </rich_text><rich_text foreground="#3d3dc5c53d3d" weight="heavy">DECISION see below the list</rich_text><rich_text>
text
boolean
integer
real
date
time
language
namespace
type
property
class
object
graph
union
enum
range
pattern
visibility
date_order (not supported)
date_separator (not supported)
date_format
uid
include
import
using
header
state
child
parent
base
link
default
</rich_text><rich_text underline="single" weight="heavy">Usage limitation rules</rich_text><rich_text>:
All words may be used as values.
Some words may not be used as entity names.
In the list below, the </rich_text><rich_text style="italic">bold</rich_text><rich_text> words are the ones </rich_text><rich_text style="italic">not</rich_text><rich_text> allowed to be used as entity names:
</rich_text><rich_text weight="heavy">text</rich_text><rich_text>
</rich_text><rich_text weight="heavy">boolean</rich_text><rich_text>
</rich_text><rich_text weight="heavy">integer</rich_text><rich_text>
</rich_text><rich_text weight="heavy">real</rich_text><rich_text>
</rich_text><rich_text weight="heavy">date</rich_text><rich_text>
</rich_text><rich_text weight="heavy">time</rich_text><rich_text>
</rich_text><rich_text weight="heavy">language</rich_text><rich_text>
</rich_text><rich_text weight="heavy">namespace</rich_text><rich_text>
</rich_text><rich_text weight="heavy">type</rich_text><rich_text>
</rich_text><rich_text weight="heavy">property</rich_text><rich_text>
</rich_text><rich_text weight="heavy">class</rich_text><rich_text>
</rich_text><rich_text weight="heavy">object</rich_text><rich_text>
</rich_text><rich_text weight="heavy">graph</rich_text><rich_text>
</rich_text><rich_text weight="heavy">union</rich_text><rich_text>
</rich_text><rich_text weight="heavy">enum</rich_text><rich_text>
</rich_text><rich_text weight="heavy">range</rich_text><rich_text>
</rich_text><rich_text weight="heavy">pattern</rich_text><rich_text>
</rich_text><rich_text weight="heavy">alias</rich_text><rich_text>
visibility
date_order (not supported)
date_separator (not supported)
date_format
</rich_text><rich_text weight="heavy">uid</rich_text><rich_text>
</rich_text><rich_text weight="heavy">include</rich_text><rich_text>
</rich_text><rich_text weight="heavy">import</rich_text><rich_text>
</rich_text><rich_text weight="heavy">using</rich_text><rich_text>
header
state
child
parent
auto
</rich_text><rich_text weight="heavy">base</rich_text><rich_text>
</rich_text><rich_text weight="heavy">link</rich_text><rich_text>
</rich_text><rich_text weight="heavy">default</rich_text></node></node><node name="Todo" prog_lang="custom-colors" readonly="False" tags="" unique_id="181"><rich_text>This page will contain tasks for the next version of the tutorial, and ideas for language features:
[ ] Specifying disjoint sets (like in OWL)
[ ] Specifying inverse relations (S = R</rich_text><rich_text scale="sup">-1</rich_text><rich_text>)
[ ] Specifying implies (S ⊆ R</rich_text><rich_text scale="sup">-1</rich_text><rich_text>)
[ ] Giving URIs/IDs/references to "statements", i.e. object-property-value, like RDF Reification
[X] </rich_text><rich_text strikethrough="true">Full i18n: allow entity name not be in English, and even maybe use foreign keywords, i.e. מחלקה means </rich_text><rich_text strikethrough="true" style="italic">class</rich_text><rich_text>
[X] </rich_text><rich_text strikethrough="true">Make sure I add the ability to specify default values for properties (as already planned in early drafts)</rich_text><rich_text>
[ ] Start a project blog on Gitorious or NoBlogs (autistici), and report updates of the project there</rich_text></node><node name="Library" prog_lang="custom-colors" readonly="False" tags="" unique_id="186"><rich_text>Here I'm going to plan the C++ software library for working with </rich_text><rich_text style="italic">idan</rich_text><rich_text> files.
It doesn't have to be one big library! I can split it into several small ones. Anyway, let's make a list of use cases and functional requirements - what do we want our system to do?
I can split the functionality to several layers. Let's start with two layers:
1. Read a file into a structure and manipulate the structure, and save it to a file
2. Perform queries and high-level operations
Let's start with the low-level operations. I want to choose the structure first. Assume the program parses the file. How does it store the file in classes and objects? I'll try to make a class hierarchy.
Entity
Component
ModelComponent
Type
Property
Class
DataComponent
Object
Namespace
Graph
Abstraction idea: Do two stages of parsing! First just make a tree, then link references to actual objects, resolve UIDs, etc.
I'm adding a new file, a Dia diagram, in which I'll plan the classes and their methods and fields. I'll write here while planning there.
Three options for property model:
1. Static
2. Dynamic
3. Static fields accessible through dynamic interface
Static means I give each entity type fields, e.g. visibility and date_format for Namespace. The problem is that adding more parameters and implementing the entity-to-string functions will require manual changes every time I change the language.
The solution can be to use a dynamic map for "parameters", i.e. the entity traits. Like header, state, child, parent and auto for </rich_text><rich_text style="italic">graphs</rich_text><rich_text>. Then, adding one means just add an entry to the map. The parser and writer will automatically treat the new parameter.
The disadvantage is that the speed of direct acess is lost. This is why I looked at Qt code. It allows to define class data members, and then list them in the property map. So the dynamic access is just a wrapper, and static fast access is still possible.
TODO: The problem with Qt is its usage of ugly macros. The only convenient way to add a class member with dynamic access support, is by using a macro. </rich_text><rich_text underline="single">I want to look at GObject code too next time, and then decide which approach I'm going to take.</rich_text><rich_text>
Idea: I can use GObject directly, so I won't even need to implement the dynamic property system. On the other hand, not all class members are "parameters", so maybe using GObject for that is not good design. Maybe I should have my own parameter system, and even add macros if I need to (preferably not... we'll see next time).
19/07/2013
Okay, I looked at GObject info. It looks like properties are regular struct members, and property set/get functions just use a switch statement which sets the right field according to the chosen PROP enum value.
Now it's time to think. What can make changes difficult? Let's examine an obvious change: Adding a new parameter to one of my entity classes. I'll need to add it to the parser and to the writer.
Let's take the writer. How does the writer convert an entity into text? Assume it needs to convert a </rich_text><rich_text style="italic">namespace</rich_text><rich_text>. If parameters are static, the implementation just writes them one by one:
</rich_text><rich_text justification="left"></rich_text><rich_text>
So if I add a new parameter, I need to add it as a class field and update the writer to use it.
What about the reader? How does it work? It takes the block describing the entity and analyzes it line by line. If it reaches a parameter, it treats it as such, otherwise it's something else. Currently there's no ambiguity:
• namespaces: only parameters
• types: only parameters (uid)
• properties: only parameters (uid, base, link)
• classes: the only parameter is uid, everything else is properties
• objects: the only parameter is uid, everything else is property values
• graphs: all non-parameters begin with a /, or are properties and specified under an object
• graph objects: like regular objects
The only parameter which may cause ambiguity is </rich_text><rich_text style="italic">uid</rich_text><rich_text> currently. But it may easily change, e.g. if I make </rich_text><rich_text style="italic">base</rich_text><rich_text> and </rich_text><rich_text style="italic">link</rich_text><rich_text> parameters like I planned.
If the reader code checks for </rich_text><rich_text style="italic">uid</rich_text><rich_text> manually, I'll have to manually add each new parameter.
In order to make the system more general-purpose and easier to change, I'd like parameters to be dynamic. It means each entity has a list of them, and it matches its findings against the list. When the reader parses the generated document model, I can also make it automatically update the right static values by giving it setter functions. And I can implement a callback method, like a SAX parser. Then the document model can rely on that, i.e. the SAX-like method will be the most low-level parsing interface.
It's hard to plan like that, without seeing some code. I'll start by using static parameters, and then I'll change what's necessary and add the parameter hashtables.
No... wait a second. The first parsing stage is to get the syntactic structure, ignoring the meaning. So right now I can't use specific fields. It has to be dynamic.
Let's make a list of line types:
namespace: only parameter-value lines
type: only uid-value line
property: only uid-value line
class: uid-value and property lines
object: uid-value and property-value lines
graph: parameter-value lines, object lines and their own lines
Objects and graphs are the only entities capable of listing something that is not a parameter. But in practice, object property values are somewhat like parameters. Graphs don't work like that, but graphs are also not real entities.
Since classes and graphs and syntax unique to </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, I think I'll abandon the general-purpose approach. Bison and Flex probably already do the job for general-purpose parsing. I may start using them in the near future, but for now I'll use my own code.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Instead of using plain name-value parameters, I'll use a class hierarchy of them! Then a subclass can implement the specifics of class properties: cardinality spec, default values, etc. Perfect! I'm going back to the diagram... actually I'll make a new one.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Since the basic parsing operation relies on much weaker rules than </rich_text><rich_text style="italic">Idan</rich_text><rich_text>'s, I can give these rules their own name and their own software library, and let libidan use it! Hmmm... but how do I call it? Let's check my name list...
I chose a working title. Unless I decide otherwise later, currently the name of the lowest level document interface is </rich_text><rich_text style="italic">Frelsi</rich_text><rich_text>, which means </rich_text><rich_text style="italic">freedom</rich_text><rich_text> in Icelandic.
Now let's make a new diagram for it...</rich_text><codebox char_offset="3106" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">write_name ();
write_uid ();
write_visibility ();
write_date_format ();</codebox><node name="Frelsi" prog_lang="custom-colors" readonly="False" tags="" unique_id="187"><rich_text>Frelsi is a library which deals with files containing definitions of the following form:
[type] [name]:
[param] [value]
[param] [value]
But with extended syntax, i.e. this example is a simplification of the actual way it works.
The first thing we need to do is define how Frelsi languages are defined. In other words, how do I tell Frelsi what kind of language I use? This definition is done using Notions.
A </rich_text><rich_text style="italic">notion</rich_text><rich_text> is a language model concept. For example, in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> the notions are namespace, type, property, class, object and graph. And language can be made a notion too. The </rich_text><rich_text style="italic">Frelsi::Notion</rich_text><rich_text> class allows us to create and define notions.
Each notion definition begins with a </rich_text><rich_text style="italic">header</rich_text><rich_text>. These are some header examples:
language he_IL
namespace Todo
namespace Todo:
type union {text, date} my_type
type union {text, date} my_type:
property text name
property text name:
property union {text, date} name
property union {text, date} name:
property text name base a, b, c
property text name base a, b, c:
property union {text, date} name base a, b, c
property union {text, date} name base a, b, c:
class MyClass
class MyClass:
class MyClass base a, b link c, d
class MyClass base a, b link c, d:
object MyClass my_obj
object MyClass my_obj:
graph MyClass my_graph:
/x
/x hello world
/x [X]
/x [X] hello world
So which components are placed in headers?
• notion name
• entity name
• definition
• parameters
• colon
Let's analyze the headers:
language he_IL [notion] [entity]
namespace Todo [notion] [entity]
namespace Todo: [notion] [entity] [colon]
type union {text, date} my_type [notion] [definition] [entity]
type union {text, date} my_type: [notion] [definition] [entity] [colon]
property text name [notion] [parameter] [entity]
property text name: [notion] [parameter] [entity] [colon]
property union {text, date} name [notion] [parameter: definition] [entity]
property union {text, date} name: [notion] [parameter: definition] [entity] [colon]
property text name base a, b, c [notion] [parameter] [entity] [parameter]
property text name base a, b, c: [notion] [parameter] [entity] [parameter] [colon]
property union {text, date} name base a, b, c [notion] [parameter: definition] [entity] [parameter]
property union {text, date} name base a, b, c: [notion] [parameter: definition] [entity] [parameter] [colon]
class MyClass [notion] [entity]
class MyClass: [notion] [entity] [colon]
class MyClass base a, b link c, d [notion] [entity] [parameter]
class MyClass base a, b link c, d: [notion] [entity] [parameter] [colon]
object MyClass my_obj [notion] [parameter] [entity]
object MyClass my_obj: [notion] [parameter] [entity] [colon]
graph MyClass my_graph: [notion] [parameter] [entity] [colon]
/x [entity]
/x hello world [entity] [parameter]
/x [X] [entity] [parameter]
/x [X] hello world [entity] [parameter] [colon]
What about parameters? What do they look like?
param value
prop
text prop
text prop default "hello"
union {text, date} prop
union {text, date} prop default "hello"
<3:7> prop
text <3:7> prop
text <3:7> prop default "hello"
union {text, date} <3:7> prop
union {text, date} <3:7> prop default "hello"
So what types of "components" can we have on a single line?
token (no spaces, no tabs)
word (only letters of any alphabet, digits of any alphabet and underscores)
string (follows </rich_text><rich_text style="italic">Idan</rich_text><rich_text>'s definition of </rich_text><rich_text style="italic">text</rich_text><rich_text> type, and must be surrounded with double quotes)
curly bracket block
angle bracket block
parentheses block
square braket block
mixed bracket block
comma-separates components
colon-separated components
mix-separated components
Before I proceed, I'd like to take a look at Bison. Instead of reinventing the wheel, I can use Bison to parse the file and convert the resulting tree into </rich_text><rich_text style="italic">Idan</rich_text><rich_text>'s data structures. And then maybe I won't need Frelsi at all.
Hmmm... reading the Bison manual. I checked what CPython does, and found out it uses its own parser implementation. This piece is copied from python.org:
</rich_text><rich_text foreground="#aeaecdcd3b3b">Historically (through 2.4), compilation from source code to bytecode involved two steps:
1. Parse the source code into a parse tree (Parser/pgen.c)
2. Emit bytecode based on the parse tree (Python/compile.c)
Historically, this is not how a standard compiler works. The usual steps for compilation are:
1. Parse source code into a parse tree (Parser/pgen.c)
2. Transform parse tree into an Abstract Syntax Tree (Python/ast.c)
3. Transform AST into a Control Flow Graph (Python/compile.c)
4. Emit bytecode based on the Control Flow Graph (Python/compile.c)</rich_text><rich_text>
Since I'm not an expert right now, and some academic documents refered by that page are not free (sold on Amazon), I'll find my shortcut to get where I want.
In order to make things flexible, I'll continue working with Frelsi and developing a parser, but at the same time I'll be reading the Bison manual and I'll consider using Bison directly, or making Frelsi a simple frontend which uses Bison.
The process would basically work like this:
1. Tokenize the input file, using a scanner generated by Flex
2. Parse the token stream using Bison, converting the stream into a syntax tree
3. Convert the syntax tree into a Frelsi document
4. Convert the Frelsi document into </rich_text><rich_text style="italic">Idan</rich_text><rich_text>'s structure
So I can use Frelsi even if I use Flex and Bison.
</rich_text><rich_text weight="heavy">QUESTION</rich_text><rich_text>: Can I do this without Flex and Bison? Start with a super-simple analyzer? It may save time by getting initial results faster (and give me some experience too).
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Yes, I'll start without them.</rich_text><node name="Tokenizer" prog_lang="custom-colors" readonly="False" tags="" unique_id="188"><rich_text>In Bison, the lexical analyzer is called every time the parser wants to read a token. I'll try to make it possible here too.
The job of the tokenizer is to create tokens out of the input file. Since I'm not using Flex, there's no need to reinvent the wheel and make a general purpose tokenizer. I'm going to write a tokenizer for Frelsi.
The tokenizer will simply split the text into small chunks, using a simple set of rules. It will create a token for each chunk, assign values where necessary and return the results.
I'll try to define rules here. Assume we begin on a new line.
token types:
1 Count spaces and tabs at the beginning of the line, and produce a single space token with that number stored too
2 Take a character
2.1 If it's $, make the rest of the line a comment, make a newline and go back to the stage 1 for the next line
2.2 If it's ", find the next " not preceded by \, then add all \s following the " and make it a string token
2.3 If it's another special character, make a token for it
2.4 If it's a character not supported (e.g. +, &, ^)
Wait a second! It's not clear exactly how deep we need to go here. Should we idenfity comments and strings? Should we create some kind of tree which considers opening and closing brackets?
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: The analyzer will not make any smart moves. If it finds a $, it just continues analyzing the code. When the parser gets a $ token, it can request the analyzer to skip to the end of the line, and get the result as a single token. But it only happens because the parser says, not any other reason. Same for strings.
Let's start again.
1 Make a single indentation token from all the tabs and spaces at the beginning of the line.
2 Take a character
2.0 If it's a space or a tab, skip it and keep going
2.1 If it's a :, check if the next character is :: and make a single token
2.2 If it's a single : or another symbol/mark, make a token from it
2.3 If it's some unicode control character, raise a warning
2.4 If it's a letter/digit/underscore, keep going through digits/letters/underscores and make the word a token
2.5 If it's a newline, make a token and go back to stage 1
This will probably work, but Flex seems to offer more. I mean, it can get the output much closer to what I offer. Maybe I should work the same way. Flex is capable of matching regular expressions, which means it will be able to match comments and quoted strings, something my code doesn't do. Hmmm... maybe I should use Flex anyway?
Before I decide, I'd like to try to make a list of tokens. I don't know much about regular expressions, but I'll use the examples Flex provides. Later I'll read about regexps.
Hmmm... or not? Hmmm... no. I'll start without Flex. I want to make sure things work first. Let's write new rules which take comments and strings into account.
Character classes:
space
tab
letter
digit
legal symbol
newline
invisible control character
1 Make a single token from the tabs and spaces
2 Take a character
2.1 If it's a ", interpret it according to </rich_text><rich_text style="italic">Idan</rich_text><rich_text> string rules
2.2 If it's a $, take the rest of the line as comment
2.3 If it's a : followed by :, take is as a single :: token
2.4 If it's a space or a tab, skip it
2.5 If it's another legal symbol, make it a token and continue
2.6 If it's a letter, digit, underscore or mark, make all these a single token
2.x If it's a newline, make it a token and go back to step 1
2.y Otherwise, report an warning (for invisible character) or an error (for a visible one)
Okay. Let's try it, shall we?
First, let's see how we're going to model the token stream. I'm adding a token class hierarchy to the diagram.
Good. Now, how does the tokenizer work? The process needs to be hard-coded. Not the best reusability and not the best flexibility, but that's what I'm going to use for now. I'm going to write a tokenizer class which can take a:
- filename
- stream
- string
and get the tokens one by one. Since it's unicode, maybe it's a good idea to use Glib's file access routines. On the other hand I can enjoy C++11 features if I use regular interfaces. Actually I don't have to use Glib if I find a way to get the next UTF-8 string from the given string position. Otherwise I guess I'll use glibmm, not a big issue anyway.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Create a simple class which just returns tokens, and then create a higher level tokenizer which calls virtual methods for specific types and can be overriden, like the xmlpp::SaxParser.
Great. What about the writer? How does the writer work? Hmmm... huh? Who said I'm working on a writer? Let's ignore it for now, because files can be written by hand. No writer for now. I've prepared a simplified interface idea, since for now I don't use the writer.
Tomorrow I'll add the build files. For now I just want to start writing some code. And read about streams. Anyway, let's get started! </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: make a token stream class, like C++ streams.
Report: After looking at glibmm and C++ I/O it seems there's no way to read UTF-8 character by character. I can do a trick and read 4 characters every time, then remove the first character and read again to complete to 4. But instead I can save trouble and read whole lines. As a result, it doesn't make much difference which interface I use. So I'm taking the standard C++ I/O interface.
I prepared the classes and files. </rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: start writing the code. I'll probably need a char-to-symbol unordered map, which will be a static private member of the TokenReader class. Also consider changing things a bit so that UIDs are supported, e.g. taking names beginning with % as UIDs. But try to make it dynamic, i.e. not tie UIDs to % if possible. Consider the legal characters for UIDs, which are more than what "words" can have. I'll probably need another text type, or change word to accept UIDs.guni
Types of non-space phrases:
* Language word, possibly not in English
* Entity identifier
* UID
* Quoted string
* Comment
</rich_text><rich_text underline="single" weight="heavy">UPDATE</rich_text><rich_text>: I realized it's not going to be so simple. Considering how UTF-8 is involved, it's better I use a professional tool. I also should learn much more about Unicode, but I want to get things to work before that. I decided to try to use Quex, an LGPL lexer hosted on SourceForge, which supports Unicode.
Hmmm... I looked at Glib's gunicode.h function implementations too, and they're quite complicated. I mean, the functions are short, but they use unicode code point ranges generated by combining a chartable and convenience macros. The chartable is generated by a perl script.
I can just use Quex, but I still need to somehow determine the ranges, don't I? I have an easy solution: Skip the i18n feature for now. Simple, isn't it? Just use English. Ignore the </rich_text><rich_text style="italic">language</rich_text><rich_text> specified in the file! Now I can easily write my own code, and easily use Flex and Bison. Let's start...
Wait. Why not use Quex anyway? This way I'll get used to it, won't I? </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Yes, but I'll start with Flex and Bison because they're widely used. Then I'll be prepared to use Quex.
I looked at the examples which come with Quex's source code, and they look pretty easy. Flex is supposed to work in a simiar way, so I guess I'll be fine. But... there's another issue I need to decide on.
In Flex/Quex, you directly specify all the tokens you want to have. For example, for C++ you'd specify tokens for "class", "template", "auto", etc. The language keywords, directly. If I do that, I won't be able to customize the language programatically. I'll need to edit the Flex input file by hand.
On the other hand, why not? What's wrong with editing it by hand? When it comes to language keywords, there's no problem. The other way is to have the leywords defined in another file, and automatically inserted into the input file. But then I need to manually change them in the file where they're defined... so what's the difference?
Well, it doesn't really make difference. But... oh, wait. Here it is. If I need to define new names for keywords, I can edit the input file. But what if I want to avoid choosing keywords? For example, what if I want my system to support a user-defined set of notions, which doesn't have to match my 6 notions in </rich_text><rich_text style="italic">Idan</rich_text><rich_text>? You could say, just let the user edit by hand.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Define a simple Frelsi input file syntax, in which the user defines notions and other things, and a program which generates the Bison and Flex input files from the Frelsi input file! But should this program be Frelsi itself? Or Frelsi will be a library? Let's write the whole process from input to on-memory </rich_text><rich_text style="italic">Idan</rich_text><rich_text> model. I'm creating a new diagram for that (my first flowchart in Dia).
Good. </rich_text><rich_text underline="single" weight="heavy">Now</rich_text><rich_text>, before I can assign tasks to software components, I need to read about parse trees and syntax trees. What exactly are they? What do they look like? How is Bison typically used when generating a parse tree from source code of some new language?
Then I'll need to plan how the generation of Flex and Bison output works with the autotools. Should it happen in autogen.sh (i.e. it's just a shell script) or integrated with automake by adding a target to automake which runs flex and bison? I should look at their manuals, and see what othe programs do, e.g. how Glib's unicode table Perl script is run. Or something else, since that script probably rarely needs to run.
21/07/2013
I read about parse trees and ASTs. A parse tree is a concrete syntax tree, generated by a parser for a specific language. The AST is abstract, i.e. doesn't contain the specific grammar details. For example, an "if... else" block can become a node with two paths to other nodes in the AST (one for the "if (true)" part, and the other for the "else" part). So the AST describes the syntactic structure of the program, without the technical details of the language: delimiters, keywords, forward declarations, etc.
Which trees do I need?
My system is somewhat different from how programming languages work. This is the process with programming languages:
Tokenize the input into tokens (according to language keywords and symbols)
Parse tokens into a parse tree (according to language constructs)
Transform parse tree into an Abstract Syntax Tree (generate general syntax representation)
Transform AST into a Control Flow Graph
Emit bytecode based on the Control Flow Graph
In my system it's different. First of all, I can't use specific language keywords because the language can be translated. One of the implications is that I cannot feed Flex with keywords for a specific language, because the generated parser will be able to parse only that language. The process is not supposed to depend on the language. Hmmm... how do I feed Flex dynamically?
You know what? I have a better idea. For now I'll ignore the dynamics, and by the time I add i18n, I'll know Flex well enough to plan a solution.
So here's my process:
Tokenize the input into tokens (according to specific language keywords and Frelsi symbols)
Parse tokens into a parse tree (according to Frelsi constructs)
Transform parse tree into a Document Model (according to language constructs)
Actually it's best not to use specific keywords, because it allows ignoring the specific language until the Document Model stage. On the other hand, it means errors are detected at a later stage and possibly harder to detect and to find bugs.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: I'll start by writing a Flex input file specifically for </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, without i18n support, and later I'll "upgrade". The static Flex input will be enough to get a working parser, which is what I need in order to get going. Develop an interface, GUI widgets, etc.
Wait... wait a second. Most of </rich_text><rich_text style="italic">Idan</rich_text><rich_text> code is not even recursive. Without graphs, I don't need a parser at all. A scanner may be enough. Actually, not using Flex at all can make my life much much easier! </rich_text><rich_text style="italic">Idan</rich_text><rich_text> is a simple language. I can write code for it without Flex and Bison (although it's a good idea to use them anyway for practice).
Let's go back to Frelsi. How is it going to read a Frelsi file? Reminder: files are made of chunks like this:
[type] [name] :
[param] [value]
[param] [value]
Hmmm... how do I let the user specify the pattern for param values? Good question. It will have to be something similar to regex. But then we go back to Flex again...
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Forget Frelsi for now. Forget the "family of languages". Write by hand a parser for </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, and later change the inner workings while the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> interface remains the same.</rich_text></node></node><node name="New Plan" prog_lang="custom-colors" readonly="False" tags="" unique_id="189"><rich_text>21/0702013
Alright. I decided to write by hand a specific parser for </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. The process is going to be like this:
1. Build a parse tree
2. Build document model
Hopefully it will be simple. Let's start. I'm going back to the model diagram.
I want to try to define an interface which allows the user to specify the specific syntax of the language. First, the user needs to be able to define all the possible constructs. Everything looks like this:
[notion] :
[param]
So the user needs to define all the possible notions, and all possible parameters. Working on a diagram...
Done with most of the language spec interface. Currently, the spec does </rich_text><rich_text weight="heavy">not</rich_text><rich_text> generate a static parser. Actually, it makes me wonder how good the static parser actually is. I mean, it's a simple script language. It may be good enough and fast enough to read a spec in real-time and only then generate a concrete syntax tree.
I began drawing a flowchart diagram describing the parsing process. I realized the take-all-options-in-paralle works like the GLR parser. A GLR parser works in O(n^3) worst case, but most languages are at least "nearly deterministic" so most of the time only one stack is active, and the result is O(n).
But a major optimization is using a common prefix or suffix to the tree branches, so the tree becomes a DAG. This may be a good place to make use of the Arbre::Graph which I already wrote.
The Wikipedia article doesn't link to more online free material, but I found material on the web. I won't try to use the formal algorithms because I don't use formal language specs, and if I did, I could use Bison's GLR parser directly. Since I don't use Bison right now, I'll try to write my own code and see what happens.
Assume I parse linearly. I have just one notion, and a single parameter spec. Then all I need to do is read entities in order, and parse the parameters. If I fail, I report an error, otherwise I end up with a linear list of entities.
But what if it's not linear? I have a list of blocks, and each block has several optional parameter specs. Same for the notions themselves. I'm going to have several "fronts". Let's ignore optimization for now and treat it like a tree.
At the beginning there's nothing. I go to the first notion and make sure it's a valid notion. Now I need to match blocks. So I go over all the blocks until the first required block, included. These are the only blocks with which the code may begin.
For each such block, I check the notions it may contain. Blocks which can't contain the notion I found are dropped, and what remains is the blocks which may contain it. So I can build a tree/graph just for the blocks, since they don't affect the language entities.
Wait a second... I can simplify things by making more block rules. For example, in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> blocks are disjoint. The first can contain only a namespace, and the second may contain anything but a namespace. Is it safe to make this limitation? What if in some other language it makes sense to use the same notion in different blocks?
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Don't run away from complexity. So what? It's a little difficult. Run away? Don't be a coward. Attack your weaknesses! Train your skills. Learn. Improve.
Yes, I'm going to support joint blocks. How? Imagine blocks A and B may both contain notion N, and disjoint notions A1, A2, A3... for A and B1, B2, B3... for B. Now imagine the script begins with a mixture of Ai-s and N. Then comes some Aj and after that some Bk. Then clearly Aj is the last entity in block A, and Bk begins block B. No ambiguity.
But now assume the order is: Aj, N, Bk. Clearly Bk belongs to block B, but where does N belong to? Block A or block B? This problem is solved by my algorithm by providing language settings.
There are two settings for that:
* Block delimiter
* Ending mode
The block delimiter is a string which may appear unindented, alone (possibly a comment follows), and marks block separation. If set, then block separation is unambiguous. Ending mode is used when there's no delimiter: If it's set to end_early, a block ends as soon as possible, otherwise it ends as late as possible.
For example, in the sequence Aj N Bk, end_early means A[Aj] B[N Bk] while end_late means A[Aj N] B[Bk]. If some "middle" option is desired, use a block delimiter. It may also make sense to use some more sophisticated method to determine a "middle" setting, but until I see a use-case I won't support it.
So... how do we build a block graph? And is it really a DAG, or a simple tree/list is enough? What I really want to know is </rich_text><rich_text weight="heavy">where each block begins</rich_text><rich_text>. So here's a suggestion: Store the minimal and maximal range for each block. Then gradually reduce them, until we reach the best match when we're done parsing. Then use the Ending Mode setting to choose the actual markers.
Assume we store an array for blocks, and a (min, max) value for each block. Let's initialize the array. In general, in we have </rich_text><rich_text style="italic">n</rich_text><rich_text> blocks, then the minimal position is 0 (not exist) and the maximal is </rich_text><rich_text style="italic">n</rich_text><rich_text> (when they all exist). Graphically it looks like this:
1 0............ n
2 0............ n
...
n 0............ n
Now assume some of the blocks are required. For a number m, 0 <= m <= n, m out of the n blocks are required. Let's mark these blocks with R1... Rm. How does it affect our array? Example: All the blocks before Rm have max=n-1 because </rich_text><rich_text style="italic">n</rich_text><rich_text> would be taken by Rm. So everything before Rm-1 has max=n-2, and so on. The result is:
1 0.............. n-m
...
R1 0.............. n-m+1
...
x 1.............. n-m+1
...
R2 1.............. n-m+2
...
y 2.............. n-m+2
...
z m-1............ n-2
...
Rm-1 m-1............ n-1
...
w m.............. n-1
...
Rm m.............. n
...
u m+1............ n
...
When we start, we don't know how many entities we're going to have (thus max is unknown) but we know how many required blocks we have.
How to further limit the values? When we take the first notion, we find all the blocks in [1, R1] which may have this notion. All blocks before the first matching one are marked as "not exist". Then we make a list S1... Sk of these possible start blocks.
Sk is the last possible start block, which means that if any Si exists, then we have a "required" block before R1. Assume we have k=1:
1 0.............. n-m
...
S1 1.............. n-m
...
R1 2.............. n-m+1
...
x 2.............. n-m+1
...
R2 2.............. n-m+2
...
y 3.............. n-m+2
...
z m............ n-2
...
Rm-1 m............ n-1
...
w m+1............ n-1
...
Rm m+1............ n
...
u m+2............ n
...
Wait a second. This is becoming too confusing. I need a better view of this. Let's try a naive approach first, and then proceed to something more efficient.
</rich_text><rich_text underline="single">Goal</rich_text><rich_text>: Decide where block Ai ends and Ai+1 starts, for each relevant i.
</rich_text><rich_text underline="single">Method</rich_text><rich_text>:
Wait a second... I think it can work. I can use the method I tried above. Next time I'll continue with it.
22/07/2013
I decided to skip the blocks for now. Assume we have just a single block which can contain all notion types. What do we do now?
Clearly the notions go in a line. We start reading them one by one, and make a list of them. No problem. But now we need to read the parameter blocks inside! It's more or less like the blocks.
What does the parser create? I'm adding the Parse Tree classes to the diagram.
Hmmm... maybe use another namespace? Yes. I want to use classes like Slice to represent both the slice spec (which numbers are supported, whether infinity is supported, whether omiting one side is supported, etc.). So I'd like to split Frelsi into three namespaces:
1. Language definition classes
2. Parse Tree classes
3. The rest: the Frelsi file reader (and Language generator), Parser and other misc
The three namespaces I'm going to use are:
Sprak (from "language" in Norwegian)
Strom ("tree" in Czech)
Frelsi
There's a problem. Assume I create several tokens. Then I want to create phrases which use them. How do I do that? If I use pointers directly, I'll have to have the addresses accessible. I have new thoughts.
Currently, the Language object has sets of Parts, Parameters and Parameter Blocks. But in practice, it never even uses these sets! It goes to notion definitions, which have pointers to the parameters. What does the parser really need? Just a list of parameter blocks. Currently phrases have pointers to tokens, and parameters have pointers to parts, so </rich_text><rich_text style="italic">someone</rich_text><rich_text> needs to manage their memory. In the lowest level, the user manages the memory, i.e. the user creates all the tokens and other things. But why not embed memory management in the base system?
A way to keep memory managed can be to use shared pointers everywhere. Then the user passes shared pointers to the system, and doesn't need to worry anymore. Another option can be to create objects through methods, and receive pointers back. But this is a problem because Language needs to be aware of all the token types.
Another </rich_text><rich_text weight="heavy">cool</rich_text><rich_text> idea: Use inheritance! Instead of modeling each language as an </rich_text><rich_text style="italic">object,</rich_text><rich_text> make it a </rich_text><rich_text style="italic">class</rich_text><rich_text>. It's like when you create derived widgets in gtkmm. Well, not exactly the same... it doesn't make sense to create more than one object for a specific language class.
Nah. Don't do that.
Hmmm... if phrases hold their tokens, they won't be shared. But if they hold pointers, someone else will have to manage their memory. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Start with shared pointers, then we'll see.
Hold on... I think I have a better idea. This kind of software is going to require some time to write... maybe I should concentrate on </rich_text><rich_text style="italic">Idan</rich_text><rich_text> and </rich_text><rich_text style="italic">Partager</rich_text><rich_text> first, then go back here. Agreed? Yes!
Now the question is: Do I use Flex/Quex and Bison? Or I write my own parser? Hmmm... I'd like to try to write my own simple </rich_text><rich_text style="italic">Idan</rich_text><rich_text> parser first, then maybe move to Flex. Let's start.</rich_text></node><node name="Idan Parser" prog_lang="custom-colors" readonly="False" tags="" unique_id="190"><rich_text scale="h1">22/07/2013</rich_text><rich_text>
So I'm going to try writing my own </rich_text><rich_text style="italic">Idan</rich_text><rich_text> parser by hand. Before I start, I'd like to write the language rules, using informal grammar (I have no idea how to write BNF, or whatever they call that formal language).
NOTION_CHAR := a character legal for use in a notion name
NOTION_NAME := NOTION_CHAR+
DIGIT := one of the legal digits (possibly not western ones, e.g. in Arabic)
SQ_STRING_CHAR := any character legal in a 'string', i.e. anything but ' and newline
SQ_ESCAPE := \'
DQ_STRING_CHAR := any character legal in a "string", i.e. anything but " and newline
DQ_ESCAPE := \"
STRING_SUFFIX := \+ i.e. at least one backslash
Nah, forget it. I'm not going to use these things in my hand-written parse. I just need to have a list of the rules. Let's make it simple, shall we? I can even make it brute-force by reading the whole file, splitting into notions and reading each one in turn. What do you say? Yes. Let's do it. It's easy, you see? I'll have a working system fast and early.
First I'm completing the document model diagram...
I'm going to work in two stages. In the first stage the parser just creates a parse tree. In this tree entities are not connected, so it's really a tree. For example, objects don't point to their class. They just have a string containing the class name. Graphs exist, although they don't represent actual data.
In the second stage the document model is transformed into a model you can easily work with.
I want to write them separately. Both basically should be parts of </rich_text><rich_text style="italic">libidan</rich_text><rich_text>, otherwise what exactly will it contain? Hmmm... let's write the goals.
What I want my software to do:
* Read an </rich_text><rich_text style="italic">Idan</rich_text><rich_text> file and generate an in-memory model
* Take an in-memory model and write it into a file
* Perform queries on the model
</rich_text><rich_text style="italic">libidan</rich_text><rich_text> should basically do these things. Or at least the first two things. </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: I'll have separate components for the parser and </rich_text><rich_text style="italic">Idan</rich_text><rich_text> models, and </rich_text><rich_text style="italic">libidan</rich_text><rich_text> will be in charge of the algorithms. Let's try it, and see what happens.
I need two trees here: Parse tree and Entity Model. Again I need names for the components... Should I use the same names I already have? I mean, if I really use those components eventually, will I still need what I'm writing right now? Maybe I will. Let's find new names.
Cist from "read" in Czech
Alder from "age" (as in עידן) in swedish, icelandic and several others
Okay, done creating repos. Now I need to create parse tree classes in Cist, which are specific to </rich_text><rich_text style="italic">Idan</rich_text><rich_text>.
</rich_text><rich_text weight="heavy">QUESTION</rich_text><rich_text>: How deep does Cist go? I mean, it's not clear. Some features are perfectly read by Cist and can be copied into Alder, but others are not. What </rich_text><rich_text style="italic">exactly</rich_text><rich_text> is Cist supposed to do? Hmmm... after reading a bit in Wikipedia, I'm still not sure... let's look at some code...
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Wait a second... hmmm... I have a cool idea. XML is a language, but it defines only structure, not data. Exactly in the same way, Frelsi is a language but </rich_text><rich_text style="italic">Idan</rich_text><rich_text> adds meanings and more rules to the structures.
What I was doing until now, was to take the specific language details and parse accordingly. Instead, why not parse the whole thing first? This way I won't even need Bison and Flex for each Frelsi language. I'll need them once for Frelsi itself, and that's all. Hmmm... worth trying. Or... hmmm... I'm not sure it will work. XML has a beter structure. I mean, you can parse the whole thing. In Frelsi, things like slash-prefixed graph objects aren't known until you define </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. So how can the Frelsi parser know whether the slash begins a resource, an identifier or something totally different?
These are good questions. It's still hard to tell things, because I don't know how </rich_text><rich_text style="italic">Idan</rich_text><rich_text> will be used by people. Actually, I don't even see any reason to create other languages. Any model can be described in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> directly. Instead of inventing entity types and choosing parameters, you can define classes and choose properties. This is much much easier. Then you can define objects as much as you want.
For now, I'll ignore Frelsi generic syntax and focus on </rich_text><rich_text style="italic">Idan</rich_text><rich_text>'s specific rules.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: The difference between Cist and Alder is </rich_text><rich_text weight="heavy">linking</rich_text><rich_text>. Cist just takes names. Alder builds an entity map and creates connections. It finds local namespaces, fetches refered entities from them, etc. The parameters are the same, but the linking happens only in Alder.
This raises a question: Shouldn't there be more in common to them? Probably yes, but I'll decide when I'm done with Cist diagrams. Guideline for Cist: At least for now, as long as I don't take into account Frelsi variations (e.g. the things I worked on at the beginning, like sets and generators), </rich_text><rich_text style="italic">get as close as possible to Alder, without linking.</rich_text><rich_text>
Let's start.
</rich_text><rich_text weight="heavy">New</rich_text><rich_text> </rich_text><rich_text weight="heavy">guideline</rich_text><rich_text>: Try to be general-purpose where possible. Experiment with generalization. I can help write Sprak later.
Question: How do files and repositories interact? Assume we load a file, and it uses entities from another file. How do we get to the other file? How do we get to remote things? </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: For now, anything external to the file is not supported. Cist will parse it and Alder will find it, but it will generate an error when building the Alder document. This way I won't need to deal with this for now.
Maybe the next stage is to add "links" to Alder, and let yet another processing stage do the inter-file linking after Alder's job is done.
Okay. I wrote a basic Alder model, but I want to add more. I want it to do the job. I'd like to try writing some code or requirements, both direct user query and GUI working with the model. Then I'll have a better view of what the interface should be able to do.
</rich_text><rich_text scale="h1">23/07/2013</rich_text><rich_text>
Let's take the task management as an example. It's the only example I have... how do I work with it? The first issue is probably the working model issue.
The static model can still be relevant. If you write a task management app, you can still use a static model with Task, Topic and Graph classes. This is how </rich_text><rich_text style="italic">Partager</rich_text><rich_text> works. Then this model can interact with the Alder model. But another option is to use the Alder model directly.
I'm going to use the second option for 2 reasons:
1. A non-programmer can't write static models, so GUI needs to work with Alder
2. I want to experiment with a new way of working with document models (directly work with dynamic model)
So assume I have a dynamic model:
* several types
* Task class
* Topic class
That's all. Not a big issue, right? So which tasks do I need Alder to do for me?
* create a task
* set a specific task property
* add child task
Hmmm... I don't think I can list requirements like that. I need a concrete example, with a full list of functions. I'll get back to it later. Right now I have another problem.
Class-property relations and class-object relations can be represented directly by pointers in Alder. It's not a big issue. But what about object-object relations? I'm asking because I can use shared_ptr when pointing from an object to some other object used as a property value. The reason is that it may easily create cyclic references, and the objects will never be freed.
So what I'm suggesting is not to use shared pointers. Have a single repository which manages the objects' memory (using new and delete, or unique_ptr or shared_ptr). Then, everything else can either use the name strings, or use raw pointers-to-const.
As to property values, I haven't found a good solution yet. Properties can have combined values, which means a given property can have a union type of </rich_text><rich_text style="italic">text</rich_text><rich_text> and </rich_text><rich_text style="italic">integer</rich_text><rich_text>, and have both strings and ints as values. Also, specific types like user-defined ones should probably use their own type. I don't have requirements yet. </rich_text><rich_text weight="heavy">For now</rich_text><rich_text>, I'll just use strings for everything.
I realized I may need hash functions for my types. So I decided to use Boost Hash. The other option is to add them to SGP, but that's not any better than using the already-existing Boost. The only problem is that I need to check whether Boost exists in configure.ac, but I found a nice project (on GitHub) which makes it easy.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: For some queries I'll probably need to use graph algorithms on the class hierarchy and also on objects. Objects can easily relate to each other in any way, but classes are restricted to the DAGs like Arbre::Graph, so instead of writing algorithms for classes I can use Arbre::Graph as a representation of classes. Remove the bases and let Arbre::Node take care of it all.
On the other hand, Arbre::Node may offer some unnecessary extra features, so instead I can try to use Boost Graph Library. Anyway, we'll see... first I need to write a list of actions (create new task, etc.). I can make a list of tasks by thinking how a typical GTD workflow would go: Create tasks, edit tasks, associate tasks with topics, get a work view, get by-topic view, mark tasks as complete.
</rich_text><rich_text scale="h1">24/07/2013</rich_text><rich_text>
Task properties:
topics
subtasks
content
complete
start date
due date
Things I want to do:
* create a new task
* set task content
* add subtask
* add topic
* toggle complete
* set due date
* set start date
* load the whole model from a file
</rich_text><rich_text scale="h1">25/07/2013</rich_text><rich_text>
I made an improved IterationInterface, which hopefully I'll successfully use with Alder classes. Before I start using it in the classes, I want to go over the above requirements, and have some more ideas (e.g. load whole lists of values from the file into a C++ object), and update the interfaces accordingly. </rich_text><rich_text style="italic">Then</rich_text><rich_text> I'll start implementing iteration interface issues.
</rich_text><rich_text scale="h1">26/07/2013</rich_text><rich_text>
The Alder::Document interface is great in the OOP sense, because it easily scales and easy to change. But after using Java for university homework for a year, I leant that insisting on an OOP interface unnecessarily makes it very cumbersome, and makes the code look ugly. Sometimes using a single interface with "add_this" and "delete_that" methods is much easier than creating objects and passing them around.
It's like when using a database: You just write queries, and the database software handles the flexibility internally.
So I decided to try to design a super-easy-to-use high-level interface, implemented through Alder. Since this interface is the highest-level interface before the application-specific one, I will call it Idan, like the language.
I'm starting a new repo for it.
Wait a second... how different will it be from Alder? I'll try to describe the whole process and see how Alder does things.
</rich_text><rich_text weight="heavy">Process of task-menagement app</rich_text><rich_text>:
1. Load a file into an in-memory model
2. Build an app-specific interfacing model
3. Make queries for GUI and model changes
* create a new task
* set task content
* add subtask
* add topic
* toggle complete
* set due date
* set start date
4. Store the model into a file
How do we work with entities? Through pointers or through their names?
Let's focus on objects for a moment. If I create an object of a specific class, I can pass the class name, instead of a class pointer. Then I can either get back the object pointer for editing, or makes changes by passing the object's name to a set_object_property() function. Then the app-specific objects can either store pointers, or just store the name strings.
What's better? Hmmm... it's hard to tell. Pointers are faster, but they aren't necessarily as convenient. Let's assume we use pointers, and plan the interface accordingly.
What about the app-specific interface? How deeply does it go into hard-coding the data access? Let's assume it fully hard-codes it. A general GUI widget probably won't, but in this case let's assume it goes the whole way hard-coding the interface for modularity.
We'll use two classes at least:
class Topic stores a reference to an Alder::Object whose class is "Topic"
class Task stores a reference to an Alder::Object whose class is "Task"
You know what? I'll try to write it in actual code. It's supposed to be part of </rich_text><rich_text style="italic">Partager</rich_text><rich_text>, but I don't want to touch the code there. I'll start a new repo called Todo. Actually I'm changing its name to </rich_text><rich_text style="italic">Kranti</rich_text><rich_text> (</rich_text><rich_text style="italic">revolution</rich_text><rich_text> in Hindi, or at least should be).
Basic interface is in place, now I'll try to implement Idan and Kranti interfaces using the underlying Alder objects and improve the Alder interface accordingly. We'll see what comes out.
I created exception classes which Entity needs to use. Next time I'll fill them, and let Entity's ctor throw an exception if it gets an invalid name string.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: Finish the exception classes and string-util, make sure Entity is ready and then continue to implement other classes. Also focus on implementing Kranti and Idan using Alder, and fix Alder accordingly.
</rich_text><rich_text scale="h1">03/08/2013</rich_text><rich_text>
Done with Entity and the exceptions. Now let's implement all other classes...
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Just like Kranti is implemented using Alder, I can implement Alder using a generic Frelsi interface, so Alder::Class and Alder::Object would be implemented using references/objects of type Frelsi::Entity which has "object" or "class" as its notion.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Task and Topic can be just opaque references, but instead can handle memory, i.e. an Object is created when a Task is created, and destroyed when the Task is destructed. Then the user needs to manage the memory of Tasks and Topics, but the implementation is completely free and hidden from the user of the Kranti interface, i.e. can easily have a plain static backend and an Alder backend switched on the fly.
</rich_text><rich_text scale="h1">04/08/2013</rich_text><rich_text>
There's an iterator issue. The Iteration Interface pattern works great, but when I need to pass an iterator to container functions, I need to get a raw iterator. A direct one. Sometimes the Interface::iterator </rich_text><rich_text style="italic">is</rich_text><rich_text> the direct iterator, but sometimes it isn't. Either I define some get_direct_iter() function, or I give the iterator adapter an private </rich_text><rich_text style="italic">operator BaseIter</rich_text><rich_text> member function.
I could give my adaptors a base() method, or use the one defined by boost:iterator_adapter, but what if I use the raw iterator type directly? Then there's no </rich_text><rich_text style="italic">base()</rich_text><rich_text> method. That's why I want to have a function somewhere else. It can be defined in the IterationInterface: If the iterator type is the direct one, then get_direct() returns a reference to the given iterator, otherwise it returns a reference to the base(). Very simple, no need to define it for every new class I write.
Before I add that, there are some other considerations to make:
* Either get_direct() is public, or IterationInterface will need to define the user class as a friend
* All non-direct iterator types will </rich_text><rich_text weight="heavy">have</rich_text><rich_text> to be adapters and supply a base() function
Considering this, I can augment the IterationInterface to support several extras, such as rbegin and rend, and cbegin and cend. Not necessarily using derived classes, but by adding members conditionally, depending the container type. Also I can test for C++11 for cbegin/crbegin support. Maybe the generated config.h has useful macros for that (or I can use the standard version macro).
The additional functions in IterationInterface can be switched in two ways:
1. Surround them with macro conditionals: #if ... #endif
2. Use the C++ way, i.e. define them using std::enable_if, with the macro used to compute the boolean
The standard __cplusplus__ macro doesn't seem to be reliable, so instead I'll use the one from Autoconf Archive which tests C++11 support and adds things to CXXFLAGS. It's definitely better than adding the GCC flag by hand in configure.ac, like I did in </rich_text><rich_text style="italic">makeclass</rich_text><rich_text>.
Before I start touching code, I'd like to add some helpers to Sgp. I mean, add them to Alder and later move them to Sgp. What I'd like to add is </rich_text><rich_text style="italic">constexpr</rich_text><rich_text> functions which replace macros with booleans. For example, assume I have the HAVE_CXX11 macro constant now. I want to have a matching function have_cxx11() which returns a boolean. How do I write it?
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now, assume I want to write a general-purpose function which takes a macro name and returns a boolean, depending on whether it is defined. How do I do it? Hmmm... it has to be a macro function. Or not... how do I do it? Is it completely impossible?
Hmmm... it would be useful if some process would add a function for each macro. For example, if you include config2.hpp, you have the function have_cxx11() defined, even if HAVE_CXX11 is not. But it's confusing. I prefer to have a single function macro_is_defined() which returns a boolean. Usage example:
</rich_text><rich_text justification="left"></rich_text><rich_text>
The problem is that such a function would have to be replaced with a sequence of macro lines, but it seems to be impossible.
Hmmm... I didn't expect this. I guess a good solution may be to have a tool which defines </rich_text><rich_text style="italic">constexpr</rich_text><rich_text> functions in addition to the macros. It can probably be done by adding some code to autoconf or whatever takes all the AC_DEFINE and generates the config.h file. But obviously I'm not going to add things to the Autotools now... maybe I could add some kind of make target which builds the new special config file.
Okay, I think I </rich_text><rich_text weight="heavy">found</rich_text><rich_text> something. config.h.in contains all the definitions, but all of them are #undef. What </rich_text><rich_text style="italic">configure</rich_text><rich_text> does is to convert each one of them into #define or comment it out, depending on whether the specific feature is supported.
So here's an idea: I could add in some code/script somehow, which processes config.h (possibly using config.h.in if it helps) and for each macro it checks whether it's in #undef or #define state (probably except the ones always defined to a value... we want only the HAVE_* ones), and defines a constexpr function accordingly.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>:
* See if I got comments/answers on StackOverflow
* Investigate how the function generation tool can be written and used
* Try enable_if with cbegin, just to see if this specific example would work
* If no result yet, add cbegin/cend/etc. to IterationInterface using #ifdef
* Adding crbegin/crend would still be done by testing Container for supporting backward-iteration,
but I guess it's a reasonable temporary workaround to use a derived class of IterationInterface until I figure out how to test the Container type (could test for existence of given method, e.g. Container::crbegin(), as this should be easy and has an example on StackOverflow)
</rich_text><rich_text scale="h1">05/08/2013</rich_text><rich_text>
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: configure is called by hand when building the software. So instead of looking for ways to add things to configure, I can simply write my own program which runs between configure and make. Or it can be run by make, but then I need to learn how to add a custom make target which generates the constexpr function file.
I looked at Autoconf sources. It has many manually written make targets, and </rich_text><rich_text style="italic">autoheader.in</rich_text><rich_text> is actually a </rich_text><rich_text style="italic">Perl</rich_text><rich_text> script. It may be a very good idea to add the special file to automake.am, but I must make sure it's always run before the C++ sources are compiled. Maybe it's a good time to try learning make again, and this time go over the manual, serious tutorials and a lot of practice.
Right now I don't want to touch </rich_text><rich_text style="italic">make</rich_text><rich_text> because it means a few weeks of not working on </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. I prefer to take care of it later. Until then, I need to do some issue tracking. Placing TODOs in source code is not good enough. Hmmm... I'll read a bit about issue tracking systems.
It looks like Redmine and Roundup are good options. Since I work in a small team of 1 people, the complexity of Bugzilla is not necessary. Anyway, for now I can just add tasks to a TODO list. I'll add a new page for it here.
For now I'll just use the HAVE_CXX11 defined conditionally by the M4 macro I got from the Autoconf Archive. If it's defined, I can support cbegin and cend, otherwise not. Actually I can support them anyway. Yes... in this specific case there is no reason not to support them, regardless of C++11 being used.
As to rbegin and rend, I can't switch them out using enable_if because it works only on template functions, which rbegin and rend are </rich_text><rich_text style="italic">not</rich_text><rich_text>. I also don't want to use Container for that because the interface should not be deduced from the container type, which is an implementation detail. I'll just add a derived class BidiIterationInterface which adds the r* methods.
Adding the class... then I need to take care of the access to base() iterators of iterator adapters.
Let's try an Idea:
</rich_text><rich_text justification="left"></rich_text><rich_text>
I can also add a random-acess one, which adds operator [] and things like that.
</rich_text><rich_text scale="h1">09/08/2013</rich_text><rich_text>
When adding a base to a class, should the Class make sure the base is legal? This raises another question: </rich_text><rich_text style="italic">How</rich_text><rich_text> to make sure it's legal?
There are two simple rules:
1. There must be no loops, i.e. a class can't be an ancestor of itself
2. A class cannot specify bases which have ancestor-decendant relation
Th diamond problem is still possible, but if A ==> B, then C can't have both A and B as bases. However it doesn't mean that </rich_text><rich_text style="italic">Idan</rich_text><rich_text> forbids that: It just means I want to keep the model this way, so that queries may be faster. Actually, it may be much smarter to keep an edge matrix, so ancestry tests are done in O(1), but I'll try it later. I can also use some predefined tool like Arbre or Boost Graph, and enjoy existing interfaces plus all the algorithms.
What do you say? Hmmm... I can make Class implement the interface required by Boost Graph. On the other hand I can just make my own simple version, and practice more coding, and try Boost later. And have my own specialized data representation.
What do you think? How should I implement it? Testing for legality is just like in Arbre. I can use the same code! I can also use shared_ptr instead of unique_ptr, and thus be able to use Arbre directly. Another option is to "port" the code to unique_ptr, and give the Graph object the responsibility to manage memory.
Hmmm... using unique_ptr makes things faster a bit, but it means more work. It's much faster to use shared_ptr now, in terms of developer time, because I already have code (even though it probably needs some heavy debugging). Let's look at the boost source code and see what they do there.
Okay. Boost is very customizble. It lets you choose containers, etc. and all operations seem to happen through the graph, not through vertices. Is it okay in my case? Hmmm... what if Arbre managed all nodes using Graph, and nodes would be accessed using iterators whose operator* returns the node data? Hmmm... good idea, actually. Sounds not bad at all, if you ask me. It can definitely simplify some things by letting Graph manage the whole interface. And it can save the need to use shared_ptr. Instead just use a container that holds all vertices, and the vertices refer to each other using raw pointers! Isn't it much much easier?
It sounds like a good idea, but why reinvent the wheel? I can use Boost Graph with my own custom DAG classes, and get all the nice algorithms. What do you think? I think I need to write the custom classes anyway, so let's write them first. </rich_text><rich_text style="italic">Then</rich_text><rich_text> I'll have a deeper look at Boost Graph.
Instead of writing new classes, I can try to use Arbre as much as possible. Is there a reason not to use shared_ptr? If I keep vertices in some structure, then order doesn't matter, so I can easily implement a "set" of vertices using a vector. Then problem is that iterators of vector are persistent. I can solve it by not giving any general vertext iterator, and only allow a child and parent iterators, like I already have. Then what are the advantages?
Wait. If I need the Nodes in a vector, how will I keep </rich_text><rich_text style="italic">any</rich_text><rich_text> iterators over them? Even a raw pointer won't work, because when moving things in the vector, the addresses change. I'll need to use a vector of </rich_text><rich_text style="italic">pointers</rich_text><rich_text>, or to avoid working with raw memory, a vector of unique_ptr. It means things will work just like now.
I don't see a clear way to make a choice. Here's an idea: Instead of locking myself to one option, I'll write things in a way which allows me to change containers later. Anyway, let's start. Arbre::Node, show me what you got.
Another thing. I do have to use some kind of NodeReference, if I don't want to expose Node, since I decided not to have general node iterators. Instead I can use keep the Node class exposed, and later read more about Boost Graph. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I'll let Node be exposed for now. Less extra work, results made earlier. </rich_text><rich_text style="italic">Then</rich_text><rich_text> I can fix and revise things.
The </rich_text><rich_text weight="heavy">idea</rich_text><rich_text>: Before I just go use Node, try to generalize it to any container, not necessarily one that manages memory of children and parents. See if I can make the code do that. Also see if I have any important TODOs in Node, which I'll need to solve for Alder to work.
Things like detach_child become a bit different when the memory is not managed by Node. Hmmm... when using Graph from the outside, the implementation doesn't matter. If the interface doesn't need to expose shared_ptr, it's hidden. The </rich_text><rich_text style="italic">advantage</rich_text><rich_text> is that the nodes are not tied to a specific graph. Their ownership can be shared by graphs. You can add a node to one graph, remove from another, etc. Actually using a node in two Arbre graphs sounds dangerous, but with shared_ptr it becomes easier.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Keep shared_ptr and try to keep Arbre::Node. Make sure it works fully.
Now how to implement Alder::Class? I don't want it to be a Node, because Nodes have general-purpose things like parent and child traversal, which all Class should have is </rich_text><rich_text style="italic">base</rich_text><rich_text> traversal. You may... oh, wait a second. Shit. How can Class offer traversal of bases, if the parent pointers point to Nodes, instead of Class objects?
A nice idea may be to have Class do protected-inheritance of Node, and maybe even let Node point to Classes through a template parameter. But one thing but be taken care of: The destruction of derived class objects. Node has a private destructor, and a custom deleter. If I try to use shared-ptr-to-node point to a Class object, what happens? Maybe Node's dtor will need to become proected, but that's okay.
Let's run a simple experiment... Great. It works. A custom deleter which calles </rich_text><rich_text style="italic">delete</rich_text><rich_text> and a virtual dtor solve the problem. Now the next problem...
If Class becomes a Node, it will have to be used as shared_ptr. This is quite a problem, because the current interface doesn't have any such limitations. I'd like to be able to handle classes in the regular way, writing things like </rich_text><rich_text justification="left"></rich_text><rich_text>. On the other hand... what's wrong with limiting classes to be like nodes?
Hmmm... now I have doubts again. Why use shared_ptr in the first place? Objects can have fields of self-type either, so these fields can form any kind of graph. And it may still be useful to run graph algorithms on objects. </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Do have raw pointers on classes, but define some templates/bases for graph algorithm reuse.
I have something to say. Maybe you haven't noticed, but algorithms are separate from add/remove functionality. Even if you use the reusable algorithms, you still need to implement the basic get/set/iterate interface. Anyway, let's implement one. Or maybe... hmmm... Maybe it's a better idea to implement one just for Class, and then learn from the experience and be wiser before I try to write something more generic.
Hey, I just realized that full algorithms are impossible as long as Class has only a set of </rich_text><rich_text style="italic">bases</rich_text><rich_text>, but no set of child classes! Also, since classes can't choose children, I can't really validate everything. But there are things I can do anyway, and they may be enough. Let's see.
When adding a base, what do I need to check?
1. The base doesn't have our class as an ancestor (by scanning bases)
2. The base isn't an ancestor of any of the existing bases (by scanning their bases)
3. If the base is a decendant of a some existing base B (possibly there's more than 1), remove B from bases
Everything can be tested by scanning bases. It may not be the fastest option, as opposed to scanning children, but remember class hierarchies are usually trees or nearly-trees, and are written by hand, so there should be no big problem. Let's go write Class.
Question: Who's responsible for making sure the new base is legal? </rich_text><rich_text weight="heavy">ANSWER</rich_text><rich_text>: At least for now, there's no reason why Class can't handle it. So Class will make sure the new base is legal.
I'm considering to make some Node helper class anyway. I just realized I'm going to use most of Arbre::Node's child and parent related things, and it doesn't feel right to write the same code again and again. There must be a way to generalize it.
Since the method names are usage-specific, the public interface won't be automated, but it will be just a thin wrapper around the Node interface. How do I get the Node interface into other classes? I see two ways:
1. Aggregation, i.e. a Node object containing parent/child containers is a member of Class
2. Inheritance, i.e. a Node class serves as a base class for Class, having protected members for Class to use
The problem with aggregation is that Node must point to Class objects, i.e. it needs to be given a functor which takes a Class and returns its Node object, as a reference. If I use inheritance, it's easier. Node can even point to other nodes, or point to Class, and the methods are accessible directly.
DECISION: Let's examine relationships:
</rich_text><rich_text weight="heavy">A class is a node</rich_text><rich_text> VS </rich_text><rich_text weight="heavy">A class has a node</rich_text><rich_text>
I guess this time it's a technical issue, and not a high-level design consideration, but "is-a" applies here more than "has-a". </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I'm taking is-a, and I'll change later if I don't like the results.
Creating class template Alder::Node... (to be honest, it should probably move to Arbre later)
</rich_text><rich_text scale="h1">11/08/2013</rich_text><rich_text>
I'm working on NodeWithChildren. Now writing detach_child(). I just asked myself an important question: What should the interface do when someone tries to detach a node that's not really a child?
In Arbre::Node, the function assumes it's a child, as a precondition. It checks the precondition through an </rich_text><rich_text style="italic">assertion</rich_text><rich_text>, and then simply pretends it's true. But there's also the option to throw an exception. How do I decide?
I'm using this as a reference: </rich_text><rich_text link="webs http://www.drdobbs.com/when-and-how-to-use-exceptions/184401836">http://www.drdobbs.com/when-and-how-to-use-exceptions/184401836</rich_text><rich_text>
It says a function should handle programming errors using assertions, and that code possible causing errors should detect and report them. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: The precondition doesn't stop the function from doing its job. It's a programmer's responsiblity to make sure detach_child is called with a real child. I'll use </rich_text><rich_text weight="heavy">assert</rich_text><rich_text>.
Done implementing, now I'll do new things:
- fix template parameters using find&replace
- write default/useful functors
- more stuff:
* start using doxygen
* write and run test(s)
* start using autotools with Alder (create with autoscan)
Let's start using autotools. I want to read about </rich_text><rich_text style="italic">autoscan</rich_text><rich_text> and see in the Automake manual if there's a similar tool.
Okay, I added initial Autotools files. I need to read about autogen.sh, libtool, gettext and other things. Refresh my memory and learn new things. But before I get there, I want to start using doxygen. </rich_text><rich_text style="italic">Then</rich_text><rich_text> I can start playing with autotools a bit, or at least make a list of related tasks, such as </rich_text><rich_text weight="heavy">make ChangeLog be auto-generated from git log</rich_text><rich_text>, and also </rich_text><rich_text weight="heavy">make devhelp-ready doxygen docs be auto-generated</rich_text><rich_text>.
</rich_text><rich_text scale="h1">12/08/2013</rich_text><rich_text>
Reading here: </rich_text><rich_text link="webs http://www.stack.nl/~dimitri/doxygen/manual/starting.html">http://www.stack.nl/~dimitri/doxygen/manual/starting.html</rich_text><rich_text>
I want to start documenting the code in doxygen style, even if I don't touch the makefiles yet and don't add devhelp support. This way, by the time I add them I'll have the code fully documented.
I looked at the code of several C++ libraries on Gnome Git, and they all use mm-common. It contains scripts which generate Doxyfile from Doxyfile.in and generate files for Devhelp. I guess there's no reason for me to write these things since they're already there, but for now I'll just keep the default Doxyfile.in where it is, and later I'll take care of everything else.
</rich_text><rich_text scale="h1">13/08/2013</rich_text><rich_text>
Doxygen choices to make:
* brief/detailed documentation style
* comment style
* placement of comments: header or cpp, before or after code
* whether private is documented
* which entities are documented
* character for tags: \ or @
Let's start making decisions.
* </rich_text><rich_text underline="single">brief/detailed documentation style</rich_text><rich_text>
/** Brief description.
* Detailes
*/
With Javadoc Autobrief enabled
* </rich_text><rich_text underline="single">comment style</rich_text><rich_text>
/** ... */ like in Javadoc, Gtk+ and gtkmm sources
* </rich_text><rich_text underline="single">placement of comments: header or cpp, before or after code</rich_text><rich_text>
In header, before code
File doc at the stop of the file, after header guard
Function parameters, template parameters, typedefs and data members can have it after, on the same line, just make sure it's possible for them in the Doxygen manual
* </rich_text><rich_text underline="single">whether private is documented</rich_text><rich_text>
* </rich_text><rich_text underline="single">which entities are documented</rich_text><rich_text>
files:
namespaces:
enums:
classes:
typedefs:
functions:d
member typedefs:
member functions:
data members:
* </rich_text><rich_text underline="single">character for tags: \ or @</rich_text><rich_text>
@ like in Javadoc
</rich_text><rich_text scale="h1">15/08/2013</rich_text><rich_text>
I'm done playing with Doxygen for now. I have more autotools-related things to do, but I'll get back to that later. For now I want to finish the Node classes and write Alder::Class based on them. </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Maybe try to create my autotools setup template on Sgp and not Alder, since Sgp is probably more simple and smaller. We'll see.
There's a decision I need to make. I wanted to have two classes, NodeWithChildren and NodeWithParents, and have another Node class which inherits both. But now I realize there will be some complications and naming conflicts, and it may be a good idea not to do that. Parents and Children are dependent concepts, and they shouldn't be modeled independently.
I have to ideas: Have a node-with-parents-and-children class inherit NodeWithChildren, or remove NodeWithChildren and have only a children+parents class.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: For now I'll take the second option: use only a combined class.
</rich_text><rich_text scale="h1">16/08/2013</rich_text><rich_text>
Node is doing great. I'm creating an upgraded Arbre Node, which I may later bring back to Arbre. The issue there is that I'm not sure I'll ever need Arbre Node for Partager at all. The reason is that I'll be using </rich_text><rich_text style="italic">Idan</rich_text><rich_text> for the task and topic models, and not the static model I had. But don't worry - we'll get there later.
What I want to do right now is decide what I'm going to do with template classes. I can't have the header and the source file include each other, without adding some new macros.
</rich_text><rich_text underline="single">Scenario 1</rich_text><rich_text>: The source file is compiled
Expected result: The header is included at the top
</rich_text><rich_text underline="single">Scenario 2</rich_text><rich_text>: The header is included somewhere
Expected result: The source is included after it
Let's see what happens without further modifications, i.e. they include each other.
</rich_text><rich_text underline="single">Scenario 1</rich_text><rich_text>: The source looks like this:
* include header
* function definitions
And the header looks like this:
* if HPP isn't defined, define it and take the rest:
* class definition
* include source
After the header is included, the source will look like this:
* if HPP isn't defined, define it and take the rest:
* class definition
* include source
* function definitions
Now the source includes itself. Bad.
In the second scenario, the header includes the source and the source tries to include the header, but it can't because of the header guard. </rich_text><rich_text weight="heavy">SOLUTION</rich_text><rich_text>: Add a guard to class template source files. Or not?
</rich_text><rich_text weight="heavy">QUESTION</rich_text><rich_text>: Is the source file ever compiled?
</rich_text><rich_text weight="heavy">ANSWER</rich_text><rich_text>: In the dependency tracking done by automake, there's a chance the source gets compiled, but I don't know what gcc produces exactly. I mean, there's no object file. I can try to compile a cpp of a class template and see what happens... then maybe look at some existing projects or run an experiment (e.g. add a dummy class template to makeclass and see what happens).
Judging by Gnote's sources... hmmm... there's a class template there mentioned as a source file in Makefile.am, but the whole class definition is in the header. There's no separate source file. I'll make an experiment with makeclass.
</rich_text><rich_text scale="h1">25/08/2013</rich_text><rich_text>
It works if the cpp is mentioned in Makefile.am (like any class cpp) and the cpp has a guard like a header file. This is what I'm going to do for all class templates. In order to make it </rich_text><rich_text weight="heavy">clear</rich_text><rich_text> why it's there, and make sure it gets removed when not necessary, the guard name will be the header name with </rich_text><rich_text weight="heavy">HPP</rich_text><rich_text> replaced with </rich_text><rich_text weight="heavy">TEMPLATE</rich_text><rich_text>, </rich_text><rich_text style="italic">not</rich_text><rich_text> with the more expected </rich_text><rich_text weight="heavy">CPP</rich_text><rich_text>.
I'll also need to mark symbols. Here's a useful document: </rich_text><rich_text link="webs http://gcc.gnu.org/wiki/Visibility">http://gcc.gnu.org/wiki/Visibility</rich_text><rich_text>
Currently the way to use Node is to derive it public inheritance. But sometimes the user doesn't want to have Node's interface public, in which case there are two options:
1. Do private/protected inheritance and mark Node as a friend class (so that methods can be accessed through Derived* pointers)
2. Allow the class to have Node as a data member and supply a functor which gets the Node from a given Derived
I'll try to have them both work. If not possible, I'll try to choose the one which sounds better. First let's run an experiment to see if private inheritance works if the base class is a friend of the derived class.
</rich_text><rich_text weight="heavy">RESULT</rich_text><rich_text>: Okay, private and protected inheritance works. But there's something I didn't take into account: If I define my helper functions as </rich_text><rich_text style="italic">private</rich_text><rich_text> in </rich_text><rich_text style="italic">Node</rich_text><rich_text>, they won't be accessible when calling them on a </rich_text><rich_text style="italic">Derived</rich_text><rich_text> object. They'd have to be </rich_text><rich_text style="italic">protected</rich_text><rich_text>, but that means they are unnecessarily accessible from </rich_text><rich_text style="italic">Derived</rich_text><rich_text>, polluting the interface used by writers of </rich_text><rich_text style="italic">Derived</rich_text><rich_text>.
</rich_text><rich_text scale="h1">26/08/2013</rich_text><rich_text>
A solution to the problem mentioned above is to convert Derived* to Node* using static_cast, but that's ugly. I need Node to run private helpers, possibly on Derived& parameters, but not expose them to Derived. Is that even possible, without using ugly tricks? Hmmm... I have an idea.
What if all Node's methods are </rich_text><rich_text weight="heavy">protected</rich_text><rich_text> in the first place? Oh, wait... it won't work. It does allow Derived to use public inheritance, but Node would still need to use pointers to Derived. Hmmm...
Another idea: I can assume Node never needs to call private helpers on Derived objects. It always does it on the </rich_text><rich_text weight="heavy">this</rich_text><rich_text> object. But I'm not sure it's safe to make this assumption.
Before I try more things, I want to try the node-member approach. If Class has a Node member, how will it work? Assume I give class a Node private member, and Node takes a template parameter which is a node getter functor, i.e. its operator() takes a Class object and returns a reference to its Node member. Since the member is private, that functor has to be a friend of class. This may be a problem, since template parameters are specified before the class block contents are read. This is a somewhat circular dependency between the functor class and the template parameters of Node used when defining Class. Maybe it will work, maybe not.
Another option is to use a Base class. Base will have a private Node member, and Class will simply inherit it. Now now functor is needed... I think. Let's see...
</rich_text><rich_text justification="left"></rich_text><rich_text>
Since Base is </rich_text><rich_text weight="heavy">based</rich_text><rich_text> on Node, it cannot give Node any functor. Node needs to </rich_text><rich_text style="italic">assume</rich_text><rich_text> that Derived has a member. Since Node doesn't have access to Derived, it cannot touch that member unless it is declared a friend.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now Node assumes Derived has a </rich_text><rich_text style="italic">node</rich_text><rich_text> member and uses it. But I don't like the friendship. If Class has more members, and Node code accidentally uses them, what happens? What if Node is intentionally coded to use a specific Derived and hack it?
Let's run an exoeriment. I want to see if it's possible to define a nested class and use it as a template parameter.
Okay, I ran an experiment. Since Class doesn't inherit Node, Node's parameters are specified in the </rich_text><rich_text style="italic">node</rich_text><rich_text> member declaration, so there's no circular dependencies. It seems to work. The question is, how do I combine everything?
When Node treats Derived as a derived class, it tries to call Derived's methods as if it was Node itself. It makes sense, as long as Node has this kind of access. But if Node is just a member of Derived, then when using the Derived objects stored as children and parents, there are no known member functions available. At all. Derived can be any class. So Node has to have a </rich_text><rich_text style="italic">functor</rich_text><rich_text> which takes a Derived and returns the encapsulated Node. Then Node doesn't have full access to Derived, only access to the Node member.
I want to combine it all. I'm going to add an access functor, but it will default to </rich_text><rich_text style="italic">identity</rich_text><rich_text> in case of inheritance. Of simply do it in any case... hmmm... I hope it works.
</rich_text><rich_text scale="h1">28/08/2013</rich_text><rich_text>
There's a problem with graph rules. So far, I've been using has_decendant() all the time, and _visited versions of scanning functions (like graph rules) relied on getting VisitedSets made by such functions. But now I want to use has_ancestor(), because I expect it to be faster for near-tree graphs.
I decided not to depend on the solution, and simply write all versions for each scanning function. Then I can choose it much more easily, but changing the function called by the default one. I can call the versions with names like apply_graph_rules_ancestor/decendant or apply_graph_rules_up/down, or some other suffix.
Okay, now I need to write apply_graph_rules_visited_real (), and now I see how </rich_text><rich_text style="italic">visited</rich_text><rich_text> is used. I feel I need a new optimization plan for graph rules. Basically there are two possible optimizations:
1. Avoid revisiting nodes as "this"
2. Avoid revisiting known nodes in the has_decendant/ancestor call
The optimizations do affect each other: Even without the first one, the second one alone may solve speed issues. The problem is that when I look at the apply_graph_rules_visited() code from original Arbre::Node, I see only the second optimization and I can't avoid feeling that all this mess and tons of combinations can be solved by using algorithms I already defined.
I want to try using them. Assume I take the "down" approach. Then I basically need to use dft_preorder, with a modification: As I scan a node's children, it should be possible to remove a child and just keep scanning. How is it possible? When removing child, the Function needs to give us an iterator to the next child. Unless... hmm...
I had a thought. Getting an iterator means I also need to pass an iterator to Function, in place or in addition to giving it the target object as its "this" pointer. But there's another option, maybe much easier: When looping through children, always keep two iterators: current and next. Then, instead of doing ++iter, assign </rich_text><rich_text style="italic">next</rich_text><rich_text> to </rich_text><rich_text style="italic">current</rich_text><rich_text>. Even if </rich_text><rich_text style="italic">current</rich_text><rich_text> was invalidated, it gets a new valid value.
There's another consideration: What if I use a flat set, implemented as a vector? In this case iterators are not persistent. If one element is deleted, then another element's position may change. Maybe I already wrote code which breaks when used with flat_set. Who knows? I need to go over it and examine it carefully. All the loops involving </rich_text><rich_text style="italic">detach</rich_text><rich_text> probably won't work. But think about it: How can you loop through a vector, while removing elements? Hmmm... actually, it can still work. Watch me.
Here's the idea: If I remove element at </rich_text><rich_text style="italic">i</rich_text><rich_text> from the vector, then in a flat set the element at </rich_text><rich_text style="italic">s</rich_text><rich_text>-1 is moved there, to replace it and occupy the "hole". It means that if I remove an element, I don't need to change the iterator at all: If I do use </rich_text><rich_text style="italic">next</rich_text><rich_text>, I could miss an element. Hmmm... serious issue here. Vector invalidates iterators, so I'm not sure it's safe to use them after detaching an element.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: The Function class should not be generic, but written after Node's parameters are chosen, including the ChildContainer. So it's possible to write special Functions ready for </rich_text><rich_text style="italic">detach</rich_text><rich_text>, which the user can user without worrying about the details. In order to make </rich_text><rich_text style="italic">detach</rich_text><rich_text> efficient, I can allow Function to have the child_iterator and the parent through which we got there, which is useful both in general and as a way to </rich_text><rich_text style="italic">detach</rich_text><rich_text> - you have to have the parent, and the iterator makes it faster than detach-by-value.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text> </rich_text><rich_text weight="heavy">TIME</rich_text><rich_text>: Try to come up with a signature for Function as suggested, maybe even make two versions for algorithms: One taking the simple version and the other taking the extended one. It may also be a good idea to have the extended version directed at low-level usage, and present the simple one as the primary API. Or, in the "worst" case - update apply_graph_rules (or make a version) to use code copied from the algorithm implementation, with added parts, i.e. the "Function" embedded directly in code like now.
</rich_text><rich_text weight="heavy">NOTE</rich_text><rich_text>: It's also possible to pass only the parent, no iterator. And regardless, separate the iterator choice from Function. Like I said, the loop can use </rich_text><rich_text style="italic">current</rich_text><rich_text> and </rich_text><rich_text style="italic">next</rich_text><rich_text>, so the choice of the new </rich_text><rich_text style="italic">current</rich_text><rich_text> can be done using a new template parameter (functor) which I'll add to NodeParameters. Then Node parameter chooser also chooses this thing, and makes it match the chosen child and parent containers.
</rich_text><rich_text scale="h1">29/08/2013</rich_text><rich_text>
What do we need the Function to do? This piece of code from the loop will help us:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Normally Function takes only the node itself, which clearly is not enough. In order to run these things, the minimal requirement is that Function also knows from which parent we got the child, and has the report_func object. We can give it the report_func, but it will still have to use the parent in real-time. Let's try to write a minimal Function, which retuens a single boolean, denoting whether it detached the child from the parent.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now, using the returned boolean, it should be possible to change the way iteration is made. But now I need to deal with the different kinds of child and parent containers. Before I try to generalize the loop details, I want to suggest a solution for vector, i.e. flat set.
When removing an item using an iterator, the iterator gets invalidated. As a result, it cannot be used again, and neither can the iterators of elements following it. The result is that </rich_text><rich_text style="italic">next</rich_text><rich_text> is useless. So I have a new idea: Either use </rich_text><rich_text style="italic">prev</rich_text><rich_text> instead, or iterate backwards. The problem with </rich_text><rich_text style="italic">prev</rich_text><rich_text> is that there is no element before the first, but if iterating backwards, there's end() before the last element.
Let's try </rich_text><rich_text style="italic">prev</rich_text><rich_text> first. Assume I have </rich_text><rich_text style="italic">current</rich_text><rich_text> and </rich_text><rich_text style="italic">prev</rich_text><rich_text>. If no element is erased, </rich_text><rich_text style="italic">prev</rich_text><rich_text> gets </rich_text><rich_text style="italic">current</rich_text><rich_text>, and </rich_text><rich_text style="italic">current</rich_text><rich_text> gets ++ (or both get ++, same result). But if </rich_text><rich_text style="italic">current</rich_text><rich_text> is erased, it is simply set to </rich_text><rich_text style="italic">prev</rich_text><rich_text>+1 and </rich_text><rich_text style="italic">prev</rich_text><rich_text> doesn't need to change. The only problem is the first element: If the first element is erased, then the new </rich_text><rich_text style="italic">current</rich_text><rich_text> needs to be </rich_text><rich_text style="italic">begin()</rich_text><rich_text>, which does not have a previous element at all. It means that other than ugly hacking and trying to see if --begin() produces a before-begin iterator, I'll need to do a check: </rich_text><rich_text style="italic">prev</rich_text><rich_text> can be initialized with </rich_text><rich_text style="italic">begin()</rich_text><rich_text>, and if an element is removed, it checks whether it's at the beginning, i.e. whether </rich_text><rich_text style="italic">current</rich_text><rich_text> is </rich_text><rich_text style="italic">begin()</rich_text><rich_text>. If it is, </rich_text><rich_text style="italic">current</rich_text><rich_text> gets the new </rich_text><rich_text style="italic">begin()</rich_text><rich_text>, otherwise it gets </rich_text><rich_text style="italic">prev+1</rich_text><rich_text>.
It's not a big deal, but this check can be avoided and maybe lead to more elegant code, if the backwards-iteration technique is used instead. How does it work? You have </rich_text><rich_text style="italic">current</rich_text><rich_text> and </rich_text><rich_text style="italic">next</rich_text><rich_text>, but you go backwards. If an element is erased - oh, wait a second. You can't use iterators after </rich_text><rich_text style="italic">current</rich_text><rich_text>. You can only use </rich_text><rich_text style="italic">prev</rich_text><rich_text> here. But what difference does it make? Let's see.
When an element is erased, </rich_text><rich_text style="italic">current</rich_text><rich_text> simply takes the value of </rich_text><rich_text style="italic">prev</rich_text><rich_text>, and </rich_text><rich_text style="italic">prev</rich_text><rich_text> doesn't change. When not erased, </rich_text><rich_text style="italic">current</rich_text><rich_text> gets </rich_text><rich_text style="italic">prev</rich_text><rich_text> and </rich_text><rich_text style="italic">prev</rich_text><rich_text> goes -- (or both go --). But this doesn't work at the end: Assume </rich_text><rich_text style="italic">current</rich_text><rich_text> is the second element and </rich_text><rich_text style="italic">prev</rich_text><rich_text> is the first. What happens now? I'll have to make a test: If </rich_text><rich_text style="italic">current</rich_text><rich_text> is erased, then see if </rich_text><rich_text style="italic">current</rich_text><rich_text> is </rich_text><rich_text style="italic">begin</rich_text><rich_text>. If it is, it will get the new </rich_text><rich_text style="italic">begin</rich_text><rich_text>, otherwise it will get </rich_text><rich_text style="italic">prev</rich_text><rich_text>.
Wait a second... it's just like the forward iteration test. Almost the same. It's not better, then, unless the first/last element is taken care of outside the loop, which is quite cumbersome considering the tiny speed change. I'll just use the forward iteration method. Later I can easily give a try to the two-step method, i.e. a separate loop for the first element.
Now, how do I </rich_text><rich_text weight="heavy">generalize</rich_text><rich_text> the loop details? Each container may need different details, because the iterator limitations depend on the internals of the container. First let's write the loops:
Hash set:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Wait a second, there are two issues here: First, the code for both cases is exactly the same! It doesn't matter whether anything is erased. The second issue is that </rich_text><rich_text style="italic">++next</rich_text><rich_text> will be called when </rich_text><rich_text style="italic">next</rich_text><rich_text> is </rich_text><rich_text style="italic">end()</rich_text><rich_text>, which is illegal. It's undefined behavior, and I ran an experiment that shows what happens: Vector, list and set are fine, but unordered_set causes segfault when an </rich_text><rich_text style="italic">end()</rich_text><rich_text> iterator is incremented.
I'll solve the second problem by changing the location of the </rich_text><rich_text style="italic">++next</rich_text><rich_text>, and avoiding its duplication.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now let's do the same thing for flat set.
Flat set:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Conclusion: I don't want to create any internal assumptions and dependencies. I can simply add helper functions like these:
for_each_child doesn't allow removals that invalidate iterators
for_each_parent doesn't allow removals that invalidate iterators
for_each_child_allow_detach allows detaching the child
for_each_parent_allow_detach allow detaching the parent
I can also add functions that allow *any* detach, maybe by copying the child list and iterating on the copy. Then changes to the real one don't make trouble.
What about additions? What if I want to scan children, and decide to add new ones using some decision mechanism? Adding before the element (e.g. if there's a flat set which gets all new insertions at the beginning) could invalidate the iterator. Hmmm... I think I'll write functions first, then decide. I'll write them here.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Great, now I'd like to write two functors for the second function: one for my "flat set" and the other for unordered_set.
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text justification="left"></rich_text><rich_text>
Great! Now let's move all this new material to the actual source files.
</rich_text><rich_text scale="h1">02/09/2013</rich_text><rich_text>
There are new versions of apply_graph_rules, that I need to write.
()
down_ancestor
down_decendant
up_ancestor
up_decendant
These basic algorithms can be extended through the VisitedSet:
* take external one VS use internal one
* share results between calls VS make new copy of external every time
All these options add complexity to the implementation and make the Node class bigger and more difficult to understand. They *are* nice optimizations, but do I really need them all? Are they worth it? Hmmm... one of the ways to answer this question is to examine the way </rich_text><rich_text style="italic">apply_graph_rules</rich_text><rich_text> is used.
</rich_text><rich_text weight="heavy">Jerusalem, we have a problem.</rich_text><rich_text>
I wanted to implement </rich_text><rich_text style="italic">actual()</rich_text><rich_text>, and then I realized I can't. If Node is just a member of Actual, there's no way to get the Actual object to which a given Node belongs. So I can't implement </rich_text><rich_text style="italic">actual()</rich_text><rich_text>. This issue raises a big question, and now the whole Node concept is in great danger!!! I'll try to examine the problem as carefully as I can.
Using the </rich_text><rich_text style="italic">get_node_func</rich_text><rich_text>, the Node code is able to work with Actuals and get their Nodes when needed. But the </rich_text><rich_text weight="heavy">this</rich_text><rich_text> pointer points to a Node object, and thus cannot be used with these functions without conversion to Actual, which is impossible. The solution to the problem can be to work </rich_text><rich_text style="italic">only</rich_text><rich_text> with Actual objects. But is it possible?
In order for Actual to be able to inherit the node interface, the interface has to exist in a base class, as member functions. It means that while the inteface works with Actual objects, it has to be able to work with Node objects too, otherwise Node's functions can't be implemented and inherited by Actual.
One solution is to use the old Node: Have a single stand-alone class with a Data parameter. But I want to try to avoid the problem by not needing to use actual() at all. For that to work, I need to make sure it's possible, and that small changes won't ruin all my plans. I'm going to try to design a hypothetical simple Node method, and see under which conditions a Node-based private helper and an Actual public wrapper can't solve the problem. Clearly the only reason to use Actual inside is </rich_text><rich_text weight="heavy">when accessing children or parents</rich_text><rich_text>, because the containers store Actual objects, not Nodes. </rich_text><rich_text weight="heavy">Next</rich_text><rich_text> time I'll try it.
</rich_text><rich_text scale="h1">03/09/2013</rich_text><rich_text>
I thought about the </rich_text><rich_text style="italic">actual()</rich_text><rich_text> issue. Some of my thoughts, ideas and research are documented on paper, and I won't type them here. Hopefully, eventually all my papers will get scanned and become electronic material. When my personal data organizer application is ready, I'll easily link my pages to the scanned text. Of course it's possible to insert file links in a wiki, including here in CherryTree, but this doesn't allow me to manage documents in the big-picture level.
I'm going to add a new functor to Node, called GetActual. Its job is very simple: Do the reverse operation of what GetNode does. But if Actual has virtual things, the only portable safe way to do it is to have an </rich_text><rich_text style="italic">actual</rich_text><rich_text> pointer/reference as a member of Node. Not the best solution you could expect, but it's safer than using pointer dark magic.
</rich_text><rich_text scale="h1">05/09/2013</rich_text><rich_text>
Node is almost complete! Just one last pass left, to make sure the initial version is ready for usage. The on_* functions are currently not virtual, so nothing can re-implement them. But I can easily change that later. Other small things are listed as TODOs, of which I will take care in the next pass.
It's time Node gets finished! I wasted a lot of time on it already. I want it to be ready! But it's probably not a good idea to continue without testing it: After I finish Node, I'll add and update all necessary Autotools files and write full tests for Node, using a simple Actual class. </rich_text><rich_text style="italic">Then</rich_text><rich_text>, I'll be able to proceed safely to implement </rich_text><rich_text style="italic">Alder::Class</rich_text><rich_text> using </rich_text><rich_text style="italic">Arbre::Node</rich_text><rich_text>.
</rich_text><rich_text weight="heavy">UPDATE</rich_text><rich_text>: Finished first version!!! Now, just before I add some autotools support, I'll write default functors: one set for unordered_set, and another set for "flat set".
I did GetActual and GetNode. Now I need to complete the functors for the rest of the functor parameters, and the next step is to setup autotools full use for Alder and write tests for Node.
</rich_text><rich_text scale="h1">06/09/2013</rich_text><rich_text>
I'm done with Node functors, and now I want to try Node in a test. But I realized that Node comes from Arbre, and it should go back there. On the other hand Arbre is already full of things I won't need, like XML. On another hand, XML can be useful in the future. It may be a good idea to keep some code.
Anyway, I was considering to start a new separate Arbre, and then I realized all my classes are templates. So I'll need my makefiles to treat the code as headers-only in some way. I'll need the cpp files to be distributed together with the headers, in the same place. And there will be no compilation. How do I do that?
I went to Wikipedia and started reading about GNU make, but I realized it's very boring to just read, without doing actual work. And then I'd have to go over Automake and Autoconf manuals, and understand all the targets and variables. I was going to do it, but then I began losing motivation. So much to read and explore... It's easier to just take Arbre and replace Node with my new class. Hmmm... you know what? I have an idea.
Since Arbre is part of Partager, I'll need to give it new makefiles anyway. Before I do that, I'll go to Autoconf and Automake manuals and try to find interesting sections. Then I'll start writing some real things for Arbre. </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: I'll create two reference example repos. One for a library, one for a program. And every time I'll need to start a new repo, I'll simply clone them. Later I can add Doxygen support by copying code from mm-common and add a repo for header-only libraries. Let's start!
</rich_text><rich_text scale="h1">11/09/2013</rich_text><rich_text>
Hello again, people. I've been doing some research and writing a "skeleton" prototype for C++/autotools/git projects. I just started writing about DOAP while reading in Wikipedia, and then suddenly I stumbled upon YAML. I started reading about YAML, and I realized it has amazing similarity to </rich_text><rich_text style="italic">Idan</rich_text><rich_text>!!! Moreover, it looks like </rich_text><rich_text style="italic">Idan</rich_text><rich_text> may not be necessary at all. I mean, imagine you can write the model in YAML and then write the data in YAML. Then all you need is to follow some rules, and no need to have </rich_text><rich_text style="italic">Idan</rich_text><rich_text>.
Even if I don't use plain YAML, I can redefine </rich_text><rich_text style="italic">Idan</rich_text><rich_text> to extend YAML or to be almost-the-same, so learning it will be easier for people who know YAML. And even better, YAML can help me with the programming aspect. I can either use YAML, or use the existing parsers to create my </rich_text><rich_text style="italic">Idan</rich_text><rich_text> parser much much faster!
Anyway, I won't continue here before I read more about YAML. It can save me tons of work. First, I'll finish with the DOAP files and take a look at some YAML libraries.
</rich_text><rich_text scale="h1">13/092013</rich_text><rich_text>
I'm done with DOAP. Before I continue with the Skeleton project, I want to take care of YAML. There are going to be very serious changes.
I realized that YAML is more powerful than Idan, if you ignore small things like the [X] boxes allowed in graph entities. YAML allows multi-class graphs, while Idan allows only single-class ones. Sooner or later I would realize I need them, and then Idan would become even closer to YAML than it already is.
Thus, I decided to use YAML instead of a plain Idan parser. I may need to add some extensions, which will be implemented as additional processing stages attached to the YAML interfaces.
I've been examining the avaulable libraries for reading and writing YAML. The conclusion: They seem to be simple and there's no all-in-one tool like libXML. Actually the interesting tools I found are:
* libYaml: C library
* SYCK: C library with several bindings, unmaintained since 2005
* yaml-cpp: C++ library
yaml-cpp is very interesting, I must say. Its simple tutorial doesn't show any event-based parsing, but it does have a very cool DOM-style code. Also, the implementation seems a bit ugly to me and the naming conventions are unusual. It's very tempting to try writing my own version, using libYaml and yaml-cpp to help me.
I can create a combined tool like libxml++, having both a SAX-like parser (like libYaml does) and a DOM-style interface (like yaml-cpp does). Then people have all the options.
Before I decide, I'd like to see how yaml-cpp is implemented. I mean, the parser itself. How exactly it reads text and makes nodes.
Hmmm... actually it looks like yaml-cpp does have a SAX-like parser.
Hmmm...... to be honest, the code is not small. It doesn't look like something you write in seconds. I can avoid the mess by just using a YAML library and that's it. Just parse the thing into my own Alder structures and forget YAML until I need to save to a file, in which case I write my structures as YAML and tell the library to update the file. On the other hand, I can keep the YAML structures in memory and just update them every time the user sends me an Alder update. Then there's no need to generate YAML (but it creates a deep dependency on YAML).
You know what? Before I make more decisions, I need to do more things.
1. Read thorough material about YAML, and see if I can at all make any plans for parsing it. Make sure it works with non-English languages fully, including RTL. Make sure all the explicit entity names I need are possible, or can be omitted and then file extensions can indicate a file's role (model VS data).
2. Design new full good sexy API for users. Take an example from yaml-cpp: It has a util folder, in which the developer writes API plans and examples, and these in turn are used to improve and design the actual API. I will do the same: Examine the needs, write random API ideas, collect good ones and make prototypes.
I will take it as a </rich_text><rich_text weight="heavy">CHALLENGE</rich_text><rich_text>: Try to write my own YAML library. Not because not enough exist already, but because it's interesting and can be good experience in API design. After all, I'll just be doing regex matches and playing with iterators and containers. Also, it may be a good idea to design some graph stuff here. Maybe. We'll see. This is however not the Partial-Order graphs I use with Arbre::Node. In YAML it's just a relational tree. I can reuse Node, but I'll need to make tons of changes. Especially, the inheritance tricks are *very* ugly.
Let's start with the second thing I mentioned: API prototypes. After all, the </rich_text><rich_text style="italic">need</rich_text><rich_text> is what drives the project.
So, what do I need </rich_text><rich_text style="italic">Idan</rich_text><rich_text> for? Let's look at the diagram I made. It contains just two classes: Model and Object. The idea is that the specific Model and specific object classes inherit these classes, and user their protected members to update the dynamic data structures.
This way, an update-to-disk policy is </rich_text><rich_text weight="heavy">very</rich_text><rich_text> easy to add: you just update the model, and tell the library whether/how/when to save it to the file. Autosave can be done on the fly. Anyway, enough with the dreamy bullshit. Let's examine actual needs.
What are programs supposed to do with data? I want to take the following examples:
1. Task management GUI app
2. Task management CLI app
3. Model and data editor GUI
4. Relational model GUI app (like Glom but for Idan, not SQL tables)
Why these examples? Because... let's define </rich_text><rich_text style="italic">Idan</rich_text><rich_text>'s goals. The things it solves. Idan is a dynamic semantic data access system, whose primary purpose is to supply a convenient interface for apps to use for handling their data. Primarily I'd like to examine GUI apps. Let's take take example </rich_text><rich_text weight="heavy">1</rich_text><rich_text>.
Assume a simple app like the old-version GTG I have here. Basically, it has a Tree View of tasks and allows the user to reorder them and edit their parameters. How is such an app organized?
First, there's a </rich_text><rich_text weight="heavy">Data</rich_text><rich_text> structure. It can be a complex relational tree, much too complicated to display on a 2D screen. But it's good at storing the bare raw pure data.
Then, we have a </rich_text><rich_text weight="heavy">Model</rich_text><rich_text>. This one represents the structure displayed to the user. It's simple enough to be displayed, and yet it has to allow for effective user productiviy. In other words, be good in both directions. The structire of this model tightly dependent on the UI concepts behind the actual graphical widget.
And last one is our </rich_text><rich_text weight="heavy">View</rich_text><rich_text>. This is a graphical component which displays the model and receives input from the user.
The question now is, how do the three components work together? There are many answers possible. Probably many different design patterns and options and ideas, and some programming languages and toolkits adopt specific ones or avoid specific ones. Here I'll try to design my own guidelines.
Here it comes. Basically, all user interaction has a meaningful purpose. The clicks and drags and drops and presses, they all have a meaning in the user's mind, related to thr data. For example, assume a task has two parents, so it appears in two places in the tree. To the user, any operation on </rich_text><rich_text style="italic">any</rich_text><rich_text> of the copies is just an operation on the task. The user </rich_text><rich_text style="italic">sees</rich_text><rich_text> the model, but she </rich_text><rich_text style="italic">thinks</rich_text><rich_text> in terms of the data. Thus, each unique operation has meaning to the data, while the model is just a GUI-helper component whose details can change if the GUI design is changed or new widgets are introcuded.
The result of this philosophy is the following model: Every operation has to begin from the data. There may be special cases where the model is in charge, e.g. drag-n-drop stages or low-level details, but in general the data is in charge and all requests begin there.
Naturally, the questio now is, how does the GUI respond to these changes? Well, there are two options:
1. The data structure reports about changes
2. A coordinator changes the data, and then updates the GUI
In complicated operations, the first option is the only choice. But in simple ones (e.g. remove a task), both can work. Unfortunately, the choice of option is not trivial. Let's see why.
Assume we have a coordinator interface. When we tell it to remove a task, what happens? First, it removes that task from the data. As a result, all the children which have become orphans are destroyed, and it happens recursivey. We can ignore all the "orphan" events. After that, we find all the task's copies in the model and delete them, along with their children.
Now, let's make sure we're safe before we proceed to trying to use reports. Assume our tasks are always destroyed when becoming childless. Then if we killed a task, we may have caused further deaths. How do we detect these? Simple: we listen to "childless" events and delete tasks from the model accordigly, right after we remove them from the data. Great. There may be more special cases, like UseCounted, but we'll examine them later.
Now assume we want to handle delete-task using events. The only way to do that is to make the </rich_text><rich_text style="italic">delete_task</rich_text><rich_text> function report on the deletion, using a signal </rich_text><rich_text style="italic">SignalDeleted</rich_text><rich_text>. It's simply called in the task's destructor. Now, on every deletion we can respond by removing things from the model. But is it </rich_text><rich_text style="italic">really</rich_text><rich_text> that easy? Let's try to find special cases. Oh, wait a second...
I think we chose the wrong event. It is not the deletion we want to detect, but something different: We want to know when a task loses all its parents. Because when it happens, it doesn't belong to our model anymore and shouldn't be displayed. Solution: Listen to "orphan" signals and remove these tasks.
Sounds great, but how does it affect the delete-task event chain? Assume we delete a task. What does delete mean? Detach from all parents. Then we detach. The task reports "orphan" after the last detach, and then the model deletes all its copies from the model - wait. Here it is. We found two problems:
1. After the task is removed from the model, destruction of the task will trigger orphanization of some of its children, and they will report orphan. But we can't remove them from the model, because we already did that. They were under the task we removed, and thus were removed too.
2. With every detach of the task from a parent, the model removes the corresponding copy of it. So it happens gradually. When the last detach happens, there's no need to scan the whole model: Just find all the occurenes of the only parent, and remove task from there. This actually is not a problem, but an optimization, but it shows how a simple event splits into stages and becomes more complicated and harder to follow.
Considering the first issue, it's probably faster to remove from the data first, and </rich_text><rich_text style="italic">then</rich_text><rich_text> remove from the model. This way we won't be looking for tasks we already removed. Even if we did, wouldn't it be stupid? We'd be removing them layer by layer, doing tons of unnecessary tree searches.
Conclusion: Do allow for event handling, but don't be afraid to use plain direct coordinators. It can be both faster and easier to fix if bugs appear, since the process is much easier to follow.
Great. So it can work. Now, how do we implement it? We're going to have an App object, with all three components inside. It doesn't have to be exactly like that, but the small nesting details don't matter right now. We keep it simple:
App
Data
Model
View
Now, assume Data has a collection or things we call Items. In our case, these are tasks. The structure is not relevant. Just the availability of the items is. Let's add them to the "tree":
App
Data
Item...
Model
View
Good. Now, what does the model contain? That's right, references to items. We'll call them Refs.
App
Data
Item...
Model
Ref...
View
Now we need to see exactly how the data and the model interact. How does the model get the ref, and how does it use it? I'll take these operations as examples:
* add new task as a child of an existing one
* remove a childless task
* remove a task
* move a task from one parent to another by drag-n-drop
* copy a task by drag-n-drop, i.e. give it a new additional parent
* edit task fields
This should be enough. Tomorrow I'll examine them. Already having these things in C++ code (which I wrote for Partager) helps a lot. Nothing is better than actual experience (and a little is better than none at all).
</rich_text><rich_text scale="h1">Again 13/09/2013, after I slept 5 hours</rich_text><rich_text>
I know, 5 hours is not much. I feel my eyelids are a bit heavy. But I'll be fine. Life is too short to waste on sleeping! Back to work. Where was I?
Oh, right. Examine actions. Assume we have two base classes which people can inherit, </rich_text><rich_text style="italic">Idan</rich_text><rich_text>::</rich_text><rich_text style="italic">Reference</rich_text><rich_text> and </rich_text><rich_text style="italic">Idan</rich_text><rich_text>::</rich_text><rich_text style="italic">Object</rich_text><rich_text>. One of them can be a subclass of the other, but it doesn't matter and is an implementation detail. These classes will be used by all app-specific data classes. </rich_text><rich_text style="italic">Object</rich_text><rich_text> means the C++ object manages the existence of the Idan object, and </rich_text><rich_text style="italic">Reference</rich_text><rich_text> means it does not, unless explicit commands cause deletion of the object.
I said one could inherit the other, because basically Object is just like a reference, but it creates its own Idan object in the ctor and removes it the dtor. Otherwise they're the same: both provide access to an Alder object accessed through a pointer (whose memory is held by the Alder model).
There are two options for the Model, which I must mention. It's important:
1. All references to </rich_text><rich_text style="italic">Idan</rich_text><rich_text> objects use </rich_text><rich_text style="italic">Idan::Reference</rich_text><rich_text>
2. Each </rich_text><rich_text style="italic">Idan</rich_text><rich_text> object has a single </rich_text><rich_text style="italic">Idan::</rich_text><rich_text> handler, Object or Reference, and all other references point to the handler
There are probably advantages to both options. But I'd like to discuss some design philosophy again, which will make the decision easier.
If all references use </rich_text><rich_text style="italic">Idan::Reference</rich_text><rich_text>, there will be many contact points spreaded in the source code. It means that an update to </rich_text><rich_text style="italic">Idan</rich_text><rich_text> or changes to app data implementation will require many changes, since all interaction happens through individual references to </rich_text><rich_text style="italic">Idan</rich_text><rich_text> directly. On the other hand, these references are independent: If you remove, change or edit one of them, the others still work.
But if you have a single point of contact, and all other interface users connect to this single point, you can easily change its implementation. You can even stop using </rich_text><rich_text style="italic">Idan</rich_text><rich_text> and choose some other implementation. The downside is that everything uses you app-specific class, which may change more easily than the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> API. If you change it, you affect all references.
The philosophy I follow says, minimize dependency between interacting services. Try to make them pluggable providers. In this case I have to quite distinct services: User interface the Data. In order to make them easily pluggable, I'll have a single contact point: Implementing specific data classes using the dynamic semantic object model of </rich_text><rich_text style="italic">Idan</rich_text><rich_text>. Obviously each specific data class means a separate contact point, but all these contact points represent a single contact layer, which exists only in the data model implementation level. The application logic and high-level structures and services which use the data classes don't see any details of </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, which means they are </rich_text><rich_text weight="heavy">separated</rich_text><rich_text> from the data implementation completely. They don't even use its API, which means a completely new backend can be inserted without affecting the app layer implementation.
Therefore, I choose the </rich_text><rich_text weight="heavy">second</rich_text><rich_text> option.
Great, not let's try to implement things. We have Data, Model and View. View is just a widget and Model contains references to Task objects. Data is the one we need to design carefully.
The problem with the Alder model is, that it doesn't return app specific objects. We can derive Task from Idan::Object, but if we request creation of a new object from the model, it will return an Alder object. Not a task. Of course, that's why </rich_text><rich_text style="italic">Idan::Model</rich_text><rich_text> exists. But before I choose to use it, let's think: do I really need it for object creation?
How is a new task created? Either as a child of an existing one, or as a toplevel task. To the Alder model, there is no specific task hierarchy at all: just pointers from one object to another. If we want to create a new task as a child of another, can we request it from an existing task? Hmmm... good question. I think we can't. All operations will have to go through the model. Yes, all of them. Why? because individual objects are not the model. A task can't create a new task, because it has to register the task in the model, which stores all the objects and manages their memory. So in reality, new tasks will be passed to us from the model. We will implement a TaskModel derived from </rich_text><rich_text style="italic">Idan::Model</rich_text><rich_text>.
Then, our Data component is simply a TaskModel object. It supplies all the operations which can't be done from objects. Actually, besides querying objects and setting fields, everything requires the model. Let's see how we implement all the actions in the list. I'll assume we don't use - hmmm... wait. Do we use Object or Reference? Each task may appear more than once in the Model. We want all occurences to be C++ references to Task objects. Where will these objects come from? Let's assume we use Reference for now and maybe change later.
* add new task as a child of an existing one
Through the View, the user clicks on an existing task and from a right-click menu she chooses "New child". The coordinator receives the request. Now it needs to do two things: Create a new empty Task, and add it to the Model. The coordinator asks the TaskModel to create a new task. The TaskModel passes the request internally to the Alder model, and gets a new Alder object. It then creates a new Task which wraps this object, and returns it. This Task is a Reference to the actual object stored in the Alder model.
The coordinator gets the new Task from -
Hmmm... we have a problem.
I decide the Model will store Task references. But who will keep the memory of these references? I missed the idea behind </rich_text><rich_text style="italic">reference</rich_text><rich_text> </rich_text><rich_text style="italic">VS</rich_text><rich_text> </rich_text><rich_text style="italic">object</rich_text><rich_text>. If we want to avoid storing Tasks in a structure, Model will have to store Task objects </rich_text><rich_text style="italic">by</rich_text><rich_text> </rich_text><rich_text style="italic">value</rich_text><rich_text>, i.e. manage their memory. That's like having each line store an </rich_text><rich_text style="italic">Idan::Reference</rich_text><rich_text>, which I wanted to avoid.
I need to re-think this. Either I store all Task objects in a structure (just to keep the memory, i.e. a simple STL container is enough) and give Model references to them, or I give Model actual Task objects to store, and then Task has to be a Reference. Hmmm... I guess both are fine. Why did I offer Reference in the first place? Because I thought it will be useful to have an app specific interface which doesn't involve memory management. The Alder model already does that, so why force the user to do it again in the app layer?
It does make sense to use Task in the Model. All these Task objects will represent the same actual task. Basically, the difference between Object and Reference is that Reference offers a mere interface. Hmmm... maybe I should give it a new name. TaskRef is somewhat ugly. If I used a cool name, Task could append it to "Task" and then the class name would reflect better what the class does. After all, a Task as a Reference is not exactly just a task. Hmmm... I'll think about it.
I'd like to discuss a problem. Before that let's finish the action: The coordinator gets the new task and stores it in the Model, one copy for each occurence of the parent task.
The problem I want to mention here is the change from Object to Reference, or the other way around. Even if the class name remains the same, such a change in the app means all Model rows will need to change from Task to Task&, or from Task& to Task. If the type of the data is parametric, it's much easier: references are treated in the syntax like object when calling their member functions. When copying, it works too: Copying an object would become copying a reference, making them point to the same object. Actually it sounds perfect.
Recommendation: Either use a parametric row data type, or be ready to do search-and-replace.
* remove a childless task
The coordinator tells the TaskModel to remove the task, and then removes all its occurences from the Model.
* remove a task
The same procedure.
* move a task from one parent to another by drag-n-drop
This is a bit more complicated. Basically a Task object will have to leave the TaskModel somehow, and wait outside while dragged. Or, another option is to allow the Model to contain tasks without parents and children. Actually, the Alder model is supposed to be able to do that. It just depends on whether the TaskModel allows that too.
* copy a task by drag-n-drop, i.e. give it a new additional parent
This operation can probably be done by connecting two tasks through Task. But if the model needs to be involved, no problem: the Coordinator can do that.
* edit task fields
Directly through Task member functions.
Good. Done with the examples. So for applications, this is how it works. This is a good time to write a usage example! I'm creating an API example subpage, which will have several C++ pages under it. Then I'll go back here.
Wish me luck!
</rich_text><rich_text weight="heavy">I'm back</rich_text><rich_text>. I made a simple Task.hpp example. I think it's good enough to start coding it in the actual git repo. I'll open the Alder classes Class and Object, and Model too...
Okay. Object is nice, but I think the end user can enjoy an easier interface. For example, there's probably no reason not to use strings directly to fetch property values. Getting the Property pointer from the Class adds unnecessary clutter to the user's code. In case the user wants to make sure the strings are legal, she can verify the data using the model, and use it only after verification. Anyway, we'll see. First I want to take the example to a new direction.
Assume you're not just the user. You have a task-related model stored in a file, and you want to store data files which match the model. How do you avoid the usage of string literals, in order to make the code easy to modify in case the model changes?
Clearly, if you write a specific app like task-manager, the fields you want to support all seem legitimate and useful, and match your view of a perfect tool for the purpose. Or at least you plan it to match your view at some point. But if you use someone else's model, you can't rely on the names remaining the same. Even if you verify a file before you load it, you still want model changes to be trivial to adapt to in your code. The natural solution is to give the strings aliases, so you don't need to use actual names.
Some ideas:
* use #define to replace your names with actual strings
* define string objects or constexpr functions and use them instead of literals
* instead of string objects, store Property pointers and use them instead
* instead of giving Object a Property-to-values map, give it a string-to-values map
Another important improvement: Treat single-value properties in a special way, allowing for more natural syntax. Since the value is always a single one, getting the value doesn't return a 1-size vector, but returns the value directly. Many properties are like that, so it's a huge benefit to the user.
I'd like to design a simple high-level interface for Object. So far I've been defining Alder using conventions mainly. Now I want to examine actual needs. What does the user need to do with objects?
First, a short reminder. An object has:
* a name
* a namespace, to which is belongs
* a uid
* a set of properties
Each property has a type, a set of allowed number-of-values and a set of values. However, I suggest that any number of values between the MIN and the MAX is considered legal. When trying to save the file, a test will be made to ensure it's legal. Otherwise, how can a user edit an object in a GUI? If the only options are 3 and 5, the user must be allowed to choose a new value, resulting in 4 values (invalid). </rich_text><rich_text style="italic">Then</rich_text><rich_text> the user can choose another one.
It's possible of course to introduce hacks in the app, which make the new changes wait outside the model. But such hacks also add a huge potential for errors and bugs of many kinds. It's a bad idea. Also, there's a backup aspect: What if autosave is delayed due to an invalid number of values, and then the computer crashes? I assume non-sequential sets are rare, but in cases like "3 or 5", there must be a way to store the data for later backup. It's possible of course to have it stored through an app mechanism, not something internal to Idan.
Or another nice idea: Write the data to a file, and ignore the rules there. It's just temporary YAML storage. Then the database collects the file and adds the new data. Backup still works through Idan, but data is not inserted to the database.
And another option: Data is sent to the storage mechanism, but it specifically picks only the legal entries, and rejects the others. Then, the writing of invalid entries is delayed until they're fixed. The data is kept by the storage system, thus safe, but the database won't accept the invalid entry until it's fixed.
Anyway... let's decide which functions Object needs to supply. Assume I work with Object from app code. What do I need it to do?
* get a property value
* get the list of property values
* get a value from the property's list of values
* set a property value
* add a property value
* remove a property value
* get/set name
* get/set uid
Assume I have an </rich_text><rich_text style="italic">Object</rich_text><rich_text> called </rich_text><rich_text style="italic">object</rich_text><rich_text>. Let's write some prototypes/examples for the functions:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Important question: Does </rich_text><rich_text style="italic">Idan</rich_text><rich_text> need lists? Should it allow properties to have a set of values where the order </rich_text><rich_text style="italic">does</rich_text><rich_text> matter?
</rich_text><rich_text scale="h1">14/09/2013</rich_text><rich_text>
I'm back. Where did I stop? Hmmm... interesting... great. I remember I though about the do-I-need-lists question. If I'm not mistaken, I decided the order of the elements needs to have some meaning. It needs to follow some rules. And then, the order can always be deduced from the meaning, thus there's no need to have explicit order in the files.
For example, assume I want to make a list of items ordered by time-added, i.e. I add each item to the end of the list. Then I want to export the list to some application and see it there, in the same order. Without the order mattering, it will probably not happen. How does Idan solve that?
Easily. With each item I add, I also mention a serial number or the date/time. Then, the application can order the items by serial, or by time. But now this answer raises a new question: What if people very frequently care about order, and always adding indices by hand would be unnecessarily cumbersome? Should there not be a way to just add items in a simply list, and have the indiced be generated automatically?
Very good question. Maybe it's worth adding the feature. But then, what if an item is added in the middle? Change the indices stored in the database? And how should we implement it? Well, here's an initial idea.
In general, objects are all declared under a namespace. There is no further nesting. Only relations. So where do lists fit in? Well, assume you want to make a shopping list and the order matters. Normally it would set, i.e. a </rich_text><rich_text style="italic">ShoppingList</rich_text><rich_text> class which has a property </rich_text><rich_text style="italic">product</rich_text><rich_text> whose type is </rich_text><rich_text style="italic">string</rich_text><rich_text> and has unlimited cardinality. Then, you could say a </rich_text><rich_text style="italic">list</rich_text><rich_text> is like having a special </rich_text><rich_text style="italic">OrderedProduct</rich_text><rich_text> class instead of the plain string, which has two properties: one is the string, and the other is the index/serial.
Hmmm... is it safe to automate? I mean, should it </rich_text><rich_text style="italic">really</rich_text><rich_text> work like that, with dummy classes? It sounds like a bad idea. Hmmm...... mmmmm..... mmmmmm...... nah. You know what? For now let's ignore it, and later I'll decide. I could simple put it into the model: The cardinality spec can specify whether it is ordered or not, or the actual value specification can do that, e.g. writing the values inside {} or [] to declare ordered VS unordered.
For the API, let's assume values specified in the - wait. If the order is specified in values, the code doesn't know what to expect: ordered or unordered. You can </rich_text><rich_text style="italic">never</rich_text><rich_text> be sure, and have to test before </rich_text><rich_text style="italic">every</rich_text><rich_text> time you do something like </rich_text><rich_text style="italic">object["items"][5]</rich_text><rich_text>. It's bad. On the other hand, why would a model enforce order. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: For now, there is </rich_text><rich_text weight="heavy">no</rich_text><rich_text> automatic ordering.
Now, here's the API again, a bit updated (removing some of the ordering-related functions). I'll add it tomorrow...
</rich_text><rich_text scale="h1">15/09/2013</rich_text><rich_text>
So here's the API with most of the ordering removed.
</rich_text><rich_text justification="left"></rich_text><rich_text>
Now I have a new interesting question. Should values be stored as strings or as integers/floats/booleans/datetime/etc.? I tried to find the Scalar field in </rich_text><rich_text style="italic">yaml-cpp</rich_text><rich_text>, and it seems to use a std::string and convert it every time something else needs to be returned, e.g. an integer. It probably makes sense, because yaml-cpp works with documents, i.e. text. But </rich_text><rich_text style="italic">Idan</rich_text><rich_text> works with typed data. The text is just part of the computer-human interface, nothing more.
For now I'll assume I store the actual type, not a string. I can do it using a Variant. Better than using a manual hacked union. GLib and Boost both provide Variants, and glibmm has a Variant wrapping GLib's GVariant. This will probably make my life easier.
I have an idea. Before I work on the most high-level interface, I want to go back to </rich_text><rich_text style="italic">Alder::Object</rich_text><rich_text> and make sure it does all the things I need. Let's start.
First, let's see how the value map is implemented. Object has a map which maps a property to a set of strings, i.e. the values. Hmmm... wait. There's a deeper problem. Optional properties!
That's right. I forgot. Some properties are optional, meaning they don't have any value at all if not mentioned. Not even a default value. One Person object can have a mail address field, while another has none at all. Should even cases of "none" have "none" as a default value?
Good question. In order to answer it, I need to figure out whether it makes sense to </rich_text><rich_text style="italic">always</rich_text><rich_text> have a default value, or sometimes no value ever makes sense, at all. Here's an example: Not all tasks have a due date. You could choose a due date of 01/01/00 to be the default, but that's just a hack. What if this due date makes trouble when we reach year 2100? I mean, 01/01/000 is not </rich_text><rich_text style="italic">really</rich_text><rich_text> the </rich_text><rich_text style="italic">due date</rich_text><rich_text> of the task. It has no due date at all, and that's how it should be.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Make the getter throw an exception (or undefined behavior, maybe in the lower level) if the property is not defined, but supply a function to check whether a property is defined, so that the user can check that for optional properties before she tries to access them. For required properties, it simply always returns </rich_text><rich_text style="italic">true</rich_text><rich_text>.
</rich_text><rich_text scale="h1">16/09/2013</rich_text><rich_text>
</rich_text><rich_text weight="heavy">Question</rich_text><rich_text>: I can put all properties in a single map, where properties with a single value are stored as a container containing a single item, while more-than-one values are containers with more than one value. But I can also create two separate lists, where one list is only for single-property values and the other for the rest. Which option should I prefer?
I think I already asked myself this question, when I implemented </rich_text><rich_text style="italic">Alder::Object</rich_text><rich_text>. I decided they'd have one unified map, because it makes iterators very simple. It's not a natural operation for the user, but assume you write a GUI for editing </rich_text><rich_text style="italic">Idan</rich_text><rich_text> models. Then you may want to iterate through all the object's properties, without knowing their names in coding-time.
</rich_text><rich_text scale="h1">17/09/2013</rich_text><rich_text>
Two interesting questions here:
1) How to develop a general-purpose iterator which iterates on two containers, jumping from the end of the first one to the beginning of the second one?
2) What is the difference between </rich_text><rich_text style="italic">unified</rich_text><rich_text> and </rich_text><rich_text style="italic">separate</rich_text><rich_text> approaches, besides the iterator?
I'll start with the second question.
</rich_text><rich_text scale="h1">18/09/2013</rich_text><rich_text>
Yes. The second question. In a </rich_text><rich_text style="italic">unified</rich_text><rich_text> setup, there's a map from property to set-of-values. In a </rich_text><rich_text style="italic">separate</rich_text><rich_text> setup, there's an additional container, which is a map from property to value. This is a bit faster than the first container, and since many/most properties will probably have a single value, it may make a big difference. Maybe. Not necessarily. It depends on how users use the library.
There's another option: Create a base class called Value, and have SingleValue and MultiValue derived classes. The problem: I'll have to call virtual methods and have another level of indirection and memory allocation. For best speed, I should use a direct mapping to values, i.e. the value is stored by-value. To be honest, I'll probably be using a variant, but with SingleValue, this variant would be allocated dynamically.
I can also add the set-of-values to the variant. Then I can have a single container, and let Variant handle the errors. The problem is that adding a class type could result in a non-optimal variant, so it would be faster to put the sets in a separate container. Allow me to read a bit more about Boost.Variant...
I'd like to suggest some options:
1 Make a variant for all possible types, with invalid things causing exceptions
2 Make a variant with types deduced at build time from the model, and then invalid things cause compiler errors
3 Allow switching between exception and no-implementation, to allow easy debugging
4 Make a variant for trivial for scalar types, and a separate set
5 Make a hierarchy of variants (probably like in glibmm)
6 Create an interface for variants/scalars, so that the implementation (boost, glibmm, etc.) can change easily
I guess my I should check YAML's data types before I finalize mine, but for the example, let's take Idan's types:
- boolean
- integer
- real
- date
- time
- string
Quite simple. Time and date can be stored in simple structures, to make them fast and easy to use. It would probably be faster and more flexible than using Glib's classes. Something like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Strings, if they impose an efficiency limit, can be stored as pointer-to-char instead of std::string, but that could create a serious problem when getting or setting them: I'd have to somehow take over the string's allocated memory, otherwise I would have to copy it. Of course, if Boost.Variant already takes this into account, I can use std::string directly.
In the catch-all approach, there's a single Variant class which can contain any of these types and when it is set to a new value, it is a compiler error to use an invalid one. Actually I'm not sure how Boost.Variant handles this, but my wrapper will simply take an object and do a copy/move. Then, this object can be costructed using any constructor. And hopefully the compiler can completely eliminate the move, i.e. like </rich_text><rich_text style="italic">emplace</rich_text><rich_text> in STL containers.
Let's look at the code again. The example I wrote few days ago, on 15/9. The expression </rich_text><rich_text style="italic">object["size"]</rich_text><rich_text> returns something which can convert to its real value, e.g. int, but if I use such an interface, I should also be able to set a value and offer iteration. And in any case I have to check the passed value, so I can't just return a reference to the internally stored integer.
As you can see, I have two interfaces in the example: One uses only Object, and the other involves a property proxy which allows the nice convenient usage of operator []. Instead of mixing, I think it's worth trying to use one as a low-level interface, and use the other one as a wrapper. If impossible, simply offer both in parallel somehow. We'll see, I'll try.
I'm going to do some actual coding now, so I guess it's time to choose types. Let's read some YAML tutorials...
Okay. Confusing. I opened the YAML specification, version 1.2. I saw the word schema, which is confusing because I'm used to XML schemas. What's a YAML schema? I kept reading and found all kinds of </rich_text><rich_text style="italic">type</rich_text><rich_text> definitions, and examples. Things like unordered map, ordered map, sequence, float, integer, set... anyway, it looks like the main difference is that I don't have a </rich_text><rich_text style="italic">binary</rich_text><rich_text> type. I think YAML encodes it as Base64. XML probably does that too. Do I need a </rich_text><rich_text style="italic">binary</rich_text><rich_text> type? I could implement it using a bit vector. Either vector<bool> or some Boost alternative.
Hmmm... basically, images and binary data are not supposed to be inside data files. They can be in binary files, and data can then link to them. DECISION: for now, no binary data.
Great. Let's start my Object class... I'm adding it to Alder as Object_new1 and Object_new2, each will get one of the interfaces. Then I'll see if and how I can combine them. No, wait. It would cause mess. And what about autotools? Is it safe to have files lying there, considering autotools? I don't know. Good question. I'll answer it in my autotools guide. For now... I'll create a new folder called sandbox. A new git repo. There I'll add these things. Great! Hmmm... yes? Or no? Maybe a branch?
Oh, I forgot! I can create a branch, and work there! Awesome! But now a question: How will I track branches? How will I make sure I don't forget where I stopped in a branch? And which branch I was working on? Answer: I would have to attach some diary to each branch. But not put it inside the branch, because I would need to merge them later. Hmmm... maybe it's a good idea. I'll think about it. For now, forget branches. Or... hmmm...
This code is supposed to end up somewhere. Right? I'll need to commit it anyway. Why make change-tracking harder? I can just add it right now. DECISION: I'm adding it directly to Alder, to the master. Alder is too young to require branches... the master itself is unstable (actually I don't even have autotools files yet).
Classes I'm adding:
Object_low
Object_high
PropertyProxy
I'd like to think about conversion operators. In order to allow objects and variables to be initialized from expressions like </rich_text><rich_text style="italic">task["start_date"]</rich_text><rich_text>, the PropertyProxy has to be implicitly convertible to all appropriate types: string, int, float, boolean, etc. Actually... wait. Maybe I can use the </rich_text><rich_text style="italic">convert</rich_text><rich_text> functor like in yaml-cpp. Wait a second, I'll check it...
Okay, yaml-cpp allows you to define conversions, and then a node can be created from your type, and converted into your type. When converting to a type, it must be specified explicitly as a template parameter. In the Object_low class I have these options:
object.get ("param")
object.get <float> ("param")
object.get ("param").as <float> ()
The last one is probably not necessary. Let's take the first two:
object.get ("param")
object.get <float> ("param")
If I use the first one, </rich_text><rich_text style="italic">get</rich_text><rich_text> will have to return a proxy, which can convert through non-explicit conversion operators to all scalar types. In the second case the type is specified directly. It does make sense to want a date to be returned as Glib::DateTime or any other specific class, but this can be done by - oh, wait. Glib::DateTime already exists, which means you can't write a new constructor for it. Hmmm... okay, assume I keep just the scalar types I choose. Which types are allowed as the parameter?
I can simply add a static assertion inside the function, to make sure the type is one of the ones allowed. Hmmm... yes. In this case the type is obvious, but the user still has to supply it. Is it justified? To always supply it? What if conversion is explicit?
Assume I use the proxy. Then it can convert to all scalar types. Is it safe? Depends on the types which can be constructed from the scalar types... hmmm... I need to read more, and run some tests.
Let's take the specific-type approach. Either I add functions like </rich_text><rich_text style="italic">get_string</rich_text><rich_text>, </rich_text><rich_text style="italic">get_int</rich_text><rich_text>, </rich_text><rich_text style="italic">get_float</rich_text><rich_text>, etc., or I use the template parameter. It's not a big difference. Actually it's the same thing exactly. The methods would be generated because they are templates, but otherwise it's the same.
Except for one thing. I can add types. Assume you want to set your dates from Glib::DateTime, and create Glib::DateTime from your date. Makes sense, right? In order for </rich_text><rich_text style="italic">object.get<DateTime>("date")</rich_text><rich_text> to work, you have to define how the conversion is done. Let's do it like yaml-cpp, i.e. allow a returned boolean to contain the success/failure flag. But what about the return value? I can use a std::pair, or take a parameter. Hmmm... let's start with pair, and later consider changing.
Wait a second. I just realized it's not the same thing at all. In yaml-cpp, conversion is possible for complex objects too. For example, it's like taking a Todo::Task and converting it into an Alder::Object. Of course I'm talking about a Task which has regular static definitions, like Partager::Task. Hmmm... considering Alder's design, these conversions may not be necessary. Currently it is preferred that data classes </rich_text><rich_text style="italic">wrap</rich_text><rich_text> Alder objects. But sometimes it makes sense to create an Object from a Task. Then, the user can define a function.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: For now, no conversion functions. So the question is whether I'm going to use a template parameter. DECISION: I'll use functions for now, because of subtle issues like whether float or double is used. Hmmm... wait, this actually could be settled by using template parameters. But if I use functions, I can use </rich_text><rich_text style="italic">get_real</rich_text><rich_text> and easily change the return type. I can also start with </rich_text><rich_text style="italic">get_float</rich_text><rich_text> and always add </rich_text><rich_text style="italic">get_double</rich_text><rich_text> later, possibly making </rich_text><rich_text style="italic">get_float</rich_text><rich_text> deprecated. Hmmm... good question, isn't it?
Again, the types in Idan are:
- boolean
- integer
- real
- date
- time
- string
So I would need 6 functions. Hmmm... damn it, how do I choose? If I don't use the template, there won't be room for extending for arbitrary types. On the other hand... I don't have working code to examine. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I'll start with functions. Later changing to template will be easy anyway.
Adding them to Object_low...
Good. Here's an idea:
</rich_text><rich_text style="italic">Alder::Object</rich_text><rich_text> doesn't use property strings. It uses pointers to Property objects. This allows storing the pointers, and then access to properties in the application does not at all involve string hashing. Instead, pointer hashing is used, which should be much easier. Property names are actually short anyway, but I guess avoiding the loop removes a few operations. On the other hand, for one-time usage, it's faster to type in the string literal than to store pointers. It's convenient.
What I'm saying is that the interface very much depends on your needs. And on your usage patterns. So I suggest to try defining an all-purpose Object, and have several wrappers suited for specific usage patterns. First I want to collect all the possibilities, and see it some can be implemented using others. Having them all under one class will help make the implementation efficient, and everything else will be just thin wrappers.
I'm starting a new class, Object_omni, which will contain *all* my ideas. Then I'll start making the decisions I have to make, in order to stabilize the interface.
</rich_text><rich_text scale="h1">19/09/2013</rich_text><rich_text>
I have a suggestion. The word </rich_text><rich_text style="italic">property</rich_text><rich_text> is confusing, because it refers to three things:
- Idan property entity
- Property specification in an Idan class
- Property value in an Idan object
I'd like to give these things three different names, and use the names in the API. Here's a suggestion:
- Property
- Field
- Value
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Accepted.
There's a new problem. I think returning an iteration interface by reference will not work. I need to return it by value (or store a const interface in addition to the regular one). It's not something I could foresee, but GCC game me the clue when I tried to run a proxy experiment (proxy.cpp). Here it is.
The IterationInterface has a </rich_text><rich_text style="italic">reference</rich_text><rich_text>. That reference is a non-const reference to the container, on which we want to iterate. As long as the object holding the container is const, we're fine. But what if it's const? Since the IterationInterface is stored as a member, it is a const object too, and so is the container. The problem is that the </rich_text><rich_text style="italic">reference</rich_text><rich_text> inside the IterationInterface is </rich_text><rich_text style="italic">to-non-const</rich_text><rich_text>! References themselves are always const, but like pointers, a const pointer/reference cannot be changed but can point either to int:
int* const ptr;
Or to const int:
const int* const ptr;
The problem is that the pointer being a member of a const object, does </rich_text><rich_text style="italic">not</rich_text><rich_text> make it point to </rich_text><rich_text style="italic">const int</rich_text><rich_text>. It cal still change the pointed object; it just can't point to another object. As a result -
Wait a second. I just tried another experiment, and now it works. Returning by value seems to require a separate ConstProxy class which holds reference to const Foo, but return by reference is different. Why? Because Proxy is created in the constructor, which runs the same both for const and non-const Container objects. So Proxy is initialized with </rich_text><rich_text style="italic">foo</rich_text><rich_text> and it works.
Listen. I tried return by reference, and it works. The problem with return by value is in a const function like </rich_text><rich_text style="italic">get_proxy () const</rich_text><rich_text>, any reference to an internal object is const too, therefore const Foo cannot be assigned to Foo. It would remove constness, which is of couse invalid.
</rich_text><rich_text weight="heavy">BUT</rich_text><rich_text>, it's not so simple. There's a flaw in my design: Even a const Proxy holds a reference to a non-const Foo. That means it can call non-const methods of it. That's right, it can. It gets a reference to Foo in Container's constructor, and from now on it is able to call non-const methods on Foo, even if the container is const! The good news are, it is internal to Proxy. As long as const Proxy exposes only non-changing methods (i.e. returns only const_iterator), it's okay. The problem is that these const methods can still make changes. I don't like it. Hmmm... is there a chance that a design with two classes, Proxy and ConstProxy, is universally safe?
I'll think about it. For now, I'll keep what I have right now. Next!
Let's continue working on Object_omni...
I forgot completely!!! Object fields can have another type! A seventh type!!! Guess which! </rich_text><rich_text weight="heavy">Object</rich_text><rich_text>. An object's property value can be </rich_text><rich_text weight="heavy">another object</rich_text><rich_text>. I could store objects in shared memory, but since the model manages memory, I'll keep its centralized memory management model for now (it definitely saves the reference counting overhead, although I doubt it ever makes a difference).
Updating the classes...
</rich_text><rich_text scale="h1">20/09/2013</rich_text><rich_text>
I think Object is going to require a bit more attention than expected.
I just finished an initial version of Object_omni, which doesn't yet include interfaces for all the features required by the example code. But it already has a huge number of meember functions, which begins to remind me how Node became huge recently. I need to to some planning, listen carefully.
Currently, Object_omni has a very high level of redundancy. Many functions accept fields in three forms - iterator, Property and name string - and many functions are very thin wrappers around others. Before I suggest a solution, here is the original design.
I tried to figure out the best interface for Alder::Object, but then I realized it's too difficult to choose. The reason is quite simple: Alder is critical to code readability and convenience of the usage of </rich_text><rich_text style="italic">Idan</rich_text><rich_text> as a system. It is the public face of </rich_text><rich_text style="italic">Idan</rich_text><rich_text> to application delelopers. The only reliable way to develop a good interface is to have experience, and I have none: both in general, and specifically with Alder. I did write some code examples to help me, but different patterns of usage may require different designs.
So in order to make it flexible and modular, I decided to have one Object which implements </rich_text><rich_text style="italic">everything</rich_text><rich_text>. Including thin wrappers. Then, </rich_text><rich_text style="italic">Alder::Object</rich_text><rich_text> can wrap it with its simple interface, and I can change </rich_text><rich_text style="italic">Alder::Object</rich_text><rich_text>'s interface without any implementation changes, since </rich_text><rich_text style="italic">Alder::Object</rich_text><rich_text> would be just a wrapper. And the implementation would be efficient, because all the interfaces would be implemented in one place.
Now I started running into problems. Object_omni quickly became huge and scary. I began to realize the tons of redundancy it has can make it very difficult to work with, and make it very unattractive to low-level developers. Instead, I have a new idea for it.
</rich_text><rich_text scale="h3">Concept 1: Errors</rich_text><rich_text>
The idea is simple: Let base objects return success/failure booleans, and high level wrappers throw exceptions instead. This way the validity of conditions is not tied too strong to the implementation.
</rich_text><rich_text scale="h3">Concept 2: Modular Design</rich_text><rich_text>
1 Have a simple Object class with a non-redundant API similar to the API for STL containers </rich_text><rich_text style="italic">unordered_set</rich_text><rich_text> and </rich_text><rich_text style="italic">unordered_map</rich_text><rich_text>. This Object represents a collection of properties and values, not tied to any concept. However, its design will follow an important guideline: Once the properties are chosen, they should not be changed. In other words, fields are not removed or added on the fly. It's possible to add and remove at any moment, but any operation which relies on field existence will never create or remove it on the fly, and instead report an error.
2 Have wrappers for Object. These wrappers in general have the following roles:
* Supply a rich function interface (good for bindings and non-C++ developers)
* Handle errors by throwing exceptions, when rules of </rich_text><rich_text style="italic">Idan</rich_text><rich_text> objects are violated
* Use a Class to initialize an Object's fields, and not allow further changes of them
* Supply a convenient proxy interface for application developers
* Supply access to properties through strings
Since the only class which needs these modularity upgrades is Object, it would be strange to give Object its own namespace. Cist, Sprak, Strom, etc. are whole systems. What will I do for Object? I have an idea.
I'm going to use new names like these if necessary: ObjectBase, Instance, Unit. And I'm going to design the highest level Object now, then put things in the middle.
</rich_text><rich_text scale="h1">21/09/2013</rich_text><rich_text>
The next steps are:
* add all the interfaces from the example to Object_omni
* write a simple minimal STL-like free object
* write a highest-level object for app usage
Before that I want to think about something. What does "free object" mean? There are at least three types of freedom for objects:
1. Not depend on property types
2. Not depend on field cardinality restrictions
3. Not limit real-time changes to properties
The first freedom is what made me want to think. If an object doesn't care about types, does the property matter at all? What are properties exactly?
A property is a name and a type. That's all. The type can be a union, a range, an enumeration, etc. or a primitive type, or an Class. So what is a free object, in the first freedom? Ideas:
* properties can have any value
Hmmm... that's all, I guess. Simple. In a free object, properties are just names. This gives me an idea: Have a FreeProperty class which doesn't have a type, and accepts </rich_text><rich_text style="italic">any</rich_text><rich_text> value. Then, it can have a derived class Property which has a type and accepts only values which match it. The downside: Checking the type, which will happen every time a value is changed, will be a virtual function. It cannot be inlined. Hmmm... how critical is it?
Actually I would probably have a virtual call anyway. The type test could run by giving each type a class with a virtual function. Or it could work through a </rich_text><rich_text style="italic">switch</rich_text><rich_text> statement. We'll see.
Before I decide, here's another question. Why have FreeObject and FreeProperty at all? Are they </rich_text><rich_text style="italic">useful</rich_text><rich_text> for anything? Why can't the most low-level object accept only values which match property's types? Hmmm... hey! I have an idea! I already offered the FreeProperty base class. Instead I can -
Hmmm... let me explain. I can have just Property, and simple have FreeObject </rich_text><rich_text style="italic">ignore</rich_text><rich_text> the property's type. It avoids virtual calls, because Object would simply </rich_text><rich_text style="italic">wrap</rich_text><rich_text> Object. But it's somewhat a bad design, because Property does have a type after all, and ignoring it may be unexpected by the user.
I think I'll... hmmm... question: Do I need a FreeObject with no type support? Is it useful? In </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, all properties must have a type. There could be an accept-all type, but in general everything has a type. It's not like in YAML, where you can just write your data and ignore types. Here you </rich_text><rich_text style="italic">have</rich_text><rich_text> to specify them. Hmmm... wait. Where do I specify types? In the model. Only in the model. There are no types in the data itself. Data files would look like this, in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> syntax:
object Task task:
content do something
start_date 21/09/2013
priority high
So in practice you don't see any types here. You set fields to values which make sense, but what if there were no types at all? What if it was up to you? What if you wouldn't have to bother to choose a type, so things like "one day" or "next week" as a date would just work on the fly? The problem is that semantic desktop integration would be a problem, because other applications wouldn't know what to expect. But no doubt, for custom personal usage, not having types would make things easy.
So... free object or not free object? Another idea: A free object can be acheived by not doing any type checking. If a user writes or generates a model where all types are accepted, and thus all values, there is no need to make any efforts to create a free object! Just use regular properties which accept all types.
Before I accept this decision, let's think how it works. Assume there's an easy way to choose to accept any value, e.g. a type called </rich_text><rich_text style="italic">any</rich_text><rich_text> which takes any primitive and any object. Then the user can create a simple model in which a class has properties with the </rich_text><rich_text style="italic">any</rich_text><rich_text> type. Or even better: fully free objects are not even bound to any class! So such a user can just write data, not related to </rich_text><rich_text style="italic">Idan</rich_text><rich_text>, in which there are objects with arbitrary fields with any value being legal.
Actually, such a file would be just like YAML. Maybe even closer to JSON (I don't know much about JSON). It would probably be just a subset, because YAML has ordered lists while </rich_text><rich_text style="italic">Idan</rich_text><rich_text> doesn't have then. But it could be useful as an easy fast way to describe data. Question: Would it be better than YAML in any way? Is it worth at all to support such a feature? Answer: Probably not better than YAML because it is a subset, but it could serve as a basis for my implementation of YAML in C++. Or as a basis for some other dynamic object systems. Who knows.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: FreeObject is already class-independent. By using any-value properties, type independence can be achieved without any changes to Alder. Therefore, FreeObject </rich_text><rich_text style="italic">will</rich_text><rich_text> consider types. Later I'll consider moving type tests to a derived class, to make FreeObject easier to use in other systems.
Let's continue working...
Great. I still need to write ValueProxy (and FieldProxy is probably unnecessary, unless I use them as brother classes, one for multi-value fields and the other for single-value fields), but Object_omni seems to have the whole interface now.
Time to start the FreeObject. I'll create a new file Object_free and start creating a minimal interface. As a reminder, here are the tasks again:
* [DONE] add all the interfaces from the example to Object_omni
* write a simple minimal STL-like free object
* write a highest-level object for app usage
</rich_text><rich_text scale="h1">23/09/2013</rich_text><rich_text>
I need another experiment. I want to remove all those ugly </rich_text><rich_text style="italic">get</rich_text><rich_text> and </rich_text><rich_text style="italic">set</rich_text><rich_text> functions. If I don't do that, iterators' operator* won't exist and it will be very confusing. Since the operator* would have to return a ValueProxy, there would be no need to have </rich_text><rich_text style="italic">get</rich_text><rich_text> and </rich_text><rich_text style="italic">set</rich_text><rich_text> anymore. Their functionality would be implemented using something like </rich_text><rich_text style="italic">at</rich_text><rich_text> and </rich_text><rich_text style="italic">operator[]</rich_text><rich_text>, which would return ValueProxy too.
In order to test it, I'm going to write an experient with a simple ValueProxy and see what happens.
Great, it works! But I need to take care of a workaround: if char* is passed for a string, it can be caught by bool because a pointer is implicitly convertible to bool. Either I add a ValueProxy::operator= (const char*) which calls the operator= for string, or I make sure string catches it and not bool (maybe changing their order in the class definition will help, maybe not).
Another thing is streaming: It doesn't work automatically with streaming because streams have operator<< for many types, and the compiler doesn't have a single best typecast to choose. I'll write an operator<< for ostream and maybe operator>> for istream which work with ValueProxy and make things smooth.
Results of putting operator string before operator bool: It doesn't help. I'll try to add operator const char* and pass it to the operator string. Then we'll see what happens...
Perfect. It works! This new operator= (const char*) solves the problem. I'm glad I found it early and fixed it. Now, let's see how to write operator>> and operator<< for streams... hmmm done. I just need operator <<. Or... no, wait. How do I write operator >> for a proxy? I'll make some tests... hmmm... let's see. If a number is sent, what should happen to the proxy? Should it take a string or a number?
I see two options: always take the value as a string, or have a list of priorities: a integer is always int, a real number is always double, </rich_text><rich_text style="italic">true</rich_text><rich_text> and </rich_text><rich_text style="italic">false</rich_text><rich_text> are always bool and so on. But I'm not sure it's the best behavior. What if there's a string </rich_text><rich_text style="italic">"true"</rich_text><rich_text>? I think it's better to wait and see whether, when how and why I use operator >> with a proxy.
Let's continue with Object_free... (try to remove get and set, and use operator[] and at)
</rich_text><rich_text scale="h1">27/09/2013</rich_text><rich_text>
I think I'm done with the initial interface of Object_free, not yet taking care or ValueProxy and ConstValueProxy. Even a const ValueProxy and a const IterationInterface can use their reference-to-nonconst to make changes to the object. The only way to protect the referred object is to define new classes ConstIterationInterface and ConstValueProxy which work somewhat like a const_iterator, i.e. they have a reference-to-const and thus can't do </rich_text><rich_text style="italic">any</rich_text><rich_text> changes to the referred object.
Even if these classes don't exist, I should still use them instead of references like const Fields&. This way I can decide internally how they work, and whether I really use two different classes. After all, everything is safe as long as ValueProxy never changes the Object in its const member functions.
How do I decide whether it's important?
* Look at libstdc++ headers (e.g. Vector's iterators and Set's iterators)
* Read about it on the web, e.g. why iterator and const_iterator might be the same class
* Try to find a way how these extra permissions given to ValueProxy can lead to security problems
Okay, listen. I checked StackOverflow, and it looks like the iterator classes </rich_text><rich_text style="italic">really</rich_text><rich_text> shouldn't be the same because one uses a reference-to-const while the other doesn't. </rich_text><rich_text style="italic">Boost.Iterator</rich_text><rich_text> already provides base classes for definition of iterators, but it doesn't do that for general-purpose things like iteration interfaces.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Create templates/base classes (look at links I found, it can be done using a single class where the reference type is chosen using std::conditional) for definition of interface helpers, i.e. a design pattern where a container returns an object containing a reference to the container or a member of it, and offers a sub-interface. I can call this template/base class Sgp::Reference or Sgp::SubInterface or something like that.
Then, IterationInterface and ValueProxy can both be based on this Sgp::Reference class.
</rich_text><rich_text underline="single">Tasks for next time</rich_text><rich_text>:
</rich_text><rich_text weight="heavy">1</rich_text><rich_text>. Write an interface for ValueProxy, assuming a reference-to-nonconst member (no need to define the member for now, just the interface). Use the code examples I wrote recently (find them above) and commented code in Object_free. This will ensure all the functionality is consistently offered by Object_free (with the help of ValueProxy, of course).
</rich_text><rich_text weight="heavy">2</rich_text><rich_text>. Take care of the </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text> above, i.e. read the links I found and try to write Sgp::Reference and then write ValueProxy and ConstValueProxy based on it, as well as IterationInterface and ConstIterationInterface.
</rich_text><rich_text weight="heavy">3</rich_text><rich_text>. Decide whether I return the subinterfaces by value or by reference. In case of reference, does it mean I may need to store both const and nonconst versions as members? And what if I return temporary objects but the return type is still reference (allowing me to switch between stored object and temporary object easily)?
</rich_text><rich_text scale="h1">27/09/2013 - Morning, after I slept</rich_text><rich_text>
I have an idea. It can be the addition and removal of C++ types (bool, int, Time, Date, etc.) easier and save a lot of code duplication. Here it is: </rich_text><rich_text style="italic">ValueProxy</rich_text><rich_text> has insert/erase/operator=/cast operator for all C++ types used to represent </rich_text><rich_text style="italic">Idan</rich_text><rich_text> types. But their code is mostly identical, if not precisely the same. So I can define a class template ValueProxyBase or TypedValueProxy which takes a type as a template parameter and implements insert, erase, etc. for that type. Then, it is enough for ValueProxy to inherit instantiations of this class, one for each type it wants to use.
The problem here is the access to the Object. If each TypedValueProxy holds its own reference, I'll end up with ValueProxy having 8 identical pointers, for 7 types and the IterationInterface! 8 pointers is </rich_text><rich_text style="italic">huge</rich_text><rich_text> compared to how small ValueProxy can be! A </rich_text><rich_text style="italic">single</rich_text><rich_text> pointer is enough!
Hmmm... what do I do? I have two ideas:
* Use virtual inheritance, but make sure there's no overhead
* Use CRTP somehow (i.e. Derived is a template parameter of Base) to avoid the 8 pointers
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Assume a class TypedValueProxy which, instead of storing a pointer to the Object, gets the pointer by down-casting itself to ValueProxy and using ValueProxy's member!
Hmmm... sounds great! A cast is a no-op in actual binary code. So I'd have a single pointer. I can put the pointer getter in a function like I did for Node, and then creating a regular non-CRTP version is as easy as making that function return </rich_text><rich_text weight="heavy">this</rich_text><rich_text> or a member object, without any casting. Great!
I'll try to write a TypedValueProxy...
Okay, I have an initial interface. Now I need to examine usage of enable_if and SFINAE in order to enhance type safety. If I can't figure it out easily I'll explain the problem here in detail...
Forget it, for now. It depends on the implementation, i.e. depends on the usage of boost::variant. I'll take care of this issue later. Right now, since I have the basic interface in place, let's go back to the tasks and see where I stopped.
</rich_text><rich_text foreground="#e206dee21e6e">* [DONE] add all the interfaces from the example to Object_omni
* write a simple minimal STL-like free object
* write a highest-level object for app usage
</rich_text><rich_text foreground="#e206dee21e6e" weight="heavy">1</rich_text><rich_text foreground="#e206dee21e6e">. Write an interface for ValueProxy, assuming a reference-to-nonconst member (no need to define the member for now, just the interface). Use the code examples I wrote recently (find them above) and commented code in Object_free. This will ensure all the functionality is consistently offered by Object_free (with the help of ValueProxy, of course).
</rich_text><rich_text foreground="#e206dee21e6e" weight="heavy">2</rich_text><rich_text foreground="#e206dee21e6e">. Take care of the </rich_text><rich_text foreground="#e206dee21e6e" weight="heavy">IDEA</rich_text><rich_text foreground="#e206dee21e6e"> above, i.e. read the links I found and try to write Sgp::Reference and then write ValueProxy and ConstValueProxy based on it, as well as IterationInterface and ConstIterationInterface.
</rich_text><rich_text foreground="#e206dee21e6e" weight="heavy">3</rich_text><rich_text foreground="#e206dee21e6e">. Decide whether I return the subinterfaces by value or by reference. In case of reference, does it mean I may need to store both const and nonconst versions as members? And what if I return temporary objects but the return type is still reference (allowing me to switch between stored object and temporary object easily)?</rich_text><rich_text>
I want to implement Object_free fully now, but before that I want to finish task 2. I'll real about iterator code duplication and come back.
Fine. Austern's idea is to use a template parameter. A boolean denoting whether our iterator is const. I don't want to do anything specific for iterators because </rich_text><rich_text style="italic">Boost.Iterator</rich_text><rich_text> should do that. If it doesn't, I'll know only after I try it. Until then, I work on a general purpose solution.
So what exactly is the Sgp::SubInterface? There is an object type Object. Object has some internal piece called member, of type Member. Now, I want Object to be able to return subinterfaces:
Object:
SubInterface siface ()
ConstSubInterface siface () const
ConstSubInterface csiface () const
ConstSubInterface:
has reference to const Member, i.e. </rich_text><rich_text style="italic">const Member& member</rich_text><rich_text>
has methods which do non-changing operations
SubInterface:
has reference to Member, i.e. </rich_text><rich_text style="italic">Member& member</rich_text><rich_text>
has methods which do non-changing operations
has methods which make changes
I'll take a simple list of functions:
• empty (const)
• begin
• begin (const)
• cbegin (const)
• clear
Let's try to write them both in one class. Oh, wait. It's impossible, because </rich_text><rich_text style="italic">clear</rich_text><rich_text> doesn't exist in ConstSubInterface at all. Then let's write just the things which exist in ConstSubInterface:
class ConstSubInterface
{
public:
bool empty ();
const_iterator begin ();
const_iterator cbegin ();
private:
const Member& member;
};
We can't use it as a base for SubInterface, so let's make it a template:
template <bool V_const>
class SubInterfaceBase
{
public:
typedef std::conditional
protected:
};
Wait a second. I have a cool idea: I can return ValueProxy by value as is, and make it noncopyable!!! Then, there's no way to create a non-const object from a const one returned from a function. Now returning a temporary object is possible easily. In the worst case the return type can be a reference.
Why does it matter? Hmmm... SubInterfaceBase will have to hold just a const_iterator typedef. I think. Hold on. Assume I have a const Object. Then this should be possible:
const Object obj;
auto iter = obj[prop].begin ();
What will be returned? </rich_text><rich_text style="italic">Operator [] const</rich_text><rich_text> returns a </rich_text><rich_text style="italic">ConstValueProxy</rich_text><rich_text> or </rich_text><rich_text style="italic">const ValueProxy</rich_text><rich_text> or </rich_text><rich_text style="italic">const ValueProxy&</rich_text><rich_text>. In any case, they must have their </rich_text><rich_text style="italic">begin</rich_text><rich_text> function return a const_iterator. This is okay. Fine. Now this:
Object obj;
auto iter = obj[prop].begin ();
Now an </rich_text><rich_text style="italic">iterator</rich_text><rich_text> is returned. Good. We can use a const reference with a non-const object, and get a </rich_text><rich_text style="italic">const_iterator</rich_text><rich_text>. So... wait. Does it matter whether I use constness or not? Hmmm... Why does gtkmm not rely on constness? Idea: It has to allow TreeView rows to be copyable, so a const one can be copied to a nonconst one.
Should I really rely on constness? What if ValueProxy has some extra data, some of which is meant to be changed? Answer: I can use </rich_text><rich_text style="italic">mutable</rich_text><rich_text>. Hmmm... this is a good question. Very good question. I'd like to make a list of options before I proceed:
* Have a P member and return P& or const P&
* Make P noncopyable, return P& or const P& as temporaries
* Make P noncopyable, return P or const P as temporaries
* Have P and CP members and return P& and CP&
* Make P and CP noncopyable, return P& and CP& as temporaries
* Make P and CP noncopyable, return P and CP as temporaries
What downside does returning a reference have? Probably when copying. When returning a temporary, it can be moved. The compiler can optimize away the move, and avoid it completely. But when is the Proxy temporary moved anywhere? It's never moved. Returning a reference is enough. But can I really rely on constness?
The problem with using the same class is that the Proxy holds a non-const reference. So clearly, there must be two different classes. It still doesn't mean I can't use constness. Let's see. First let's define SubInterfaceBase again:
template <bool V_const>
class SubInterfaceBase
{
public:
typedef /*...*/ const_iterator;
typedef std::conditional</*...*/>::type iterator;
bool empty ();
iterator begin ();
const_iterator cbegin ();
protected:
std::conditional</*...*/>::type member;
};
Now things are much easier. SubInterface and ConstSubInterface will look like this:
class ConstSubInterface : public SubInterfaceBase <true>
{
};
class SubInterface : public SubInterfaceBase <false>
{
public:
void clear ();
};
Hey, I have another idea. In my specific case, ValueProxy can </rich_text><rich_text style="italic">store</rich_text><rich_text> and actual value, and be stored inside Object. Then, I can safely rely on constness because Value won't contain any references. How's that? Sounds like it solves all the problems.
Another idea: in the implementation, use a </rich_text><rich_text style="italic">member()</rich_text><rich_text> function which has a return value depending on constness. Then, as long as all access is done through the function, you're safe. When the proxy is const, the reference is const too.
Why can't iterators work like that? There could be a single iterator class with constness overrides! </rich_text><rich_text weight="heavy">Answer</rich_text><rich_text>: iterators are copyable and are returned by value. Their functions are not named: just operator++, operator* and operator->. As a result, making return types depend on a template parameter easily solves all the problems.
Take 10 seconds to relax.
Good. So, what do we have here? A part of the interface is accessible through a proxy object. This object may contain actual data, in which case it's not really a proxy, or it can contain a reference to the object or to some part of it. In the latter case, we can either store it or return a temporary.
When returning a temporary, and nonconst reference cannot be used. In other words, in order to return a temporary and still use a reference I have to use a const reference. Clearly that means I can't rely on constness overloading. If I use separate classes, it works but it's ugly because the returns types are:
const Proxy&
const ConstProxy&
Quite confusing. So, assuming I have a reference in the proxy, what do I do? If I need to store a single proxy, and I don't mind an extra pointer, I can add it as a member. Then I return a reference to it and rely on constness. Great. What if I can't?
Before I proceed, here are the conclusions I already had:
* If the proxy contains actual data
* rely on constness
* return reference
* If the proxy has a reference but can be stored without overhead or other issues:
* rely on constness
* return reference
* use </rich_text><rich_text style="italic">member()</rich_text><rich_text> private function to ensure const functions don't make changes
* If the proxy has a reference but making it a member it too much overhead
* ?
Let's solve the last part. Options:
* Use Proxy and ConstProxy and return them by value
* Use Proxy and const Proxy, returned by value, but make Proxy noncopyable for users
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Instead of using </rich_text><rich_text style="italic">member</rich_text><rich_text>(), I can make it one of my "official" design patterns by creating a class which implements this functionality. Maybe like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Perfect. Now, instead of using a member of type Member&, you use a member of type SafeReference <Member>. And have fun! Of course this is also a functor, so usage is </rich_text><rich_text style="italic">member()</rich_text><rich_text>, not plain </rich_text><rich_text style="italic">member</rich_text><rich_text>.
Making a single class is easier. But before I decide, I want to make sure it's possible. I'll write an experiment and see what happens when the return type is </rich_text><rich_text style="italic">const Proxy</rich_text><rich_text>.
Perfect. There are two options:
* Make Proxy's copy/move ctor/operator= private
* Give Proxy regular public ones, but copy takes a non-const reference (const versions can be private)
Which one should I choose? It's important for the interface. It's much easier to add functionality, than to remove. Is there any good reason proxies should be copyable by users? No! If proxies hold data, the user is not supposed to copy them. If they just hold a reference - still no reason probably. You're supposed to use Object::get to get a proxy, and act on it directly. Without storing the proxy for later usage! Only store a reference to Object if you need it.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Start with making them noncopyable and nonmovable.
I'm wondering. I want to write SafeReference, but I realized using operator-> (since operator . cannot be overloaded), like in </rich_text><rich_text style="italic">member->func ();</rich_text><rich_text>, is nicer than </rich_text><rich_text style="italic">member ().func ();</rich_text><rich_text>. The problem is that member is a reference, not a pointer. So I had an idea, why not call it SafePointer? It would make operator-> very natural, but people would try accidentally to use operator* or maybe even new and delete. Since it's not really a pointer, non of these things would work, - - - wait a second. Assume I use SafeReference as is, and now for some reason I want a reference to the actual member. What do I do? Easy: call </rich_text><rich_text style="italic">member()</rich_text><rich_text>.
I have two options:
Name Getting Members Getting Reference
* SafePointer operator-> operator *
* SafeReference operator () operator ()
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Some people may prefer one, others may prefer the other. SafePointer also allows other things like new and delete and probably some advanced tricks. And SafeReference has its unique sides which I don't see at the moment. So I'll just supply </rich_text><rich_text weight="heavy">both</rich_text><rich_text>. I can also use an internal class which supplies everything as functions, and these two are just wrappers. Let's try... adding SafeReference, SafePointer and SafeProxy (the low level class).
Yes. Adding them... let's start...
Done!
I decided to implement ValueProxy using constness overloading. I guess that means I don't need any Sgp::Reference base class. Right? Oh, wait a second. I was working on the TypedValueProxy template. Let's see... I wrote an initial interface, with some functions waiting for the decision whether they'll be moved to TypedValueProxy as SFINAE templates.
I decided to implement as is, then decide. I'll probably use Boost.Variant. Let's start.
First, I need to decide how I'm going to implement Object_free internally. In simple words, do single-value properties have a separate container. I remember I wanted to try to write an iterator-over-two-sequences and see how it goes. Let's summarize the options. First the obvious ones.
* Have a mapping from properties to sets of values
* Have a mapping from properties to variants of <set-of-values, single-value-variant>
* Have a mapping from properties to sets, and from properties to value variants
Since property iteration is not supposed to be done by apps, and model-editor apps are plain GUI apps which don't need speed, I should probably prefer access speed over iteration speed. So using a combined field iterator is okay, if the underlying objects allows fast access to single-value fields.
Let's try it.
First, I need to choose C++ types to represent the </rich_text><rich_text style="italic">Idan</rich_text><rich_text> types. I checked what YAML says, and here it is: YAML's </rich_text><rich_text style="italic">integer</rich_text><rich_text> tag doesn't have any limits, but it allows an implementation to do anything: truncate, report error or use some other workaround. Of course dynamic languages tend to use dynamic integers, while lower level languages have specific sizes, like in C.
</rich_text><rich_text style="italic">Idan</rich_text><rich_text> is a data language. It should be possible to write any numbers, and the software should be able to handle them. For this to work, it may be worth to take a look at big number libraries. You know, just take a look. Then I'll decide.
* InfInt
* Hosted in Google Code
* Just one simple header file
* Very easy to use: huge numbers are initialized with strings, e.g. "845737453245398459384".
* Implementation is a vector of integers
* Boost Multiprecision
* Has limited-size pure C++ integers
* They start from 128, there's no 64-bit integer class
Forget it, there's an easy solution. </rich_text><rich_text style="italic">long long</rich_text><rich_text> is guaranteed to be 64-bit. I'll just use it. Then I'm safe. The question is what do I do with real numbers. I have these types:
float (32 bits, 4 bytes)
double (64 bits, 8 bytes)
long double (80 bits, 10 bytes)
I have an idea. In order to make it easy to change, I'll use typedefs. This way, changing to new types in later versions will be easy. I won't hide the type I use! I'll just use a typedef to make coding easier.
Another important question is signed VS unsigned. Should I allow </rich_text><rich_text style="italic">only</rich_text><rich_text> a signed integer? I can make sense in </rich_text><rich_text style="italic">Idan</rich_text><rich_text> to use an unsigned integer. Such a type can be defined very easily, using a </rich_text><rich_text style="italic">range</rich_text><rich_text> to define the type. In original </rich_text><rich_text style="italic">Idan</rich_text><rich_text> syntax it looks like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Hmmm... the only advantage of unsigned integer is the availability of more positive huge values. But how do I decide? There's no clear way to decide because unsigned integers are not currently part of the language. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: There will be no clear interface limitation over the types. The rule for users is, just pass your numbers to the API and it will work. Don't worry about types, just about sizes in case you use huge numbers.
I'll use two typedefs, since all I need is one for integers and one for real numbers. I'll call them Alder::integer and Alder::real. And I'll define then in types.hpp. I'll can also define Date and Time here, which aren't classes and don't really need their own headers.
I'm going to try </rich_text><rich_text weight="heavy">Have a mapping from properties to sets, and from properties to value variants</rich_text><rich_text>. This means I'll need to implement special iterators. How will it work exactly?
Assume I have two containers of types C1 and C2. A regular iterator adaptor over C1 could have a C1::iterator as a member, but in this case it's not enough. I need to store something else. Options:
* store a pointer to the C2 object to which it should switch
* store a begin iterator for C2
C1 and C2 have different iterator types, so I'll also need a way to detect which one is active. Iterators alone can't do that, i.e. I'll either need a third member, or use a Variant (which will probably have a third member too). That member indicates which iterator is active.
The problem is that the begin iterator may not be persistent. What if that item is removed, and now I hold an invalid iterator? A solution can be to hold a pointer. I still need two iterators or a variant, and in addition a pointer with which I can initialize the second iterator when time comes. I guess I can try different approaches and then do some profiling and see what's the fastest approach.
Anyway, first the data structure. I still need to see exactly how Variant works, but basically the idea is to have two members:
* map from property to variant
* map from property to set of variants
Question: Is there room here for ValueProxy to be stored, instead of being a proxy? Answer: Since I use two separate maps, there is no canonical form for ValueProxy to use. It basically can be a Variant of a Variant and a set of variants, but that works only for a unified container. I'm still not sure what's fastest. Anyway, I prefer not to force the interface into the implementation. Let's start with ValueProxy being a real proxy.
Here are the members in more detail:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Next, let's see how we define the Variant. Reminder, the types I need are:
* bool
* Alder::integer
* Alder::real
* Alder::time
* Alder::date
* std::string
* Alder::Object*
</rich_text><rich_text scale="h1">28/09/2013</rich_text><rich_text>
What members will the ValueProxy contain? I don't want it to use two polymorphic derived classes, because it would require more time and memory than using a single class which uses comparisons inside. For all operations involving changes to values, ValueProxy needs:
* reference to the variant, for single values
* reference to the set of variants, for multi values
And that's all. There's no clearing for single values. And for multi values, everything can work through set operations. Great. Now, there are two ways to manage them in the proxy:
* store two pointers, where at any moment one is </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text> and and other points to the value
* store a pointer (union, variant or void*) and a boolean denoting which type it is
The first option is very simple and clean, but the other one is more intuitive: have a boolean denoting which pointer is active - single value or multi value. Anyway, I will allow access to these pointers through private member functions which throw ecceptions on invalid operations, or have another good mechanism of reporting errors and preventing low-level errors like access through </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text> pointers.
Now, the usage pattern. Single values and multi values have different functions. Single values use cast operator and operator=, while the other functions are for multi values. Each such function will simply run on the appropriate pointer from the union. The access function will be the one reporting the error, and ValueProxy will either throw an exception, or leave the job to its higher level wrappers if any exist. In this case it will have another clear way to report the error, or at least allow the wrapper to test and detect it.
I can put the union in a separate class, in order to fully encapsulate it. Since it's somewhat specific to Alder, I won't move it to SGP for now. The idea is to have a union of two pointers/references and a boolean denoting which one is active. I can probably make in an anonymous union, i.e. the members are accessed as if they were regular separate members of the containing class. But I'm not sure it's good for clarity and readability, so I'll think about it again.
Now, let's add this new small class... Alder::ReferenceSwitch...
I just realized I missed the SafeProxy part. I was going to use SafeProxy for the implementation of ValueProxy, but now I can't because I need a pointer union. Maybe use just boost variant? It's a pair of pointers, Boost should be able to make it as efficient as a union. I think.
</rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Create a safe version of ReferenceSwitch. Call the base version SafeProxySwitch, and add two versions like I did with SafeProxy. I can also have an unsafe version. And all of this can move to SGP.
Wait a second! The ReferenceSwitch is useless! It does </rich_text><rich_text style="italic">exactly</rich_text><rich_text> what boost::variant does! I should write just the same proxy. Clearly I can't use SafeProxy directly here, and I can't use a union. Options:
* use a boost::variant of two proxies
* write a new class like SafeProxy which uses a union of two pointers and a boolean
* write a new class like SafeProxy which uses a boost::variant of two pointers
Also, what do I need my Switch to do? Should it be able to set the pointers, or just take their values in the ctor, set the boolean, and then only </rich_text><rich_text style="italic">read</rich_text><rich_text>, without any member changes?
Let's see. I decided ValueProxy will start as being noncopyable and nonmovable. It has a pointer to a set or to a variant, and these don't change. The boolean doesn't ever change either. It just executes things on those pointers. In this sense, I need to examine SafeProxy first: I need to be able to use a real const SafeProxy, i.e. the pointed objects can be changed by the pointers themselves can't. Let's see, can SafeProxy get new values for the pointers? Yes, it can.
Now it raises a new issue: </rich_text><rich_text style="italic">Should</rich_text><rich_text> SafeProxy allow changing the pointer? And should I create a ConstSafeProxy class, which doesn't allow changing the pointer but possible allows changing the object (depending on constness)?
</rich_text><rich_text scale="h1">29/09/2013</rich_text><rich_text>
I just realized there are two types of constness, and I need to choose which one will be controlled by the </rich_text><rich_text style="italic">const</rich_text><rich_text> keyword. Since the Proxy has just a pointer, there is no value constness - assuming you ignore the option to change or not change the pointer. So I had no problem to use </rich_text><rich_text style="italic">const</rich_text><rich_text> for pointer constness.
But now I realize that value constness matters too. And more important, it matters a bit less than pointer constness in the case of ValueProxy. In other words, it makes some sense to use </rich_text><rich_text style="italic">const</rich_text><rich_text> for pointer constness, and control value constness using two separate classes.
This idea doesn't solve the problem, because in general value constness may be at least as important as pointer constness. And people </rich_text><rich_text style="italic">expect</rich_text><rich_text> const to control value constness. Iterators work like that too: There are two separate classes. They don't use const overloading. The question is, can SafeProxy be written this way too? Let's try. I want to have two classes: SafeProxy and ConstSafeProxy.
Writing...
Wait a second! Maybe I don't need the extra work. I realized something else: The idea of the Proxy is that its constness matches the constness of the object it points to. If the object is const, most chances we don't want to do any changes anyway... maybe. Let's think again: Should SafeProxy allow </rich_text><rich_text style="italic">any</rich_text><rich_text> changes to it? Should it be copyable at all? Or movable? </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Let's decide SafeProxy is supposed to be either temporary, or a single object is stored as a member. If you plan to store an object and set its pointer on each request (and them return a reference to the proxy), just use a temporary instead.
So I'm staying with SafeProxy! Removing functions which can change the pointer...
I have another question. The operator= and copy ctor, what should happen to them? Hmmm... if I decide to create a derived proxy which allows changes to the pointer, I'll want to have these operations:
* copy ctor
* operator= (const Proxy&)
* operator= (Member&)
* operator= (Proxy&&)
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I'll make them all protected.
Great. Now, let's take care of ValueProxy. I thought about it yesterday, and I realized using two members may not be such a big deal. It does mean copying two pointers instead of one, though. But I don't know how boost::variant would deal with it. The overloading rules may be a problem with certain pointer types, who knows. If I use a pair of SafeProxy, I won't need to implement the whole thing from the beginning. Remember ValueProxy is just a Proxy with two pointers instead of one, and only one pointer is valid after construction.
If Boost.Variant makes it optimized, it may be better. But it would need a - wait a second. If ValueProxy allows the pointers to be </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text>, I can use it to save the boolean! Then I'd use two copies instead of three.
Hmmm... on the other hand, SafeProxy is quite simple. I can easily write a SafeSwitchProxy template using pointers directly. But it will work only for a </rich_text><rich_text style="italic">pair</rich_text><rich_text> of pointers, while </rich_text><rich_text style="italic">Boost.Variant</rich_text><rich_text> can do the same for </rich_text><rich_text style="italic">any</rich_text><rich_text> number of pointers. If I wrap it - a variant of pointers or a variant of SafeProxy - I'll have a more generic result. But how fast is it? Let's make a list of options.
* wrap a pair of proxies and a boolean
* wrap a variant of two proxies
* wrap a variant of N proxies
* wrap a union of pointers and a boolean
* wrap a pair of pointers
* wrap a variant of two pointers
* wrap a variant of N proxies
There's a problem: a SafeProxy can't have a </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text>. It means... hmmm... why not just </rich_text><rich_text style="italic">allow</rich_text><rich_text> it to be </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text>? SafeReference and SafePointer should be used anyway, while SafeProxy is just the internals. Let's allow it to be </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text>...
Wait a second. I need to check things. What happens if a function in C++ is called on a </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text>? I need to decide how my code responds to it. Let's run an experiment...
No. Let's not make holes in the clean interface. SafeProxy won't have a </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text> option. </rich_text><rich_text style="italic">If</rich_text><rich_text> there's a speed problem, </rich_text><rich_text style="italic">then</rich_text><rich_text> I'll consider it.
Let's look at the implementation of </rich_text><rich_text style="italic">boost::variant</rich_text><rich_text> and decide whether it's better than two proxies and a boolean...
I did some speed tests. They're not the best tests I could run, but it looks like boost::variant has a overhead, probably because it needs loops for handling the variable number of arguments. It's not a serious difference: boost::variant is 2-3 times slower than my version. But my version has an extra advantage: it doesn't use any tricks. There's no union, just two members and a boolean.
I can try to implement ValueProxy using two SafeProxy members, and a boolean. Sounds perfect, but how do I set both proxies? When creating and ValueProxy, either I refer to a set or to a value. It can't be both! Maybe the whole object has just a single value, so I don't even have a real set to refer to! In other words, the proxy </rich_text><rich_text style="italic" weight="heavy">has</rich_text><rich_text> to refer to a real object.
In the simple case, using a static object can do the workaround. But if the object has a long constructor, it won't work. It has to be possible to create an </rich_text><rich_text weight="heavy">empty</rich_text><rich_text> proxy! Then, dereferencing it is forbidden. Let's see what happens when I access a nullptr in C++...
Okay, it causes a segfault. But using gdb, finding it is easy. The point is, be careful with SafeProxy. In the same way you don't just dereference a pointer, be careful with SafeProxy. Now, there we go -- I'm adding a new constructor. In order to make it explicit, I'm making it take a </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text> parameter without a default value, so it has to be set explicitly.
Let's add </rich_text><rich_text weight="heavy">nullptr</rich_text><rich_text> constructor and protected operator= to SafeProxy and SafePointer (SafeReference won't have this option, like a regular C++ reference)... then, implement SwitchProxy as a template. I guess it's too specific to go to SGP, at least for now. I'll see later...
</rich_text><rich_text scale="h1">30/09/2013</rich_text><rich_text>
I have an idea. Using meta-programming, I can make ReferenceSwitch work with an arbitrary number of members. I can't define a union with a variant number of pointers, but for N pointers, I can define a union containing the first pointer and a union of the other N-1 pointers. This way, recursively, any number of pointers can work. I can define a template specialization for the case of 2 pointers, which will serve as the stopping condition.
But it will probably require extra work. Question: Is it worth the extra effort? I mean, who said a large number of pointers is worth using a simple </rich_text><rich_text style="italic">switch</rich_text><rich_text> approach? Maybe it becomes better to use a polymorphic base class, or a mapping between the pointer and a function.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Stop wasting time. I can always switch to a more generic solution later. I'll just use a pair of SafeProxy and a boolean.
First, add nullptr support...
Done. Now, let's write a SwitchProxy class for Alder... Oh, wait. I don't need the boolean. I can test using the pointers themselves. Great. Let's continue...
Wonderful. I have a problem. How could I miss that? The constructors of:
SafeProxy
SafePointer
SafeReference
SwitchProxy
all take a non-const reference in the constructor. This works well for non-const objects, but fails completely for const ones. The member is const, so how can we ever have a non-const reference to it without cheating by using const_cast? It should be possible to set the member using a const reference too. Or... hmmm... wait a second. This is becoming a mess.
SafeProxy naturally has a non-const reference to Member, because a non-const object should be able to use it to change the pointed Container member. But if the container is const, we have to use a reference-to-const! Thus it's impossible to always keep a reference to Member using the same type. We have to keep a non-const reference to allow changes, but we also can't keep it like that because initialization from a const reference is then impossible.
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: It seems </rich_text><rich_text weight="heavy">const</rich_text><rich_text> really shouldn't be used for pointer constness. I should use separate classes like the STL does for containers.
Let's start with SafeProxy. I'll create a SafeProxy_new class which will try to solve the problem by being a class template.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: Implement SafeProxy, then go on to fix SafePointer and SafeReference. Now plan and write SwitchProxy based on them...
</rich_text><rich_text scale="h1">01/10/2013</rich_text><rich_text>
I'm done with SafeProxy_new. I'll make it the new SafeProxy, and the Safe* classes with pointer constness will now get a </rich_text><rich_text style="italic">_old</rich_text><rich_text> suffix. When I'm done with the new ones, I'll remove the old ones.
Wait, there's a problem. SafePointer's code is exactly the same as SafeProxy's code. The only difference is the ptr and red functions, replaced by operators -> and *. Do I really need it? </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Remove SafeReference and SafePointer. Later I'll change SafeProxy or add them again, if the need arises.
Good, two classes less means less work. Let's write the SwitchProxy. Remember the union-inside-union trick? It's too much unnecessary work. Let's write a simple pair SwitchProxy...
</rich_text><rich_text scale="h1">02/10/2013</rich_text><rich_text>
I need to decide whether I want pointer validity to be checked in SwitchProxy. Since the check is unnecessary if the user takes responsiblity, I can supply both options. Like </rich_text><rich_text style="italic">at</rich_text><rich_text> and </rich_text><rich_text style="italic">operator[]</rich_text><rich_text>, there will be a check version and an unchecked version. The checked one will throw, while the unchecked one will cause a segfault due to dereferencing a null pointer.
Which exception classes should I use? Good question. I want to reuse the exception classes from the standard library, but not use them directly. Here's the idea: I like the concept of separation between runtime errors and logic errors. But I also want to preserve the usage of one master exception for a library, is it possible? Hmmm... probably not. In order to have one base exception class, I need to drop usage of logic_error and runtime_error. It's probably not critical. But I can still use similar classes. Here's the plan.
I have two choices for the grand base class. Either I use std::exception itself, or I create my own grand base class which inherits std::exception. Basically changing base class is easy, so the decision is not critical right now. Here's an idea: SGP and the libraries around it supply some kind of framework, somewhat like Glib. With much much less abilities and responsibilities, but in a similar spirit. So I'll create an exception class called Sgp::Exception, and each library will use it as a base class. For example, Alder::Exception. Then, Alder can have - if its developer wishes - two sub-base classes Alder::RuntimeError and Alder::LogicError. Agreed? </rich_text><rich_text weight="heavy">Yes</rich_text><rich_text>.
Okay, I made Sgp::Exception and Alder::Exception. </rich_text><rich_text underline="single" weight="heavy">Next</rich_text><rich_text>: Write RuntineError and LogicError. Then consider the name for the exception I need to throw (invalid access to Object data), maybe DataAccessError or something. I can change and re-arrange my exception classes later. Remember it's still a young development stage!
Then, finish SwitchProxy using </rich_text><rich_text style="italic">at</rich_text><rich_text> and </rich_text><rich_text style="italic">operator[]</rich_text><rich_text> or std::vector or std::unordered_set as guidance (watch the fuzzy entry creation, make sure to implement carefully).
Then, write ValueProxy finally.
</rich_text><rich_text scale="h1">04/10/2013</rich_text><rich_text>
LogicError and RuntimeError - done.
ObjectDataAccessError - done.
SwitchProxy - done.
Now I need to write ValueProxy. Before I write it, I want to take care of the usage of TypedValueProxy. Let's try to make a version of ValueProxy that uses TypedValueProxy and see how it goes...
</rich_text><rich_text scale="h1">05/10/2013</rich_text><rich_text>
I have two things to think about.
* IterationInterface
* TypedValueProxy wrapper
</rich_text><rich_text weight="heavy">IterationInterface</rich_text><rich_text>: When storing it as a single member, it makes sense to have just one and return a reference to it. If I store two, one of them is never used and an extra unnecessary pointer gets added to the object size. If I use a boost variant, things become a bit slower. I mean, depending on object constness, I need just one specific II. So a good solution is to have a single class with constness overloading. Like now.
When creating an II after object construction, however, I need two classes: one for const and one for non-const. Of course, instead of using the single-class-return-reference I can remove it and start always returning a temporary. I need to think about it, but until I do - here's the arrangement.
For ValueProxy and other to have II capabilities, I need to write a CRTP base class. For simple usage as a plain II, it should have a "default" derived class. And I also need the single-class I already wrote. All three of them will move to SGP, and they need names.
Ideas:
</rich_text><rich_text underline="single">CRTP base</rich_text><rich_text> </rich_text><rich_text underline="single">Plain II</rich_text><rich_text> </rich_text><rich_text underline="single">Single-class</rich_text><rich_text>
IterationInterface PlainIterationInterface MemberIterationInterface
IterationInterfaceBase IterationInterface MemberIterationInterface
</rich_text><rich_text weight="heavy">IterationProxy PlainIterationProxy IterationInterface</rich_text><rich_text> <=== my choice
IterationProxyBase IterationProxy IterationInterface
</rich_text><rich_text weight="heavy">TypedValueProxy wrapper</rich_text><rich_text>: In some cases, overload resolution doesn't work in the order I want it to. For example, if I have a function taking bool or std::string, then passing const char* will trigger the bool overload. The solution is to provide a thin wrapper. It takes a const char* parameter and simply calls the string overload. I use such a wrapper with ValueProxy.
One obvious option it to write it by hand, i.e. write functions which take const char*. But in general cases, other resolution order issues may arise, and I prefer to have a general purpose solution. A wrapper template which calls another overload. Since the type taken by that overload should be default-constructible from it or convertible from it, maybe I can safely use a default constructor. But just in case the user just wants to add an overload wrapper which uses his own function - which makes sense - I can supply a template parameter for it (which will default to my own functor calling the default ctor).
First, let's do it in an experiment.
Or... wait a second. There's a problem!!!
TypedValueProxy has an operator=. It's impossible to inherit operator=. But I had a cool idea, listen. There's an option to </rich_text><rich_text style="italic">unhide</rich_text><rich_text> the operator=. As long as TypedValueProxy is noncopyable, everything is fine. Otherwise, its operator= will be passed on to ValueProxy, and that shouldn't happen. Since TypedValueProxy doesn't have any members, it's easy to make it noncopyable.
But there's another option. Before we get there, here's the idea: TypedValueProxy implements its operator=, then ValueProxy needs to do this 7 times:
using TypedValueProxy<X>::operator=;
X is one of the 7 allowed types (bool, integer, date, etc.). But it also means ValueProxy inherits the copy and move assignment operators of its bases. Unless... unless they don't have them? Are the default operator=s created? I'll do an experiment.
Before I check, here's the second option: Instead of using the CRTP trick, define each ValueProxy function taking the 7 types as a function template. But use enable_if to make sure it only works for those 7 types. Hmmm... no... there's a problem with the implementation then, because Object is special: its address is stored. Right? Yes. ValueProxy passes its </rich_text><rich_text style="italic">address</rich_text><rich_text> to the boost::variant, so there would have to be a template specialization. Bad idea. Same for cast operator, which returns the dereference of the stored value (Object pointer).
The good thing is that it doesn't involve the base classes. operator= will work and be clean. Using meta-programming I can create a compile-time way to ensure the template parameter is really one of the 7 allowed types. Hmmm... the implementation part really makes it worse. But hey! Here's </rich_text><rich_text style="italic">another</rich_text><rich_text> idea!
What if I write two versions, both templates - one for scalars (stored by value) and one for references (stored by pointer)? Then it's super-flexible! Hmmm... do I lose anything if I do that? Which approach should I take? Both are somewhat advanced, because one uses CRTP and the other uses enable_if. Hmmm... empty base optimization applies, so using all those base classes doesn't do harm. Hmmm... Let's start with CRTP, later I'll examine it again.
Like I said, let's do an experiment to see if operator= is created if I define my own ones, not being copy/move assignments. Then I'll see how const char* wrapper can work here.
I have some discoveries. I wasn't fully aware of the rules. I tried running some experiments, and I noticed a constructor marked as default is public even if declared in the private area of the class declaration! This means any such usage I did was wrong, and I'm going to see some unexpected behavior until I fix it. I couldn't find clear information on the web (haven't checked the C++ standard yet), but I'll try an online compiler now to make sure it's standard behavior. Let's see...
Okay, I have news! Clang 3.4 treats a </rich_text><rich_text style="italic">=default</rich_text><rich_text> function as private if it's under </rich_text><rich_text style="italic">private:</rich_text><rich_text>, while G++ 4.8 treats it as public no matter what. If I had to guess, I'd say it's probably a bug in G++.
</rich_text><rich_text weight="heavy">What now?</rich_text><rich_text>
I want the TypedValueProxy instantiations to have protected default constructors and operator=, so that ValueProxy can have default ones too. But at the moment it's supposed to be noncopyable anyway, so it may be less critical. It depends on whether it needs to be moved. Because ValueProxy is returned as a temporary from a function, so it will probably have to be movable, even in a private function. The problem is that if I make TypedValueProxy's move ctor and move oerator= protected, the line </rich_text><rich_text style="italic">using SomeBase::operator=;</rich_text><rich_text> in TypedValueProxy may bring in the protected move operator= which is bad. A solution may be to simply make it deleted, because it's not really necessary: A move constructor is probably enough for the purpose of returning the proxy from an Object function.
Things to do:
* See if the protected move operator= gets imported as public
* Do the solution above
* Try the wrapper method
Let's start with the wrapper method, I want to try it. Here's the idea: Since operator= is a special function, TypedValueProxy will have another function doing its job. It will be a protected member function called </rich_text><rich_text style="italic">set</rich_text><rich_text>, behaving exactly like operator=. Then, ValueProxy simply needs to define its operator= by itself. But it's quite easy: It can define a template for it and just make it pass on the value to the </rich_text><rich_text style="italic">set</rich_text><rich_text> function. It needs to enable only the field data types using enable_if in order to avoid issues of const char* and similar problems. How's that?
Hmmm... it's not the most clean solution. It makes the code harder to understand, while just using operator= makes it more straight forward (although probably somewhat unusual).
First let's see if using operator= just brings in all overloads regardless of original access level...
Bad news. It does bring them all. And the worst part, it generates an error if one of them is private, because it's an all-or-nothing feature. If it can't bring all the operator=s, it just fails. That means several things:
* TypedValueProxy can't have any protected operator= because </rich_text><rich_text style="italic">using</rich_text><rich_text> brings it to being public in ValueProxy
* TypedValueProxy can't have any private operator= because then </rich_text><rich_text style="italic">using</rich_text><rich_text> doesn't compile
It still doesn't mean I have to use </rich_text><rich_text style="italic">set</rich_text><rich_text>, because I can simply mark the operator= of TypedValueProxy as deleted. There will be no implicit generation of operator= for ValueProxy, which is fine for now. But if I decide I want it to be copyable or assignable, I'll need to implement my own functions. Wait a second, is SwitchProxy assignable? Yes, it is. So implementing assignment operator and copy ctor should be easy.
Hmmm... how bad is it to use </rich_text><rich_text style="italic">set</rich_text><rich_text>? I want to check to things:
* Do I need enable_if there, and how exactly overload resolution happens
* Does Boost.MPL have anything like boost::mpl::is_one_of<class T, class Types...>
Boost.MPL </rich_text><rich_text style="italic">does</rich_text><rich_text> have such a function, and its implementation looks quite complicated. I still don't understand how it works exactly, but it does the job.
Now, do I need enable_if there? Assume I have a class with a protected </rich_text><rich_text style="italic">set</rich_text><rich_text> function taking the following types as parameter types:
bool
int
double
std::string
date
time
Object&
The implementations are correct, i.e. Object's one comes from TypedReferenceProxy. Now assume I write a </rich_text><rich_text style="italic">set</rich_text><rich_text> function which serves as a wrapper: set (const char*) calls set (std::string). Now I add the following template:
</rich_text><rich_text justification="left"></rich_text><rich_text>
If someone passes const char*, it works only because I wrote the special const char* wrapper. And any other type which can be implicitly converted, e.g. void* (probably converts to bool), should work too. In other words, the template causes no harm: Once you pass the value, it tries to match it like it would if you just called </rich_text><rich_text style="italic">set</rich_text><rich_text> directly. But... hmmm... there's one problem. If I pass an Object, will type deduction choose Object over Object&? Because if it does, an Object will get copied! And that's very very bad in this case. Hmmm... I'll have to write another operator= to represent TypedReferenceProxy, and both templates will have to use enable_if. Now things become very ugly...
And ideas? I can still use the </rich_text><rich_text style="italic">using</rich_text><rich_text> idea, but it has its ugliness too. You see, the </rich_text><rich_text style="italic">set</rich_text><rich_text> solution is basically clean. The operator= wrapping it creates the problem.
Before I decide, I want to solve a problem I forgot to solve: How do I create a wrapper in a general-purpose manner? Here's an idea: Like I already said above, a CRTP class will take a functor and just call the operator= with a functor-generated new value. Here it is:
</rich_text><rich_text justification="left"></rich_text><rich_text>
</rich_text><rich_text scale="h1">06/10/2013</rich_text><rich_text>
Before I try it, I want to write the default functor:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Good. Now I'll run a little experiment...hmmm... wait a second. Before I run it, I need to decide which approach I'm going to take: the using operator= approach or the set and wrapper template approach.
Hmmm... if I take the using approach, I'll still need to write is seven times in ValueProxy's code. I wish there was a way to make it automatic, i.e. when I update the types all I need to do is change the base classes. And nothing else, maybe except for the wrappers like const char*.
Maybe I should accept a fact first: There will no clean solution as long as I use operator= for setting the proxy, and not a regular function like </rich_text><rich_text style="italic">set</rich_text><rich_text>. A good design in this case may be to implement </rich_text><rich_text style="italic">set</rich_text><rich_text>, and use operator= as merely a convenience wrapper. The problem: Some types come from TypedReferenceProxy, so their operator= wrapper is different.
Wait a second. How good is it? If I change types, I'll still need to make changes to operator= because it's not a clean wrapper. There will have to be two wrappers. One like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And one like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
You're right, there's a tiny difference: a single character. How does the code decide which types take the second version? Idea: basically, Object is unique here. All proxy values are supposed to be stored as is, and even pointers are stored by value. In general I can take pointer parameters, and then Object is the only one taken by reference. On the other hand, I could take pointed values by reference too, but then why would I want to store any pointed values in the first place? ValueProxy is written for Object.
</rich_text><rich_text weight="heavy">Decision</rich_text><rich_text>: I'll use the set method: Everything but Object will use the template, and Object will be taken by reference. Great. Let's do it...
</rich_text><rich_text weight="heavy">NOTE</rich_text><rich_text>: After implementing TypedValueproxy and TypedReferenceProxy I'll see if their code is similar. If it's close enough, I'll implement them using a single combined class template.
</rich_text><rich_text scale="h1">07/10/2013</rich_text><rich_text>
I need to solve the wrapper problem. I'll just take the solution suggested above, the one I wrote two days ago.
</rich_text><rich_text scale="h1">08/10/2013</rich_text><rich_text>
There is a problem. When I started planning ValueProxy, I considered using a </rich_text><rich_text style="italic">konst</rich_text><rich_text> template parameter. Then I realized some functions exist in the non-konst version, but don't exist at all in the konst version. The interface can be made clean by using pseudo function templates, but maintenance and debugging can then become ugly. I also rejected the constness overloading approach, so I'm back to considering konst.
If I use pseudo function templates, a simple member function like this:
int func (bool value);
Becomes a monster like this:
template <class T = bool, class = std::enable_if<!konst>::type>
int func (T value);
And even this monster won't necessarily work. I remember trying to use SFINAE like this and discovering it's impossible, although I don't remember why it didn't work. Anyway, here's my konst idea.
Some functions work for both ValueProxy and ConstValueProxy, while some functions are possible only for ValueProxy. So I'll create a base class called ObserverValueProxy. This will be the template I'm writing right now. Then, ConstValueProxy will be ObserverValueProxy<> with </rich_text><rich_text style="italic">konst</rich_text><rich_text> = </rich_text><rich_text style="italic">true</rich_text><rich_text>, and ValueProxy will simply be a derived class which adds the modifying functions.
I may need other names, in case Observer allows changes when konst is false. I'll examine it after I write it, and change the name if necessary.
</rich_text><rich_text weight="heavy">NOTE</rich_text><rich_text>: I thought about the doxygen issue when classes from Alder are just being typedefd in a clean namespace, e.g. Idan. I realized there's no easy way to make doxygen pretend the real names are the typedefs and hide internal original names. So here's a decision:
At the moment, many many things go into Alder. Some of them are probably unnecessary for simple usage. Either I move plain public API (like Alder::Object) to a high-level namespace (like Idan or a new namespace), or I use Alder as the high level namespace and move low-level things (like Alder::Type maybe) to a new namespace, e.g. Cist or Sprak or Frelsi whose names I can reuse.
I have important updates. The usage of CRTP is making the code huge and very complicated. I'm adding more and more classes. Also, all the CRTP bases need to access the boost::variant member of SingleValueProxy, which means either tons of friends or a single friend used by them all as a dirty hack. The usage of CRTP has become so ugly, it's simply not worth it.
I'm moving the classes into an "old" subfolder and going back to the clean simple ValueProxy. I will still need the Observer/Modifier model, but it's much easier now.
Hmmm... looks like I still need some CRTP for SingleValueObserverProxy, because SingleValueProxy should have just a Value reference, while ValueProxy has a SwitchProxy. There's no clean way I see to use plain inheritance, so I use static polymorphism: The non-public function </rich_text><rich_text style="italic">actual ().value ()</rich_text><rich_text> is assumed to return the Value. How it work depends on the bottom classes ValueProxy and SingleValueProxy.
</rich_text><rich_text weight="heavy">NOTE</rich_text><rich_text>: I can use ValueProxy instead of SingleValueProxy, but then beginner errors won't be discovered at compile time. For example, this code will compile:
ValueProxy v1 = obj[prop]; // valid if prop is registered
ValueProxy v2 = *v1.begin (); // valid if v1 is multi value and non empty
ValueProxy v3 = *v2.begin (); // invalid, throws exception
ValueProxy v4 = *v3.begin (); // we never reach this line
</rich_text><rich_text weight="heavy">BETTER IDEA</rich_text><rich_text>: I'm beginning to use ugly CRTP again. More mess, more classes, more code. Instead, I can write the SingleValueProxy classes by hand, without CRTP composition. They're very simple anyway (cast operator and assignment operator). </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: Yes, I'm taking the non-CRTP approach.
</rich_text><rich_text scale="h1">09/10/2013</rich_text><rich_text>
I want to store Object as a non-null pointer. There is no entity in C++ which can fulfill both things:
1 Can be set to point to another object
2 Always points to an object
But C++11 adds a class template std::reference_wrapper to <functional>, which does *exactly* that. Therefore, I can use it with object. But there's one more thing to do.
In the case of std::reference_wrapper, the pointer constness depends on the parameter type. For example, std::reference_wrapper<const int> cannot make changed to the pointed variable. I can determine the type using std::conditional, but it has become too frequent to use it with these special cases. So I want to define some convenience typedefs.
First, choose a type's constness depending on a boolean. I can static_assert that T is not konst, or just allow it to be const, or use a partial specialization in case writing "const T" is invalid when T is already const. You know what, let's check it... okay, I have an answer. It works, no need for a specalization. But it may make sense to allow only non-const T types, e.g. using std::is_const and std::enable_if. We'll see.
//////////////////////////////////////////////////////////////////////////////o
#include <type_traits>
template <class T, bool konst>
using type = typename std::conditional<konst, const T, T>::type;
/////////////////////////////////////////////////////////////////////////////o
Now, I want to define a pointer type and a reference type. And a reference wrapper type. A class already exists so I just need to use a typedef. I wrote my own classes like SafeProxy because I forgot about std::reference_wrapper.
/////////////////////////////////////////////////////////////////////////////o
#include <functional>
template <class T, bool konst>
using ref = type<T, konst>&;
template <class T, bool konst>
using ptr = type<T, konst>*;
template <class T, bool konst>
using aref = std::reference_wrapper <type <T, konst>>
//////////////////////////////////////////////////////////////////////////////o
Now my options are:
1 Use Sgp::ptr for Object, and be careful now to make it nullptr
2 Use Sgp::mref for Object, and make sure its usage doesn't create overhead for boost::variant compared to Sgp::ptr
I'll take the second option. Later, especially if a need for speed arises, I'll compare the speed. The variant already contains one non-POD typ, std::string, so there's a chance adding another does doesn't make a difference to boost::variant.
Another idea:
mref doesn't provide a full "non-null pointer" because it has reference semantics. I can define my own Sgp::BusyPointer wrapper which can never have null, and work in a similar way to std::reference_wrapper. But it doesn't have all those function related things. Another thing, I can get rid of API issues my defining my own reference wrapper without all those extra typedefs and the operator() I don't need. I can call it AssignableReference or MutableReference or something like that.
Then I can define aref and bptr to use them. Or call them a_ref and b_ptr. We'll see.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: I'm done with the basic SingleValueObserverProxy. Now make the new one which derived from a template parameter, from whom is inherits the data member and accesses it with a protected function </rich_text><rich_text style="italic">value()</rich_text><rich_text> while catching exceptions (explained in the cpp file). Then write base class for single value and write SingleValueModifierProxy (for both versions, so I'll probably need two Modifier versions too). Define konst and nonkonst single value proxies and move on two multi value.
</rich_text><rich_text scale="h1">10/10/2013</rich_text><rich_text>
I just wrote the alias which defines SingleValueProxy<>. Now the next step is to write ValueProxy and relevant types. Before I do that, I want to start adding actual comments to the code. Doxygen comments are all empty, and the code is getting big. I want to get used to them. Let's look at some gtkmm code... I'm opening a Doxygen project under my projects folder. I do remember I had a doxygen learning project somewhere, but I don't remember where.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: Finish going over Doxygen commands and adding notes to skeleton rules in Gedit. Then I can add some doxygen comments to classes I just wrote, or skip to writing the next classes. I need to write a ValueProxyBase, the paralle or SingleValueProxyBase. Then write ValueObserverProxy. It's a good idea to make it derive SingleValueOberserProxy, but it means I need to edit SingleValueModifierProxy to have a Base template parameter.
</rich_text><rich_text scale="h1">11/10/2013</rich_text><rich_text>
Done going over Doxygen. Now let's write code...
</rich_text><rich_text scale="h1">12/10/2013</rich_text><rich_text>
I'm working on IterationProxy. It's different from IterationInterface. I need to figure out the template parameters and member functions.
</rich_text><rich_text scale="h1">14/10/2013</rich_text><rich_text>
I'm done woth the basics, now I need to do finishing/polishing/fixes. Here they are:
* Design and implement an iterator adaptor
* Make the IterationProxy instantiation in ValueObserverProxy use this iterator class
* Write PlainIterationProxy and IterationInterface fully
* Look at the usage of SafePointer<Object>, especially as a function parameter in some classes, think it
* Carefully choose which classes define Sgp::is_konst: which specialize it and which derive Sgp::IsKonst
After that:
* Write the full FreeObject class
* Define the Idan-related tests and requirements of Alder::Object
* Decide how Object will be implemented
* If necessary, change "Object" in value proxy classes to "FreeObject", or make it a template parameter
* Implement Object fully
Let's start with the iterator adaptor. The base iterator is VariantSet::iterator. And VariantSet is an unordered set of Variants. And a Variant is a boost::variant of 7 types. In simple words, it's an iterator of an std::unordered_set.
The problem is that dereferencing the iterator using operator* or operator-> returns a reference to the Variant. Instead, I want to return a temporary SingleValueProxy object. I could probably write a type which combines the iterator and SingleValueProxy into a single class, but I'm not sure it would be modular like the current solution. For now I'll use the solution suggested above.
How do I write an iterator adaptor? Last time, I think I used my own class. It simply inherits std::iterator. Let's find it and take a look...
I wrote three iterator classes so far:
TagIterator from Partager, which iterates through the a pair element, where the other hidden element is a weak_ptr
SharedIterator from old Sgp, which iterates through elements stored as shared pointers
WeakIterator from old Sgp, which iterates through elements stored as weak pointers
All three are adaptors around STL iterator types.
I can do the same again, by carefully implementing everything. But instead, Boost.Iterator offers some nice utilities which should make it easier. If I recall correctly, boost::iterator_facade helps define iterators, and boost::iterator_adaptor helps define adaptors. Let's see...
Okay, here's the idea. In technical terms, my iterator is probably not really an iterator. An iterator is supposed to return a reference when dereferenced, not a proxy. Boost extends the iterator requirements into something more sophisticated. I will try to use it. But my iterator is once again something general-purpose which I can write in SGP.
Essentially, if I didn't miss anything, the only difference compared to the base iterator is the dereferencing operators -> and *. For example, these work by using a value proxy:
*it = 5;
int x = *it;
*it = "hello";
std::string s = *it;
it2->insert (5);
bool e = it2->empty ();
So there are two things to implement:
1. operator * returns a temporary SingleValueProxy<> object
2. operator -> returns a pointer to - wait a second... basically it's supposed to return a pointer to a value
I need to check things. operator-> cannot return a pointer to a temporary proxy, because the proxy is destroyed when the function returns and the pointer becomes invalid. I need to check exactly how operator-> works...
It looks like operator-> has to return a pointer. I don't understand why the documentation of Boost.Iterator doesn't mention it. At lease facade doesn't. I'll read the docs of adaptor too and see. But assuming there is no magical solution, here are the options.
The problem: Returning a pointer to a temporary causes undefined behavior.
Suggestions:
* probably impossible, but I can try writing a private operator* for SingleValueProxy, returning a ref to itself
* Store the Proxy by value </rich_text><rich_text style="italic">inside</rich_text><rich_text> the iterator and simply return a reference/pointer to it
The second solution sounds reasonable, doesn't it? In any case, I need to find a way to implement operator->. I think it can work, but for a nonconst iterator I'll have to allow the Proxy to take a new value (it can either be set when incrementing, or when dereferencing; we'll see), i.e. not just take a Variant in the ctor but also take a </rich_text><rich_text style="italic">new</rich_text><rich_text> one after constuction (possibly private, allowing only </rich_text><rich_text style="italic">iterator</rich_text><rich_text> to use this functionality). It would also mean I need to store a pointer/bptr/aref to the Variant, not a reference (since a reference can't change).
</rich_text><rich_text scale="h1">15/10/2013</rich_text><rich_text>
I had thoughts today about FreeObject. They're written on paper in my job-bag (a bag I take when I go to my jobplace). We'll get there later.
First, I need SingleValueProxy to be able to point to other values. Its constness is now going to matter, like it matters for iterators (changing the pointee). Instead of a setter op= I can simply use the move-ctor. Let's see...
I think the default move and copy ctors are still generated. But there's another problem to solve. What if the user tries something like this:
obj1[prop1] = obj2[prop2];
Implementing operator= here is the </rich_text><rich_text style="italic">only</rich_text><rich_text> way to make it work as expected, because there are 7 possible data types and the compiler can't choose one at compile time. Decision:
1. I'll add an operator= which takes a value
2. I'll write a copy ctor which copies the value, not the proxy.
Since I don't use "using Base::operator=", adding the new operator= now doesn't cause any harm. In the future it may be useful to make it private, but right now I don't see a reason to do that. Let's start!
Wait. I have another idea. Maybe all this work will become obsolete very quickly. Instead of just coding, maybe I should think more and get better results when coding. For example, I've been considering the option to write a Value class stored directly inside FreeObject, and makes ValueProxy smaller. There are also the ideas to make FreeObject and Object using something faster than unordered_set, like dynamic arrays or even std::array. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I'll just make it work for now. Later I'll consider the changes.
Okay, I added an operator= which allows SingleValueProxy to point to new values. Now let's give SingleValueModifierProxy an operator = which takes a ValueObserverProxy...
Wait. It makes the design ugly. SingleValueModifierProxy doesn't </rich_text><rich_text style="italic">know</rich_text><rich_text> the konst version of SingleValueObserverProxy. How is it supposed to take it as a parameter? I mean, it breaks the beautiful modular design! </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I'll skip it for now. Later I'll find another hack for it.
Let's stop for a moment. I can get FreeObject to work, but </rich_text><rich_text style="italic">should</rich_text><rich_text> I? I want to classify object classes first.
* Property installation
* Before setting values
* Mixed with setting values
* Field types
* Free
* Limited by type spec
* Cardinality
* Free
* required or optional
* single value or multi value
* limited by cardinality range
* limited by cardinality spec
As a general tool for prototyping, I want to start with the most general case. A completely free object. First, I want to write a Value class. It will hide the details of boost::variant from the world. First, this is the desired functionality for Alder::Value:
* can contain any of these values:
* boolean
* integer
* real
* time
* date
* string
* reference to another object
Wait a second. Do I really need date and time? So far, date and time were just syntax features. They allowed specifying time as hh:mm:ss and date as dd/mm/yy. But date and time </rich_text><rich_text style="italic">do</rich_text><rich_text> have a meaning. These features should translate into non-primitive types! </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: These syntax features will translate to compound types. There are no date and time primitives for FreeObject anymore!
So, again. Hmmm... wait. Before that, I have an idea. I can implement a flat unordered set in SGP. Then I can try using it instead of the hash-table set. Let's do it.
I have a problem again. I need an iterator type. I need a way to wrap an iterator with a thin forward iterator wrapper. For that I need to write a new iterator class...
Enough with that. I'll just add a TODO there and go back to FreeObject.
DESIRED FUNCTIONALITY of Alder::Value:
* can contain any of these values:
* boolean
* integer
* real
* text
* reference to another object
* the constness of the object reference matches the constness of the holding object
* can be set to from a value of any of these types
* can be converted implicitly to any of these types
* can take const char* and use as a string, not as bool
* can be printed to an std::ostream
Let's write this class, and then proceed. I can use the ValueProxy classes to help me.
</rich_text><rich_text scale="h1">16/10/2013</rich_text><rich_text>
I read an article today, and I realized I shouldn't ignore all those small annoying tasks. I want to a bit back. I want to write the iterator wrappers and a FlatUnorderedSet.
First, the wrappers. Can Boost make it easier? Let's see, I'll try... Boost documentation tends to be unfriendly for new people for some reason. I'll just write an experiment. If it works, I'll copy it to SGP. Special requirements:
* const_iterator is convertible to iterator
* iterator objects are be compared for equality
* operator-- doesn't work
* operators +, +=, - -=, <, >, <=, >= and [] are not defined
I hope I don't miss anything. Let's try Boost...
Done. It's perfect. Actually using Boost for this is quite simple. But I want to try adding more iterator categories. Let's see which categories exist in Boost... there's just one more type which seems useful: Bidirectional. But for easiest future changes, I'm adding the category as a second template parameter. Then I'll create two typedefs for the two useful categories.
Perfect! I have a working iterator class!
Next step: Write the FlatUnorderedSet and FlatUnorderedMap classes. I'm still not sure how exactly Map and Set are going to share code, but I'll do my best to find a way. First I'll write Set, then we'll see how I implement Map.
</rich_text><rich_text scale="h1">17/10/2013</rich_text><rich_text>
There is a problem. I'm not sure FlatUnorderedSet is any better than boost::flat_set. Here's why: The lookup complexity of an ordered set is logn. For a flat set, insertion and deletion are O(n), moving half of the elements on average.
In the case of a flat unordered_set, however, deletion is the only better operation, taking O(1). But insertion requires checking whether the element already exists in the set, and as a result it takes O(n), since the whole array has to be scanned. Comparison:
set unordered_set flat_set flat_unordered_set
insertion logn 1 n n
removal logn 1 n 1
lookup logn 1 logn n
Is it worth the effort at all? I'm not sure. Let's leave it for now.
Before I get back to Value, I want to move some classes from old SGP to new SGP. Then, they won't become annoying background work later.
What I want to start with:
* Iteration classes
* Command stack
I'll keep the current IterationProxy, but I want to write PlainIterationProxy and a fixed IterationInterface.
Done. I also have a project to take care of the default ctor/op= created for several classes, but I'll do it later.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: The command stack, and see if there are more classes I can bring.
</rich_text><rich_text scale="h1">18/10/2013</rich_text><rich_text>
Command stack. I've written a mail message to myself, explaining what to do. I'm bringing UseCounted as well.
New idea: Move all exception classes to a single library-wide header, one for SGP and one for Alder. But I'm not sure moving implementations to a header is a good idea. Instead I can create one hpp file for classes, and one cpp file for all function defintions, which are mostly just constructors.
Idea: Make writing exception classes easier by creating a template for them. The parameter can use a "tag", i.e. an empty class, to create a separate instantiation for each template, and then use a typedef to supply convenient names.
Anyway, first bring UseCounted... done. Perfect. Very simple design. Now let's take care of exceptions, and then Command Stack, and then Alder::Value.
There is a problem with Sgp::Exception: It serves both as a general exception base class, and as the base class for SGP-specific exceptions. And it can't do both. Solution: Base classes for libraries wil be named Error. SGP will have an Sgp::Error class, and Alder will have Alder::Error. Both will inherit Sgp::Exception.
Since all exception classes under Sgp::Error are just constructors, putting them in library-wide files is very easy. A top-level exception class looks like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And classes under it look like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
And classes under them look like this:
</rich_text><rich_text justification="left"></rich_text><rich_text>
Let's start with the first one. Basically, each such top-level error class should have a string containing its name. Then, everything else is the same for all of them. The question is, can the project name string be passed as a template parameter? Let's check... pointers are allowed, objects are not. But I'm not sure pointers to non-objects are allowed. Let's run an experiment...
No. It doesn't work. Here is how it works: The pointer passed to a template as a template parameter has to point to a constexpr object. I can use a constexpr array of char, like this:
constexpr char s [] = "hello";
But then, if I don't use a tag class anyway, I get a somewhat un-flexible approach, in which the template parameter is a pointer to const char. Until convenient compile time strings are added to C++, I'll use the tag clas approach.
It's going to work like this: The template takes one parameter, which is a class. Let's call it Tag. Tag has just a single requirement: To have a static public member of type std::string, named </rich_text><rich_text style="italic">text</rich_text><rich_text>. Here's an example:
struct MyTag
{
static const std::string text;
};
std::string MyTag::text = "my tag";
I can write a macro to make it shorter. I'll do it later if writing the tag class becomes too cumbersome.
After writing the tag class, it can be used with the exception class. I'm adding it as a new class in SGP, called ExceptionTemplate.
Done, great. I can add some extras, e.g. use the text "Alder" and let the template transform it into "Alder Exception ::: ".
You know what? Good idea. I'll add two more classes, one for module errors in general, and one for specific ones. I need to give them names... maybe BuiltError and BuiltModuleError?
I have another idea, maybe even better. I'm not sure which is better. Here are some designs:
1. Have other parallel templates which insert things like "::: " between the tag text and the message
2. Have another parallel template which takes a second tag and inserts between tag text and message
3. Have derived classes which add things like ": " and " ::: " between tag and message
4. Have a derived class which takes an extra tag and adds it between tag and message
I think the important decision to make here is whether I use derived classes or paralell classes. It affects mainly the shape of the inheritance tree. It could be nice to have a base class for built exception classes. </rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: At least for now, I take the inheritance approach.
</rich_text><rich_text scale="h1">19/10/2013</rich_text><rich_text>
Good. Now, the question is whether I create specific derived built-exception classes, or create one derived template. Hmmm... before I decide, I want to have the following three kinds of exception generators:
1. Plain: Passes the message directly to the base class
2. Tag: Adds a tag in front of the message and passes the result to the base
3. Tag and Separator: Adds a tag and a separator before the message and passes it to the base
After choosing inheritance, the second question I need to answer is whether each separator will be a string literal and get its own whole new class, or I'll use a tag string. I think it's better not to create tons of classes on the fly. A class is much more than just the tag string. I'll use a template!
Now, names. I use BuiltException for the Tag. Now I need three names. Ideas:
</rich_text><rich_text weight="heavy">DerivedException, PrefixedException, NamedException</rich_text><rich_text>
BuiltException, PrefixedException, TaggedException
Good, first idea taken.
Great, now where was I? Oh, right. Before I take care of CommandStack and Alder::Value, I need to create all the exception classes. Hmmm... do I really need the name-and-separator class, NamedException? What's wrong with just providing "</rich_text><rich_text style="italic">MyProject ::: </rich_text><rich_text>" as a Prefix for PrefixedException? Nothing, I guess, but when you have many of them using the same prefix, writing just </rich_text><rich_text style="italic">"MyProject"</rich_text><rich_text> is probably nicer.
I'll need two exception classes: One for top-level module exception classes, and one for all classes derived from them. I'll can them BuiltModuleError and BuiltError. And I'll define them in a one file, "built-exceptions".
Perfect! Last step with exceptions, create headers </rich_text><rich_text style="italic">exceptions.hpp</rich_text><rich_text> for SGP and Alder, where all their exception classes (except for Sgp::Exception) are defined. First Sgp::Error / Alder::Error, then everything under them.
Good. What about a macro which helps make the tags easier to define? I just defined it. </rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: CommandStack and Alder::Value.
Before that, wait a second... I want to update Alder's string-util and fix non-trivial exception classes. Then I'll do CommandStack and Alder::Value.
</rich_text><rich_text scale="h1">20/10/2013</rich_text><rich_text>
I want to get rid of the glibmm dependency. Alder and SGP don't use any external dependencies except for sigc++ and boost, and both supply class templates. Adding glibmm means adding a huge shared library. Unnecessary. I can cut off Glib::Ustring into a separate library, or use this:
</rich_text><rich_text link="webs http://utfcpp.sourceforge.net/">http://utfcpp.sourceforge.net/</rich_text><rich_text>
Let's see how it's implemented...
</rich_text><rich_text scale="h1">21/10/2013</rich_text><rich_text>
Interesting. If it can do the required work, I'll use it. But before that, I'd like to create a stand-alone autotooled package for it. It's probably not really necessary because the whole thing is just 4 header files, but I want it to be easy to install. There will be no compilation to autoconf is probably not very useful here. But still, for easier future changes, I can just add it there.
Or... hmmm... or I can make it a shared object. I'll need a script for that, to separate the implementation from the declarations. No, forget it. The files contain </rich_text><rich_text weight="heavy">templates</rich_text><rich_text>. I will need to make it a header package. Let's try creating an autotools package then... using the template :-) But don't forget to check its license, maybe I'll need to put it in COPYING instead of the GPL.
I won't prepare the files now: I'll just create a git repo, put the files there and forget about them for now. Later I'll add autotools files.
</rich_text><rich_text scale="h1">22/10/2013</rich_text><rich_text>
Working on string-util...
</rich_text><rich_text weight="heavy">DECISION</rich_text><rich_text>: I need a standalone version of Glib::ustring. I can't find a way to do things like isalnum and isgraph without using ICU or glibmm. I'll leave string-util as is for now, and later I'll see what I can do there.
Now what:
- Finish Alder exception classes
- CommandStack
- Alder::Value
Great, done with exceptions.
CommandStack uses a vector. I decide using a static array is unnecessary, so two options remain:
1 Setting a size limit for the vector
2 Using a given-sized container
Basically, I prefer to do both in a single implementation. Implementing a circular buffer can be very easy with a deque, but I need to see how it allocates memory first, and consider the possible extra changes which vector may avoid by using a continuous memory range.
std::deque doesn't provide reserve(), so I can't control allocations. </rich_text><rich_text weight="heavy">IDEA</rich_text><rich_text>: Just use a deque and allow the user to limit its size. When not limited, it grows like now. When limited, it removes old elements and changes markers as necessary.
</rich_text><rich_text scale="h1">23/10/2013</rich_text><rich_text>
I'm looking at this: </rich_text><rich_text link="webs https://wiki.gnome.org/GTK%2B/BestPractices">https://wiki.gnome.org/GTK%2B/BestPractices</rich_text><rich_text> and linked pages, and I realize I should write a style guide for my own code and use it consistently. Header guard style, use of include and "" vs. <>, etc. I'm adding this to the TODO page. I also should probably start using an actual bug tracker!
CommandStack, here I come! I decided to start with an implementation based on deque, and consider not adding any others.
I'm also considering some new idea, give Object property change signals. I have a tab open in Epiphany with an interesting article about signal systems.
</rich_text><rich_text scale="h1">24/10/2013</rich_text><rich_text>
I need to read more about signals. Later. I want to do CommandStack and go back to Alder::Value.
I've been considering to replace the indices used in the CommandStack implementation with iterators, but even in std::deque insertions (including at the beginning and at the end) invalidate iterators. So I still have to use indices. I just need to update then when I pop from the beginning.
</rich_text><rich_text weight="heavy">NEXT</rich_text><rich_text>: I implemented execute(), next function is undo().
</rich_text><rich_text scale="h1">31/10/2013</rich_text><rich_text>
I wasn't writing because my second year of unnecessarily-exhausting university studies began. But I'm done with an initial refined improved upgraded implementation of Command and CommandStack. I'll add things in the future, using the TODOs I left in the files and things I wrote on paper.
Next, Alder::Value. My paper has instructions.
Where I stopped: IIRC implementing Alder::Value, find TODO in Value.cpp and continue implementing. When done, read my papers and proceed to work on ValueSet and Field.
</rich_text><rich_text scale="h1">10/11/2013</rich_text><rich_text>
I'm done with Value and ValueSet. Next: SingleField, MultiField.
</rich_text><rich_text scale="h1">17/11/2013</rich_text><rich_text>
I've been reading a bit about Tracker and other semantic desktop systems. I designed an overall architecture, and from there I'm going to write more details and create a whole plan. I started on paper, now I'm moving it to a Dia diagram and adding things.
Good. Before I proceed and add things, I want to make several changes. There's a lot of mess in this file. It's a huge diary and it contains tons of data, lists, tasks, entries, examples and what not. And CherryTree is not standard. It doesn't easily convert to sources like LaTeX or DocBook or XML or Mallard or Markdown.
None of these formats will work for me. Even Markdown, which is closest to the goal, is supposed to be eventually converted to XHTML. I'd like to use my own title styles. Sometimes just === or --- under the title is not big enough to make it easy to spot on long text. But the Wikipedia article mentions some alternatives, e.g. AsciiDoc. I'm examining them.
Hmmm... I found a problem that *all* lightweight markup languages have. They are </rich_text><rich_text style="italic">first</rich_text><rich_text> intended for conversion to output formats, and </rich_text><rich_text style="italic">then</rich_text><rich_text> they consider human readability. What I need is a language that is </rich_text><rich_text style="italic">first</rich_text><rich_text> for humans. Then it considers being machine readable. </rich_text><rich_text weight="heavy">SOLUTION</rich_text><rich_text>: Create a dynamic language in which a config file defines the syntax for each item. Then I can set the config file to whatever syntax I like and prefer.
In order to get things going, I'll do these:
- Go over this long file and see what's in it
- Try to find out why I started using CherryTree, and what I lose if I stop using it
- Write a rules file with settings, but see if I already started writing one somewhere
- Later try to write my requirements: How a perfect personal wiki would work for me
Let's start.
* Why I use CherryTree: Because I needed to have a hierarchy in the document, and Gnote doesn't have hierarchies. And no tags, although I don't use tags here. A long diary becomes a mess quickly.
My solution: Wiki software is not the only way to create a hierarchical notebook. I'm going to use something much more general-purpose:
* Folders will represent hierarchy components
* Plain text files will contain page content
* Gedit's file browser sidepane will serve as the tree view
I couldn't find an existing config/format file. But I didn't look inside all the files I saw, so maybe I missed it. Anyway I'm going to start a new one. Since I won't be creating format Idan documents like I though I would, I don't think I need a </rich_text><rich_text weight="heavy">git</rich_text><rich_text> repo anymore for this diary and other things. At least not for now.
I'm starting this new Gedit-based approach under Projects, in the Semantic Data Management System folder. I can export CherryTree documents to multi-file plain text, but for now I'll keep this file as CTD and just extract the things I need, like task lists.</rich_text><codebox char_offset="15731" frame_height="258" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">#include "config.hpp"
#ifdef HAVE_CXX11
#define SGP_HAVE_CXX11 true
#else
#define SGP_HAVE_CXX11 false
#endif
namespace Sgp
{
constexpr bool have_cxx11 ()
{
return SGP_HAVE_CXX11;
}
}</codebox><codebox char_offset="16291" frame_height="114" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">template <class T, bool B>
class A
{
};
A <int, macro_is_defined (HAVE_CXX11)> a;</codebox><codebox char_offset="20085" frame_height="208" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">template </* ... */>
class FwdIterationInterface
{
/* ... */
};
template <class Base, /* reverse iterator types */>
class BidiIterationInterface : public Base
{
/* ... */
};</codebox><codebox char_offset="26050" frame_height="24" frame_width="400" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">Class klass (param1, param2, param3);</codebox><codebox char_offset="38478" frame_height="114" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class Node>
class Base
{
protected:
Node node;
};</codebox><codebox char_offset="38695" frame_height="78" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">class Class : public Base <Node <MyParams>>
{
friend class Node<MyParams>;
};</codebox><codebox char_offset="44471" frame_height="150" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">if (&(*parent_iter) == &dest || get_node_func (*parent_iter).has_decendant (dest))
{
report_func (*parent_iter, actual ());
parent_iter = detach_parent_notify (parent_iter, &(*parent_iter) != &dest, this != &target);
}
else
++parent_iter;</codebox><codebox char_offset="44914" frame_height="366" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">template <class ReportFunc>
class Function
{
public:
bool operator() (Actual& parent, Actual& child)
{
if (&parent == &dest || parent.has_decendant (dest))
{
report_func (parent, child);
detach_parent_notify (parent, &parent != &dest, this != &target);
return true;
}
else
return false;
}
private:
Actual& dest;
Actual& target;
ReportFunc report_func;
};</codebox><codebox char_offset="47685" frame_height="334" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">parent_iterator current, next;
current = next = parents ().begin ();
++next;
while (current != parents ().end ())
{
if (/*...*/)
{
function (/*...*/);
//detach_parent here
current = next;
++next;
}
else
{
current = next;
++next;
}
}</codebox><codebox char_offset="48193" frame_height="222" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">parent_iterator current, next;
for (current = next = parents ().begin ();
current != parents ().end ();
current = next)
{
++next;
if (/*...*/)
{
function (/*...*/);
detach_parent_notify (/*...*/);
}
}</codebox><codebox char_offset="48250" frame_height="420" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">parent_iterator prev, current;
prev = current = parents ().begin ();
while (current != parents ().end ())
{
if (/*...*/)
{
bool begin = (current == parents ().begin ());
function (/*...*/);
detach_parent_notify (/*...*/);
if (begin)
current = parents ().begin ();
else
{
prev = current;
++current;
}
}
else
{
prev = current;
++current;
}
}</codebox><codebox char_offset="49110" frame_height="474" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">template <class Params>
template <class Function>
Function Node<Params>::for_each_child (Function function)
{
for (Actual& child : children ())
function (actual (), child);
return std::move (function);
}
template <class Params>
template <class Function>
void Node<Params>::for_each_child_allow_detach (Function function)
{
std::move (for_each_child_func (actual (), std::move (function)));
}
template <class Params>
template <class Function>
void Node<Params>::for_each_child_allow_all (Function function)
{
ChildContainer child_container_copy = child_container;
Children children_copy (child_container_copy);
for (Actual& child : children_copy)
function (actual (), child);
return std::move (function);
}</codebox><codebox char_offset="49236" frame_height="318" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">template <class Actual, class Function>
class ForEachChild_UnorderedSet
{
public:
Function operator() (Actual& actual, Function function)
{
child_iterator current, next;
for (current = next = children ().begin ();
current != children ().end ();
current = next)
{
++next;
function (actual, *current);
}
return std::move (function);
}
};</codebox><codebox char_offset="49239" frame_height="564" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">template <class Actual, class Function>
class ForEachChild_Vector
{
public:
Function operator() (Actual& actual, Function function)
{
child_iterator prev, current;
prev = current = children ().begin ();
while (current != child ().end ())
{
bool begin = (current == child ().begin ());
bool erased = function (actual, *current);
if (erased)
{
if (begin)
current = child ().begin ();
else
{
prev = current;
++current;
}
}
else
{
prev = current;
++current;
}
}
return std::move (function);
}
};</codebox><codebox char_offset="80272" frame_height="474" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">float speed = object["speed"].as<float> ();
float speed = object.get <float> ("speed");
float speed = object.get ("speed").as <float> ();
std::list <int> list_of_sizes (object["sizes"].begin (), object["sizes"].end ());
int third_size = object["sizes"][2];
int last_size = object["sizes"].back ();
object["speed"] = 21.3f;
object["sizes"].add (5);
object.add ("sizes", 5);
object.insert_after (object["sizes"].begin (), 5);
object.remove ("sizes", 5);
object.remove (object["sizes"].begin ());
object["sizes"].remove (5);
object["sizes"].remove (object["sizes"].begin ());
object["sizes"][2] = Alder::null;
object["sizes"][2].remove ();
object.get_name ()
object.set_name ()
object.get_uid ()
object.set_uid ()</codebox><codebox char_offset="83195" frame_height="620" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">// get a property value
float speed = object["speed"].as<float> ();
float speed = object.get <float> ("speed");
float speed = object.get ("speed").as <float> ();
// get the list of property values
std::list <int> list_of_sizes (object["sizes"].begin (), object["sizes"].end ());
// get a value from the property's list of values
int third_size = object["sizes"]
int last_size = object["sizes"].back ();
// set a property value
object["speed"] = 21.3f;
// add a property value
object["sizes"].add (5);
object.add ("sizes", 5);
// remove a property value
object.remove ("sizes", 5);
object.remove (object["sizes"].begin ());
object["sizes"].remove (5);
object["sizes"].remove (object["sizes"].begin ());
object["sizes"][2] = Alder::null;
object["sizes"][2].remove ();
// get/set name
object.get_name ()
object.set_name ()
// get/set uid
object.get_uid ()
object.set_uid ()</codebox><codebox char_offset="88470" frame_height="240" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">struct Date
{
int year;
int month;
int day;
};
struct Time
{
int hours;
int minutes;
int seconds;
};</codebox><codebox char_offset="124423" frame_height="168" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class Member>
class SafeReference
{
public:
Member& operator ();
const Member& operator () const;
private:
Member& member
};</codebox><codebox char_offset="129697" frame_height="24" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">type range [0, inf) unsigned_integer</codebox><codebox char_offset="132230" frame_height="84" frame_width="1000" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">typedef boost::variant </*...*/> ValueVariant;
typedef std::unordered_map <Property*, ValueVariant> SingleValueMap;
typedef std::unordered_map <Property*, std::unordered_set <ValueVariant>> MultiValueVariant;//need hash function</codebox><codebox char_offset="156460" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class T>
Foo& operator= (T value)
{
return set (value);
}</codebox><codebox char_offset="157591" frame_height="260" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class Derived, class Data, class Convert = /*DefaultConstruct...*/>
class TypedValueProxyWrapper
{
public:
explicit TypedValueProxyWrapper (Convert convert = Convert ());
Derived& operator = (Data value)
{
return actual () = convert_func (value);
}
private:
Derived& actual ();
const Derived& actual () const;
Convert convert_func;
};</codebox><codebox char_offset="157664" frame_height="150" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class Data, class Wrapper>
struct DefaultConstruct
{
Wrapper DefaultConstruct (Data value)
{
return Wrapper (std::move (value));
}
};</codebox><codebox char_offset="158690" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class T>
Foo& operator= (T value)
{
return set (value);
}</codebox><codebox char_offset="158713" frame_height="96" frame_width="800" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="chdr" width_in_pixels="True">template <class T>
Foo& operator= (T& value)
{
return set (value);
}</codebox><codebox char_offset="180315" frame_height="168" frame_width="840" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">class Error : public Sgp::Exception
{
public:
explicit Error (std::string message);
};
Error::Error (std::string message) : Sgp::Exception ("MyProject Exception ::: " + message)
{
}</codebox><codebox char_offset="180356" frame_height="168" frame_width="840" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">class LogicError : public Error
{
public:
explicit LogicError (std::string message);
};
LogicError::LogicError (std::string message) : Error ("logic error: " + message)
{
}</codebox><codebox char_offset="180399" frame_height="168" frame_width="960" highlight_brackets="False" show_line_numbers="False" syntax_highlighting="cpp" width_in_pixels="True">class BusyPointerError : public LogicError
{
public:
explicit BusyPointerError (std::string message);
};
BusyPointerError::BusyPointerError (std::string message) : LogicError ("BusyPointer error: " + message)
{
}</codebox><node name="Todo" prog_lang="custom-colors" readonly="False" tags="" unique_id="191"><rich_text>[ ] 05/08/13 Learn </rich_text><rich_text style="italic">make</rich_text><rich_text> and try to add a constexpr-function-file generation process to the build process
[ ] 06/08/13 Make all template headers #include the cpp files or make tcc files which include both header and cpp and/or add "header guards" to template cpp files... in simple words, make sure a template gets included everywhere it's used
[ ] 19/09/13 Make sure IterationInterface is noncopyable, so that things like const Node::Children cannot be copied into nonconst objects
[ ] 02/10/13 Any memory allocation can fail, including a construction of an exception object. So find a safe way to wrap relevant parts with a catch of bad_alloc or out_of_memory, to make sure the app/lib doesn't just crash when out of memory
[ ] 23/10/13 I'm looking at this: </rich_text><rich_text link="webs https://wiki.gnome.org/GTK%2B/BestPractices">https://wiki.gnome.org/GTK%2B/BestPractices</rich_text><rich_text> and linked pages, and I realize I should write a style guide for my own code and use it consistently. Header guard style, use of include and "" vs. <>, etc.
[ ] 25/10/13 CommandStack feature idea: allow commands to specify whether they count in the size limit, so that memento stacks (i.e. command stores copy of document) can insert helper commands with small/no state without having to implement a derived command class CommandChain which allows extra commands to be added. The implementation can either use my own CommandChain class, or modify the size limit computations to take into account only commands which were set to affect the size (e.g. the memento commands).</rich_text></node><node name="API" prog_lang="custom-colors" readonly="False" tags="" unique_id="192"><rich_text></rich_text><node name="Task.hpp" prog_lang="cpp" readonly="False" tags="" unique_id="193"><rich_text>#ifndef _PARTAGER_TASK_HPP
#define _PARTAGER_TASK_HPP
namespace Partager
{
class Task : public Idan::Reference
{
public:
friend class TaskModel;
Task (const Task& other) : Idan::Reference (other)
{
}
void set_content (std::string content)
{
object["content"] = content;
// or
object[klass ["content"]] = content;
// or
object[klass.get_property ("content")] = content;
// or
object.set_property ("content", content);
// or
object.set_property (klass["content"], content);
// or
object.set_property (klass.get_property ("content"), content);
}
std::string get_content ()
{
return object["content"];
// or
return object["content"].get ();
// or
return object.get_property ("content");
}
/*
I could add iteration, but preferably Task implements the minimum required for the app,
and remember for-each things can be offered by Alder::Object, so no need to to wrap it in Task
unless it is actually necessary for the app.
*/
private:
Task (Alder::Object& object) : Idan::Reference (object)
{
}
};
}
#endif // _PARTAGER_TASK_HPP</rich_text></node></node></node></node></node><node name="The Name of the Language" prog_lang="custom-colors" readonly="False" tags="" unique_id="34"><rich_text></rich_text><node name="Name Suggestions" prog_lang="custom-colors" readonly="False" tags="" unique_id="35"><rich_text>In this page I collect suggested names for the new language I design.
• Idan
• CORL: Class Object Relation Language
• Slide: Semantic Desktop Language</rich_text></node></node></node><node name="Time and Resource Management" prog_lang="custom-colors" readonly="False" tags="" unique_id="139"><rich_text></rich_text></node></node></node></cherrytree>