2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
6 <chapter id="implementation-defined-behaviour">
7 <title>Implementation Defined Behaviour</title>
10 The specification of the XEXPR language is laid out in a W3C note of
11 <ulink url="http://www.w3.org/TR/2000/NOTE-xexpr-20001121">21 November
12 2000</ulink>. However, the specification leaves quite a bit of
13 information to be deduced from the examples and leaves other parts of
14 the language loosly specified. This chapter documents the way that
15 libxexpr implements the language and gives the rationale for each
19 <sect1 id="idb-numbers">
20 <title>Numbers</title>
23 Numbers are defined in pseudo-BNF as:
25 number : whitespace sign simple-number whitespace
34 simple-number : 0x[0-9A-Fa-f]+
37 | [0-9]+\.[0-9]+[eE][+-][0-9]+
40 that is: they have an optional leading sign and may be surrounded with
44 <simplesect id="idb-numbers-rationale">
45 <title>Rationale</title>
48 While negative numbers can be created using <subtract> without
49 the need for any signs, this seems overly cumbersome.
53 The examples in the specification make it clear that where two numbers
54 are seperated by a space, this should be parsed as just two numbers
55 and not two numbers plus an interveening string which a strict reading
56 of the specification would imply.
61 <sect1 id="idb-bindings">
62 <title>Bindings</title>
65 Bindings are parsed as integers, floats or strings in that order (ie.,
66 the first type that matches will be used). Thus the following pairs
67 of expressions are equivalent:
69 <func x="+01 "/>
72 <define name="x"><integer>1</integer></define>
75 <func x=" 14.0e-1"/>
78 <define name="x"><float>1.4</float></define>
81 <func x="Hello "/>
84 <define name="x"><string>Hello </string></define>
88 <simplesect id="idb-bindings-rationale">
89 <title>Rationale</title>
92 This seems to satisfy the doctrine of least-surpise.
97 <sect1 id="idb-pcdata">
98 <title>Parsing of PCDATA</title>
101 When numbers and strings are mixed in PCDATA, any whitespace surrounding
102 the numbers is taken to be part of the numbers rather than the strings.
103 Thus the following two expressions are equivalent:
105 <foo>This is the 0xdeadbeef constant.</foo>
108 <string>This is the</string>
109 <integer>0xdeadbeef</integer>
110 <string>constant.</string>
115 <simplesect id="idb-pcdata-rationale">
116 <title>Rationale</title>
119 This seems more consistent with spaces between numbers not being
120 parsed as strings than the alternative.
125 <sect1 id="idb-define">
126 <title>The <define> Function</title>
129 The <define> function creates a new function in the environment in
130 which it is invoked. This is different than the <set> function
131 which will modify the definition of an existing function if such exists.
132 Only if no such function is defined in any of the active environments will
133 <set> create a new function (and then in the outermost, or global,
137 <simplesect id="idb-define-rationale">
138 <title>Rationale</title>
141 We know from the examples in the specification (eg., in
142 <ulink url="http://www.w3.org/TR/xexpr/#id-0045">section 45</ulink>)
143 that <subtract> changes the definition of its first argument
144 in at least the grandfather environment. It makes sense that <set>
145 should do the same. When we come to <define>, however, we
146 know from <ulink url="http://www.w3.org/TR/xexpr/#id-0003">section
147 3</ulink> that it is equivalent to an attribute on the parent element
148 and so it makes sense that it should create a variable in the parent
155 <title>The <get> Function</title>
158 The following two expressions are equivalent:
160 <get name="x"/>
161 <get>x</get><!--
163 The expression <x/> has the same effect except in the case of
164 <add> and <subtract> where these two expressions are
167 <add><x/>1</add>
168 <add><get>x</get>1</add><!--
170 The first changes the definition of <x>, the second does not.
174 Note that IDs are allowed to start with the dot (.) and hyphen (-)
175 characters which are not valid as the first character in XML tags.
176 Thus get must be used in the following:
179 <define name=".net">4.5.50709</define>
180 <print><get>.net</get></print>
186 Since <get> returns a function definition (just like
187 <define>), it is possible to define functions of this type that
188 take arguments and even invoke them in a somewhat circuitous manner:
191 <define name=".product" args="a b c d">
205 <define name="closure"/>
206 <set name="closure">
207 <get>.product</get>
209 <closure>1 2 3 4</closure>
215 <simplesect id="idb-get-rationale">
216 <title>Rationale</title>
219 <ulink url="http://www.w3.org/TR/xexpr/#id-0014">Section 14</ulink>
220 tells us that <get>x</get> and <x/> have the same
221 effect in most cases (and thus presumably not all cases) and it
222 would seem surprising if <get> were not to insulate a
223 function in this manner.
228 <sect1 id="idb-arithmetic">
229 <title>Arithmetic Operators</title>
232 The empty arithmetic operators (<add/>, <subtract/>,
233 <multiply/> and <divide/>) all evaluate to <nil/>.
237 The <add> and <subtract> operators change their first
238 argument in some circumstances as in this example from the specification:
241 <gt><x/> 0</gt>
243 <print newline="true"><x/><print>
244 <subtract><x/> 1</subtract>
251 In general, the first agument will be modified if it is a function
252 invocation that has no bindings and no arguments. Thus the following
255 <define name="x"><multiply>2 3</multiply></define>
256 <add><x/>3</add>
257 <print><x/></print><!--
259 whereas this will print 6:
261 <define name="x"><multiply>2 3</multiply></define>
262 <add><x unused=""/>3</add>
263 <print><x/></print><!--
268 Where arguments are modified, this occurs as the arguments are being
269 evaluated. Thus this expression:
271 <add><x/><x/><x/></add><!--
273 will multiply <x> by 4 rather than by 3.
276 <simplesect id="idb-arithmetic-rationale">
277 <title>Rationale</title>
280 The examples in the specification imply that <add> and
281 <subtract> modify their first argument when it is a
282 variable. The iterative example in
283 <ulink url="http://www.w3.org/TR/xexpr/#id-0008">section 8</ulink>
284 wouldn't work if <multiply> worked the same way (and the
285 definition of <2pi> in <ulink
286 url="http://www.w3.org/TR/xexpr/#id-0007">section 7</ulink> would
287 not be expected to modify the definition of <pi> each time
288 it is called). Note that this example is erroneous: IDs can't contain
293 It seems undesirable to modify functions that take arguments.
294 Making the decision based on the invocation rather than the
295 function definition makes expressions much easier to read.
300 <sect1 id="idb-comparison">
301 <title>Comparison Functions</title>
304 The empty comparison functions (<eq/>, <neq/>, <leq/>,
305 <geq/>, <lt/> and <gt/>) and comparison functions with
306 exactly one argument all evaluate to <true/>.
310 The ordered comparison functions (<leq>, <geq>, <lt>
311 and <gt>) act as if the equivalent mathematical operator was
312 inserted between their arguments. Thus:
318 is equivalent to the mathematical expression:
319 <screen>1 < 2 < 3</screen>
326 is equivalent to the mathematical expression:
327 <screen>1 ≤ 2 ≤ 3</screen>
331 When comparing objects of different types:
334 Numbers will be implicitly cast between <float> and
335 <integer> where that involves no loss of precision
338 Strings will be compared byte-by-byte as UTF8 encoded strings
341 Functions will always be completely evaluated
344 Invocations of the constant functions are ordered as <false/>
345 < <nil/> < <true/>
350 <simplesect id="idb-comparison-rationale">
351 <title>Rationale</title>
354 The empty comparison functions equaluate to <true> by analogy
355 with the comparison functions.
359 The ordering of the comparison functions is confused in the
360 specification with the examples for <lt> and <gt> agreeing
361 with libxexpr's behaviour and the examples for <leq> and
362 <geq> doing the opposite. The choice was arbitary.
367 <sect1 id="idb-redefining-builtins">
368 <title>Redefining Builtin Functions</title>
371 Attempting to redefine a builtin function results in an error.
374 <simplesect id="idb-redefining-builtins-rationale">
375 <title>Rationale</title>
378 While this could be implemented, there is no mention of it in the
379 specification and it would complicate the implementation with no
385 <sect1 id="idb-namespaces">
386 <title>Namespaces</title>
389 libxexpr considers an element's namespace to be part of its name
390 and thus elements in a namespace other than the XEXPR namespace as
391 are always distinct from functions defined by XEXPR. In addition,
392 functions defined using <define> are defined in the
397 libxexpr provides hooks for extending the XEXPR language by allowing
398 handlers to be installed for other namespaces.
402 Elements which are in no namespace are treated as if they were in the
406 <simplesect id="idb-namespaces-rationale">
407 <title>Rationale</title>
410 Being able to extend the XEXPR language is vital for it to be useful
411 and namespaces are the obvious way to do this.