if (a equals b) {
c = not d;
} else {
c = d + b;
}
You have this nested inner to outer logic where if is a function.
c = if(equals(a,b), not(d), plus(d,b))The first is definitely more readible [sic] and it reads like we think of the logic. No one thinks of if as a function that takes three arguments, and forcing you to work that way just makes you crazy. I suppose it is futile to argue with an admittedly crazy person, but perhaps being forced to work with conditionals has made me crazy as well. A closer translation of the original code would be this:
(if (equals a b)
(setq c (not d))
(setq c (+ d b)))
If these sorts of differences are a ``mind-bending puzzle'', perhaps the author should consider a career in the housekeeping or food-service industries.
Word cube is game in which players form words from the nine letters in a cube. Words must have four or more letters and must use the central letter from the cube; at least one word will use all nine letters in the cube. The player who forms the most words wins. Many newspapers publish a word cube on their puzzle page, and Stealthcopter publishes a word cube on line daily. Wikipedia describes word cubes under the caption “word polygon.” There are twelve words formed from the word cube at right: bonnie, bunion, coin, concubine, conic, cubic, ennui, icon, nice, nine, nuncio, and union.
Your task is to write a program that finds all matching words for a given word cube. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
The MSF beginner’s riders class that I took a month or so ago required shoes that covered the ankles and I ended up buying a pair of the Brahma Hutch II lace-less steel-toe boots from Walmart. Wearing now for a about a month I’ve been really impressed; they are comfortable, broke in really easily, and slip on and off pretty quickly. Perhaps the only downside for motorcycle-riding is that the steel-toe makes for awkward shifting and breaking. For that reason I’m looking at buying some real motorcycle boots pretty soon; in particular the TCX X-Five.
All in all for only $30USD this is a really nice boot.
After a good bit of research I decided to go with a Shoei RF1100. After a few hundred miles I’ve found it to be really nice; comfortable, a lot of air goes through it, and it doesn’t squeal when you are sitting behind a windshield like a couple of reviews that I had read suggested.
Perhaps the most bothersome discovery is the ridge on the top of my head that is going to force me to purchase some extra padding or something to level out the top of the helmet so it quits giving me a headache!
One “funny” thing I found in the owner’s manual was a warning that if you purchase the Matte Black helmet then you need to be extra, extra-careful about protecting its finish. Great!
We examined in a previous exercise a program that extracts a chronological listing of the exercises on the Programming Praxis website from the praxis.info file. We also discussed in a previous exercise a program that creates a permuted index. In today’s exercise we will combine those two programs into the program that is used to create the Permuted Table of Contents page at Programming Praxis.
The format of the praxis.info file was given in a previous exercise. The output from today’s program should look like this:
<table cellpadding="10">
<tr><td>129</td><td>20 Apr 2010</td><td align="right"> </td><td>145 Puzzle: Build and evaluate expressions using the digits one through nine and the simple arithmetic operators</td><td><a href="/2010/04/20/145-puzzle/">exercise</a> <a href="/2010/04/20/145-puzzle/2/">solution</a> <a href="http://programmingpraxis.codepad.org/SzbrJbjx">codepad</a></td></tr>
<tr><td>51</td><td>17 Jul 2009</td><td align="right">International Mathematical Olympiad: Three exercises from</td><td>1960s math competitions</td><td><a href="/2009/07/17/international-mathematical-olympiad/">exercise</a> <a href="/2009/07/17/international-mathematical-olympiad/2/">solution</a> <a href="http://programmingpraxis.codepad.org/JRGmt2wZ">codepad</a></td></tr>
...
</table>
Your task is to write a program that reads praxis.info and produces the permuted table of contents. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
(require (planet bzlib/shp:1:3)) (require "web.ss") will start the example site. The example site is still just trivial code right now - it will eventually be enhanced and separated into its own package. shp/api/add2, which contains the following:
;; -*- scheme -*- -p
(:api-args (a number?) (b number?))
(+ a b)a and b, and return the added result. To write an api script, you must use the :api-args expression, and then supply the arguments inside. The arguments can be specified in the following forms:
(:api-args a b) ;; both a & b are non-validating and you get what's passed in
(:api-args (a number?) (b string?)) ;; a expects a number, and b expects a string
(:api-args (a number? 3) (b number? 5)) ;; a & b both expect numbers, and both have default values if they are not passed in (a defaults to 3, and b defaults to 5).
GET /api/add2 HTTP/1.0
Content-Type: text/xml; charset=utf-8
<methodResponse>
<fault>
<value>
<string>required: a</string>
</value>
</fault>
</methodResponse>
a or b is passed in.
GET /api/add2?&a=50&b=90 HTTP/1.0
Content-Type: text/xml; charset=utf-8
<methodResponse>
<params>
<param>
<value>
<int>140</int>
</value>
</param>
</params>
</methodResponse>add2 script contains args of (a number?) and (b number?), which mean that both a & b expects a number input. So if we pass a non-number to the api
GET /api/add2?&a=not-a-number&b=also-not-a-number HTTP/1.0
<methodResponse>
<fault>
<value>
<string>invalid-conversion: "not-a-number"</string>
</value>
</fault>
</methodResponse>
POST /api/add2 HTTP/1.0
Content-Type: text/xml; charset=utf-8
<methodCall>
<methodName>add2</methodName>
<params>
<param><name>a</name><value><int>50</int></value></param>
<param><name>b</name><value><int>90</int></value></param>
</params>
</methodCall>
Content-Type: text/xml; charset=utf-8
<methodResponse>
<params>
<param>
<value>
<int>140</int>
</value>
</param>
</params>
</methodResponse>add2 is specified twice in the request - once in the path, and once in the methodName parameter in the payload. And if you were to use a bogus method name such such as add3 in the methodName parameter, you will see that it is being ignored - the path has precedence. methodName parameter will be ignored. add2 from the path, as follows:
POST /api HTTP/1.0 # notice - no add2 here
Content-Type: text/xml; charset=utf-8
<methodCall>
<methodName>add2</methodName>
<params>
<param><name>a</name><value><int>50</int></value></param>
<param><name>b</name><value><int>90</int></value></param>
</params>
</methodCall>/api/add2, just post to /api, and specify add2 in the methodName parameter. This is called partial path dispatch, for the lack of a better term for now. /api directory must not contain an index script, because otherwise the index script will be matched first prior to the partial dispatch kicking in. **. So for example, if we want to dispatch to /api/add2, we can dispatch as follows:
POST /api?**add2 HTTP/1.0 # note the **add2 key in the query string.
Content-Type: text/xml; charset=utf-8
<methodCall>
<methodName>add3</methodName><!-- note the wrong method name -->
<params>
<param><name>a</name><value><int>50</int></value></param>
<param><name>b</name><value><int>90</int></value></param>
</params>
</methodCall>** prefix will be stripped, and then appended to the path. And this rule, along with the direct dispatch, supersedes the method name in the xmlrpc payload. +, -, *, /, = submit buttons, you can theoretically have the following scripts:
/api/add
/api/subtract
/api/multiply
/api/divide
/api/equal **add, **subtract, **multiply, **divide, and **equal, and map the form's action to /api. SHP will do the dispatching for you correctly.
POST /api/add2 HTTP/1.0
Content-Type: text/json; charset=utf-8
{ a : 50 , b : 90 }
Content-Type: text/json; charset=utf-8
140 ~jsonp query string parameter as follows:
POST /api/add2?~jsonp=myCallback HTTP/1.0
Content-Type: text/json; charset=utf-8
{ a : 50 , b : 90 }
Content-Type: text/json; charset=utf-8
return myCallback( 140 ); Chris Aldrich reads a lot of good books. I enjoy hearing about what he has read lately and thought that it would be nice to share his thoughts so I offered that he could post here if he was interested (or until he blogged elsewhere or whatever). He said yes. His user-name is caldrich.
See here.
In 1918, John Byrne invented a two-disk cryptographic machine, which he called a chaocipher; he drew up blueprints, but was unsuccessful in his efforts to sell the machine to the US Signal Corps and Navy. He left several challenge messages in his 1954 autobiography, but no one successfully deciphered the messages. Recently, following the death of Byrne’s son, the son’s widow donated Byrne’s complete archives, including a mock-up of the machine, to the National Cryptologic Museum at Fort Meade, Maryland. Last Friday, Moshe Rubin published the first public description of the chaocipher algorithm.
The algorithm uses two key sequences, one for cipher-text and one for plain-text. Encryption and decryption look up the desired character on one sequence and report the corresponding character on the other sequence, working from plain-text to cipher-text for encryption and from cipher-text to plain-text for decryption.
After each character, both sequences are permuted, each by a different method. Thus, the chaocipher is similar to an autokey cipher, because the key is modified according to the plain-text.
The left disk, which normally represents the cipher-text, is permuted in two steps. First, the entire alphabet is shifted left as far as cipher-text of the current character (so the current cipher-text character becomes the first character in the sequence), with the shifted-off portion of the sequence reattached at the end. Second, the second through fourteenth characters are shifted left one character, and cycled; the third character becomes the second, the fourth character becomes the third, and so on, until the fourteenth character becomes the thirteenth and the second character becomes the fourteenth. For instance, given the sequence HXUCZVAMDSLKPEFJRIGTWOBNYQ and the current character P, the entire sequence is shifted to bring P to the front, giving PEFJRIGTWOBNYQHXUCZVAMDSLK, then the second through fourteenth characters are shifted to move E after Q, giving PFJRIGTWOBNYQEHXUCZVAMDSLK. Byrne invented the terms zenith and nadir to represent the first and fourteenth characters, Rubin refers to zenith and zenith+13, but we’ll just call them by their ordinal positions in the sequence.
The right disk, which normally represents the plain-text, is permuted in three steps. First, the entire alphabet is shifted left as far as the plain-text of the current character (so the current plain-text character becomes the first character in the sequence), with the shifted-off portion of the sequence reattached at the end. Second, the first character is shifted to the end (so the current plain-text character becomes the last character in the sequence). Third, the third through fourteenth characters are shifted left one character, and cycled, similar to the left disk except for the different starting position. For instance, given the sequence PTLNBQDEOYSFAVZKGJRIHWXUMC and the current character A, the final sequence is VZGJRIHWXUMCPKTLNBQDEOYSFA.
Thus, the encryption of WELLDONEISBETTERTHANWELLSAID, given the above cipher-text and plain-text sequences, is OAHQHCNYNXTSZJRRHJBYHQKSOUJY.
Your task is to write functions that perform encryption and decryption according to the algorithm given above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
You may have noticed that the Contents page changed recently. Previously the Contents page listed all the exercises in chronological order. Now, there are four listings of the exercises, in chronological order, reverse chronological order, permuted by the words in the title and summary, and organized manually by themes.
The four listings all derive from a single source. The file praxis.info consists of records separated by blank lines, fields on a single line with field name followed by a tab character followed by the data element. Here is an excerpt, which shows the header at the beginning of the file followed by the first two records:
praxis.info
number exercise number
file base name of files
pubmon month of publication
pubday day of publication
pubyear year of publication
title formatted title
ptitle plain title
blurb formatted blurb
pblurb plain blurb
exer exercise sub-page number
soln solution sub-page number
extra extra info sub-page number
codepad eight-character codepad index
theme category in which exercise appears
name/value pairs on a line separated by tabs,
with records separated by blank lines
the "number" field must appear first, others
may be in any order, and are optional
----+----1----+----2----+----3----+----4----+----5----+----6
number 1
file rpn-calculator
pubmon 2
pubday 19
pubyear 2009
title RPN Calculator
blurb Evaluate numeric expressions at the command line
exer 1
soln 2
codepad fjzlC50x
theme Parsing
number 2
file sieve-of-eratosthenes
pubmon 2
pubday 19
pubyear 2009
title Sieve of Eratosthenes
blurb A Scheme implementation of an ancient algorithm
exer 1
soln 2
codepad wI14BJ8Q
theme Prime Numbers
Four programs manipulate the data from the praxis.info file to produce the four listings. The output has elements of html, but WordPress adds the surrounding context; here is the corresponding excerpt from the listing in chronological order:
<table cellpadding="10">
<tr><td>1</td><td>19 Feb 2009</td><td><a href="/2009/02/19/rpn-calculator/">RPN Calculator</a>: Evaluate numeric expressions at the command line</td><td><a href="/2009/02/19/rpn-calculator/">exercise</a> <a href="/2009/02/19/rpn-calculator/2/">solution</a> <a href="http://programmingpraxis.codepad.org/fjzlC50x">codepad</a></td></tr>
<tr><td>2</td><td>19 Feb 2009</td><td><a href="/2009/02/19/sieve-of-eratosthenes/">Sieve of Eratosthenes</a>: A Scheme implementation of an ancient algorithm</td><td><a href="/2009/02/19/sieve-of-eratosthenes/">exercise</a> <a href="/2009/02/19/sieve-of-eratosthenes/2/">solution</a> <a href="http://programmingpraxis.codepad.org/wI14BJ8Q">codepad</a></td></tr>
</table>
Your task is to write programs that read praxis.info and write the two listing files for exercises in chronological order and reverse chronological order. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
On Saturday morning, inspired by Andrew Moylan’s article on Wolfram’s Blog, I sat down to work out a simulation of the knockout stage of the World Cup competition. I used the bracket shown at right, and found elo ratings of the sixteen teams, as of that morning, at Wikipedia:
1 BRA Brazil 2082
2 ESP Spain 2061
3 NED Netherlands 2045
4 ARG Argentina 1966
5 ENG England 1945
6 GER Germany 1930
7 URU Uruguay 1890
8 CHI Chile 1883
9 POR Portugal 1874
10 MEX Mexico 1873
15 USA United States 1785
19 PAR Paraguay 1771
25 KOR Korea 1746
26 JPN Japan 1744
32 GHA Ghana 1711
45 SVK Slovakia 1654
The table shows that there are forty-four national teams with ratings higher than Slovakia’s rating of 1654; they are lucky to be in the tournament.
The likelihood that a team will win its match can be computed from the elo rankings of the team and its opponent according to the formula . Thus, the United States had a 60.5% expectation of winning its match against Ghana this afternoon, and Ghana had a 39.5% expectation of defeating the United States. Harrumph!
Every time a match is played, the elo rating of a team changes. The amount of the change is based on the actual result as compared to the expected result. If a team wins when they have a high expectation of winning, their elo rating goes up by a small amount, since they were expected to win. However, if a team wins when they have a low expectation of winning, their elo rating goes up by a large amount. The formula is , where K is a weighting for the importance of the game (K is 60 for the World Cup), G is a parameter based on the goal differential (we’ll assume that all games are won by a single goal, so G = 1), W is 1 for a win and 0 for a loss, and We is the winning expectation calculated by the formula given above.
Your task is to use the data and formulas described above to simulate the knockout stage of the World Cup a million times and report the number of times each nation wins. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Last Friday I took my first real ride on the bike. It was a lot of fun. Riding a bike with a 10k redline was also a new experience for me which made it fun. Honestly, it was sort of shocking to me, the engine seemed to have 3 moods:
I wondered where the engine should live for normal cruising, and Dale explained that where it seems happy, it is happy. Great. I can’t wait to get back out again to spend some time with my M.U.T.T. Who is M.U.T.T?
As Dan explained… the “Monster Under The Tank”!
Here is a great article on how to safely have fun in the sun by minimizing your UV exposure. Perfect for summer and a fun little project.
(via lifehacker)
There are hundreds, probably thousands, of programming language. Some are general-purpose, others are intended for a limited domain. Some are useful, most get in your way. Some are just weird. We programmers frequently have to learn a new language, or re-learn an old one, or adapt to improvements from the vendor.
A good way to learn a new language is to write in the new language a familiar program from an old language with which you are experienced. Many people have written that they use the exercises at Programming Praxis as a way to get started with a new language.
Your task is to write a program that solves the Programming Praxis exercise of your choice in a programming language in which you are not proficient. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Macros are an indispensable programming feature. While procedures (functions, methods, messages etc.) let developers reuse common computation patterns, macros allow the abstraction of common syntactic constructions. These constructions can be as simple as a new control operator, or can be full domain-specific languages. For instance, there is no when operator in Scheme, but a lot of people like it. It simply tests a condition and execute a block of code if the former evaluates to true:
(when (launch-authorised? president) (fuel-missile icbm) (open-hatch silo) (launch-missile icbm))
Another example of control operator is the very useful and-let* macro, semi-standardised in SRFI-2, tests several expressions in sequence, aborting the computation if any of them evaluates to false, optionally binding variables to the expressions’s resulting values in nested scopes otherwise. If none of the expressions evaluate to false, the body is executed in the resulting lexical environment. Those familiar with Haskell may find it somewhat similar to the Maybe monad.
Actually several of Scheme’s own standard control operators are macros, implemented almost exactly as user-defined macros. A named let can be easily rewritten as a letrec operator:
;; a named let expression
(let collect ((seq (produce-list-of-numbers))
(even '())
(odd '()))
(if (null? seq)
(cons even odd)
(let ((num (car seq)))
(if (even? num)
(collect (cdr seq) (cons num even) odd)
(collect (cdr seq) even (cons num odd))))))
;; becomes a letrec expression
(letrec ((collect (lambda (seq even odd)
(if (null? seq)
(cons even odd)
(let ((num (car seq)))
(if (even? num)
(collect (cdr seq) (cons num even) odd)
(collect (cdr seq) even (cons num odd))))))))
(collect (produce-list-of-numbers) '() '()))
Macros are of course not limited to adding new control operators to a language. One can design his own little language for solving specific problems, like stocks trading. Or a data modelling language, a graphics drawing language etc. A language for object-oriented programming such as Meroon can be seamlessly embedded within Scheme. Paul Graham’s On Lisp book on advanced Common Lisp programming has several chapters devoted to macros. In short, the developer becomes almost as powerful as the language designer, and such distinction is blurred. Armed with such power, the developer becomes much more productive and, therefore, happy.
Unfortunately not many programming languages provide good macro facilities. The C preprocessor, for instance, only does textual replacement and is no aware of expressions. Granted, the syntax of the programming languages of the Lisp family is very simple and uniform, making better macros possible. Nevertheless other languages like Haskell and OCaml with more complex syntax also provide such facilities.
My Aerostich Roadcrafter suit has been ordered!
We had the pleasure to drive up there, hang out with a nice fellow named Jeff, and then I was fitted for a custom suit while Vicky took in the hi-visibilty-green with black-patch high-contrast goodness.
By the way… GO = “Glorified Overalls” :).
Our Standard Prelude provides a matrix datatype with create, lookup and setting operations. In today’s exercise we extend the matrix datatype with some mathematical operations: sum two matrices, multiply a matrix by a scalar, multiply two matrices, and transpose a matrix.
Your task is to write functions that perform the four matrix operations described above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Different applications may want to use the same symbol to mean different things. To avoid such name clashes we can use compound symbols, which have two string parts: a local name and a namespace URI. The namespace-uri can be any string, but it is recommended that it have the form of an absolute URI. It would be too verbose to write the full URI all the time, so one usually uses a namespace prefix (namespace alias) as a short local alias to refer to a namespace URI.
Compound symbols are usually written using the infix colon operator:
prefix:local-name
where prefix is is namespace alias bound to some (lexically-known) namespace URI.
Compound symbols are used for namespace-aware XML processing.
Namespace objectsA namespace is a mapping from strings to symbols. The string is the local-name of resulting symbol. A namespace is similar to a Common Lisp package.
A namespace has a namespace-uri, which a string; it recommended that it have the form of an absolute URI. A namespace may optionally have a prefix, which is a string used when printing out symbols belonging to the namespace. (If you want for “equivalent symbols” (i.e. those that have the same local-name and same uri) to be the identical symbol object, then you should use namespaces whose prefix is the empty string.)
— Constructor:namespace name [prefix]Return a namespace with the given name and prefix. If no such namespace exists, create it. The namespace-name is commonly a URI, especially when working with XML, in which case it is called a namespace-URI. However, any non-empty string is allowed. The prefix can be a string or a simple symbol. (If a symbol is used, then the symbol's local-name is used.) The default for prefix is the empty string. Multiple calls with the same arguments will yield the same namespace object.
The reader macro #,namespace is equivalent to the
namespace function, but it is invoked at read-time:
#,(namespace "http://www.w3.org/1999/XSL/Transform" xsl)
(eq? #,(namespace "foo") (namespace "foo")) ⇒ #t
The form (,#namespace "" "") returns the default empty namespace,
which is used for simple symbols.
namespace-uri namespaceReturn the namespace-uri of the argument namespace, as a string.
— Procedure:namespace-prefix namespaceReturn the namespace prefix of the argument namespace, as a string.
Compound symbolsA compound symbol is one that belongs to a namespace other than the default empty namespace, and (normally) has a non-empty namespace uri. (It is possible for a symbol to belong to a non-default namespace and have an empty namespace uri, but that is not recommended.)
— Constructor:symbol local-name namespace-specsymbol local-name [uri [prefix]]Construct a symbol with the given local-name and namespace.
If namespace-spec is a namespace object, then find (or if needed
construct) a symbol with the given local-name belonging to the
namespace. Multiple calls to symbol with the same namespace
and local-name will yield the same symbol object.
If uri is a string (optionally followed by a prefix), then:
(symbol lname uri [prefix])
is equivalent to:
(symbol lname (namespace uri [prefix]))
Using #t for the namespace-spec is equivalent to
using the empty namespace #,(namespace "").
Using #!null or #f for the namespace-spec
creates an uninterned symbol, which does not belong to
any namespace.
symbol-local-name symbolReturn the local name of the argument symbol, as an immutable string. (The string is interned, except in the case of an uninterned symbol.)
— Procedure:symbol-prefix symbolReturn the prefix of the argument symbol, as an immutable (and interned) string.
— Procedure:symbol-namespace-uri symbolReturn the namespace uri of the argument symbol, as an immutable (and interned) string.
— Procedure:symbol-namespace symbolReturn the namespace object (if any) of the argument symbol.
Returns #!null if the symbol is uninterned.
symbol=? symbol1 symbol2 symbol3 ...Return #t if the symbols are equivalent as symbols,
i.e., if their local-names and namespace-uris are the same.
They may have different values of symbol-prefix and symbol-namespace.
If a symbol is uninterned (or is #!null) then symbol=?
returns the same result as eq?.
Two symbols are equal? or eqv? if they're symbol=?.
A namespace is usually referenced using a shorter namespace alias, which is is a lexical definition that binds a namespace prefix to a namespace object (and thus a namespace uri). This allows using compound symbols as identifiers in Scheme programs.
— Syntax:define-namespace name namespace-nameDefines name as a namespace prefix - a lexically scoped "nickname" for the namespace whose full name is namespace-name, which should be a non-empty string literal. It is customary for the string have syntactic form of an absolute URI, but any non-empty string is acceptable and is used without further interpretation.
Any symbols in the scope of this definitions that contain a colon, and where the part before the colon matches the name will be treated as being in the package/namespace whose global unique name is the namespace-name.
Has mostly the same effect as:
(define-constant name #,(namespace namespace-name)
However, using define-namespace (rather than define-constant)
is recommended if you want to use compound symbols as names of
variables, especially local variables, or if you want to quote
compound symbols.
Note that the prefix is only visible lexically: it is not
part of the namespace, or thus indirectly the symbols, and
so is not available when printing the symbol.
You might consider using define-xml-namespace as an alternative.
A namespace is similar to a Common Lisp package, and the namespace-name is like the name of the package. However, a namespace alias belongs to the lexical scope, while a Common Lisp package nickname is global and belongs to the package itself.
If the namespace-name starts with the string "class:", then the
name can be used for invoking Java methods and accessing fields.
You can use a namespace as an abbreviation or renaming of a
class name, but as a matter of style define-alias is preferred.
define-private-namespace name namespace-nameSame as define-namespace, but the prefix name
is local to the current module.
For example you might have a set of a geometry definitions
defined under the namespace-uri "http://foo.org/lib/geometry":
(define-namespace geom "http://foo.org/lib/geometry")
(define (geom:translate x y)
(java.awt.geom.AffineTransform:getTranslateInstance x y))
(define geom:zero (geom:translate 0 0))
geom:zero
⇒ AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
You could have some other definitions for complex math:
(define-namespace complex "http://foo.org/lib/math/complex")
(define complex:zero +0+0i)
You can use a namespace-value directly in a compound name:
(namespace "http://foo.org/lib/geometry"):zero
⇒ AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
The variation define-xml-namespace is used for
creating XML nodes.
define-xml-namespace prefix "namespace-uri"Defines a namespace with prefix prefix and URI namespace-uri.
This is similar to define-namespace but with two important differences:
html namespace.
Thus the definition is roughly equivalent to:
(define-constant name #,(namespace namespace-name name)
along with an infinite set of definitions, for every possible tag:
(define (name:tag . rest) (apply make-element 'name:tag rest))
$ kawa --output-format xml
#|kawa:1|# (define-xml-namespace na "Namespace1")
#|kawa:2|# (define-xml-namespace nb "Namespace1")
#|kawa:3|# (define xa (na:em "Info"))
#|kawa:4|# xa
<na:em xmlns:na="Namespace1">Info</na:em>
#|kawa:5|# (define xb (nb:em "Info"))
#|kawa:6|# xa
<nb:em xmlns:nb="Namespace1">Info</nb:em>
Note that the prefix is part of the qualified name (it is actually part of the namespace object), and it is used when printing the tag. Two qualified names (symbols) that have the same local-name and the same namespace-name are considered equal, even if they have different prefix. You can think of the prefix as annotation used when printing, but not otherwise part of the “meaning” of a compound symbol. They are the same object if they also have the same prefix. This is an important different from traditional Lisp/Scheme symbols, but it is how XML QNames work.
#|kawa:7|# (instance? xb na:em)
true
#|kawa:8|# (eq? 'na:em 'nb:em)
false
#|kawa:9|# (equal? 'na:em 'nb:em)
true
#|kawa:10|# (eqv? 'na:em 'nb:em)
true
(Note that #t is printed as true when using XML formatting.)
The predefined html prefix could be defined thus:
(define-xml-namespace html "http://www.w3.org/1999/xhtml")
You can write XML literals directly in Scheme code,
following a #.
Notice that the outermost element needs to be prefixed
by #, but nested elements do (and must not).
#<p>The result is <b>final</b>!</p>
Actually, these are not really literals since they can contain enclosed expressions:
#<em>The result is &{result}.</em>
The value of result is substituted into the output, in a similar way to quasi-quotation. (If you try to quote one of these “XML literals”, what you get is unspecified and is subject to change.)
An xml-literal is usually an element constructor, but there some rarely used forms (processing-instructions, comments, and CDATA section) we'll cover later.
xml-literalElement constructors::=#xml-constructor xml-constructor::=xml-element-constructor | xml-PI-constructor | xml-comment-constructor | xml-CDATA-constructor
xml-element-constructor::=<QName xml-attribute*>xml-element-datum...</QName>|<xml-name-form xml-attribute*>xml-element-datum...</>|<xml-name-form xml-attribute*/>xml-name-form::=QName | xml-enclosed-expression xml-enclosed-expression::={expression}|(expression...)
The first xml-element-constructor variant uses a literal QName, and looks like standard non-empty XML element, where the starting QName and the ending QName must match exactly:
#<a href="next.html">Next</a>
As a convenience, you can leave out the ending tag(s):
<para>This is a paragraph in <emphasis>DocBook</> syntax.</>
You can use an expression to compute the element tag at runtime - in that case you must leave out the ending tag:
#<p>This is <(if be-bold 'strong 'em)>important</>!</p>
You can use arbitrary expression inside curly braces, as long as it evaluates to a symbol. You can leave out the curly braces if the expression is a simple parenthesised compound expression. The previous example is equivalent to:
#<p>This is <{(if be-bold 'strong 'em)}>important</>!</p>
The third xml-element-constructor variant above is an XML “empty element”; it is equivalent to the second variant when there are no xml-element-datum items.
(Note that every well-formed XML element, as defined in the XML specifications, is a valid xml-element-constructor, but not vice versa.)
Elements contents (children)The “contents” (children) of an element
are a sequence of character (text) data, and nested nodes.
The characters &, <, and > are special,
and need to be escaped.
xml-element-datum::=any character except&, or<. | xml-constructor | xml-escaped xml-escaped::=&xml-enclosed-expression |&xml-entity-name;| xml-character-reference xml-character-reference::=&#decimal-digit+;|&#xhex-digit+;
Here is an example shows both hex and decimal character references:
#<p>ABCDE</p> ⇒ <p>ABCDE</p>
Currently, the only supported values for xml-entity-name
are the builtin XML names lt, gt, amp,
quot, and apos, which stand for the characters
<, >, &, ", and ', respectively.
The following two expressions are equivalent:
#<p>< > & " '</p>
#<p>&{"< > & \" '"}</p>
Attributes
xml-attribute::=xml-name-form=xml-attribute-value xml-attribute-value::="quot-attribute-datum*"|'apos-attribute-datum*'quot-attribute-datum::=any character except",&, or<. | xml-escaped apos-attribute-datum::=any character except',&, or<. | xml-escaped
If the xml-name-form is either xmlns or
a compound named with the prefix xmlns, then
technically we have a namespace declaration, rather than
an attribute.
The names of elements and attributes are qualified names (QNames), which are represented using compound symbols (see Namespaces). The lexical syntax for a QName is either a simple identifier, or a (prefix,local-name) pair:
QName::=xml-local-part | xml-prefix:xml-local-part xml-local-part::=identifier xml-prefix::=identifier
An xml-prefix is an alias for a namespace-uri,
and the mapping between them is defined by a namespace-declaration.
You can either use a define-namespace form, or you
can use a namespace declaration attribute:
xml-namespace-declaration-attribute::=xmlns:xml-prefix=xml-attribute-value |xmlns=xml-attribute-value
The former declares xml-prefix as a namespace alias for the namespace-uri specified by xml-attribute-value (which must be a compile-time constant). The second declares that xml-attribute-value is the default namespace for simple (unprefixed) element tags. (A default namespace declaration is ignored for attribute names.)
(let ((qn (element-name #<gnu:b xmlns:gnu="http://gnu.org/"/>)))
(list (symbol-local-name qn)
(symbol-prefix qn)
(symbol-namespace-uri qn)))
⇒ ("b" "gnu" "http://gnu.org/")
Other XML types
Processing instructions
An xml-PI-constructor can be used to create an XML
processing instruction, which can be used to pass
instructions or annotations to an XML processor (or tool).
(Alternatively, you can use the processing-instruction
type constructor.)
xml-PI-constructor::=<?xml-PI-target xml-PI-content?>xml-PI-target::=NCname (i.e. a simple (non-compound) identifier) xml-PI-content::=any characters, not containing?>.
For example, the DocBook XSLT stylesheets can use the dbhtml
instructions to specify that a specific chapter should be
written to a named HTML file:
#<chapter><?dbhtml filename="intro.html" ?>
<title>Introduction</title>
...
</chapter>
XML comments
You can cause XML comments to be emitted in the XML output document.
Such comments can be useful for humans reading the XML document,
but are usually ignored by programs.
(Alternatively, you can use the comment type constructor.)
xml-comment-constructorCDATA sections::=<!--xml-comment-content-->xml-comment-content::=any characters, not containing--.
A CDATA section can be used to avoid excessive use of
xml-entity-ref such as & in element content.
xml-CDATA-constructor::=<![CDATA[xml-CDATA-content]]>xml-CDATA-content::=any characters, not containing]]>.
The following are equivalent:
#<p>Specal characters <![CDATA[< > & ' "]]> here.</p>
#<p>Specal characters < > & " ' here.</p>
Kawa remembers that you used a CDATA section in
the xml-element-constructor and will write it out
using a CDATA constructor.