Planet Scheme

Syndicate content
Updated: 4 hours 38 min ago

Joe Marshall: Crazy person thinks ``Lisp sucks''

Tue, 07/13/2010 - 20:18
In this post, a person going by the initials CC declares: There's a good reason almost no software has been written in lisp. Lisp sucks. Not just lisp, but the whole way the logic is arranged as nested things. The simplest problem becomes a mind-bending puzzle. Instead of easy to understand:
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.

Programming Praxis: Word Cube

Tue, 07/13/2010 - 10:00

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.


Grant Rettke: Bought some nice work boots

Mon, 07/12/2010 - 20:42

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.

Grant Rettke: Bought a helmet

Mon, 07/12/2010 - 20:35

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!

Programming Praxis: Contents: Permuted Table Of Contents

Fri, 07/09/2010 - 10:00

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">&nbsp;</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.


Yinso Chen: BZLIB/SHP.plt 0.4 now available - Web API

Thu, 07/08/2010 - 20:33
A new version of SHP.plt is now available via planet.  This is a major rewrite of SHP and provides two main upgrades:
  • a "web API" interface - your web script can now be exposed as an "API" (think XMLRPC/JSON), and it automatically works with either XMLRPC or JSON (details below)
  • general performance enhancement - the scripts are now compiled and cached to reduce disk IO.  If the scripts are updated then they are automatically recompiled
As usual, the code is released under LGPL.

Installation 
(require (planet bzlib/shp:1:3)) 

SHP requires some newer dependencies (bzlib/base:1:6, bzlib/date:1:3, bzlib/parseq:1:3, bzlib/xml:1:3, bzlib/mime:1:0), and the current versions of PLT Scheme and Racket have issues with version dependencies (the link: module mismatch bug), so you might have to clear out the planet cache and recompile them again.

As usual, SHP comes with a small example site that you can play with under the example sub directory - cd to the example directory and run (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.

Cached Compiled Script All of the scripts are now compiled and cached.  This has some potential performance benefit, since we will only access the file content when the file timestamp changes (meaning the file has been touched and/or modified).  As this is a non-visible feature, we won't spend much time discussing it, except to note that the change is not just done for performance reasons - it is also done to enable and simplify the design of web api, which is discussed below.

Web APIUnder the example site you can find the script shp/api/add2, which contains the following:


;; -*- scheme -*- -p 
(:api-args (a number?) (b number?)) 
(+ a b)

This is the new *web api* - it takes in 2 numbers, 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). 

When you run the example site you can access the api via the following http call:

GET /api/add2 HTTP/1.0 

When running the above in browser you should get back an XMLRPC response:

Content-Type: text/xml; charset=utf-8 

<methodResponse>
<fault>
<value>
<string>required: a</string>
</value>
</fault>
</methodResponse>

XMLRPC is the default response mode for web APIs.  What it returns by default as shown above is an error message, because neither a or b is passed in.

To pass in the values - you just need to specify them in the query string as following:


GET /api/add2?&a=50&b=90 HTTP/1.0 

which will return the following:

Content-Type: text/xml; charset=utf-8

<methodResponse>
<params>
<param>
<value>
<int>140</int>
</value>
</param>
</params>
</methodResponse>

The 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 

we get the following:


<methodResponse>
<fault>
<value>
<string>invalid-conversion: "not-a-number"</string>
</value>
</fault>
</methodResponse>

Which shows that the validation takes place for each of the arguments.  We will talk about how the underlying validation magic works later.

XMLRPC Request Payload Now the API doesn't just work for query string parameters - you can pass in an XMLRPC payload as well.  To do so you need to use POST instead of GET, and put the following XMLRPC request into the payload:


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>

Which will return the same result:


Content-Type: text/xml; charset=utf-8

<methodResponse>
<params>
<param>
<value>
<int>140</int>
</value>
</param>
</params>
</methodResponse>

Partial Path Dispatch with XMLRPC methodName You might have noticed in the above that the token 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.

So - the dispatch rule is - if the path matches the script exactly, the methodName parameter will be ignored.

This is designed to follow the same dispatching rule of regular SHP scripts, and to ensure that one script compiles into one api. 

But if you like to use the regular XMLRPC dispatch, it also works - you just need to remove the 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>

So instead of posting to /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.

NOTE - in order for partial dispatch to work, the /api directory must not contain an index script, because otherwise the index script will be matched first prior to the partial dispatch kicking in.

Partial Path Dispatch With Query String There is another way of doing partial path dispatch, and that involve the using of query string.  Yes, you can specify query string with POST requests, and the query string values will be parsed properly in SHP.

The way to do it is to specify a query key that starts with **.  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>

The above has exactly the same effect as if you have done a direct dispatch - the ** 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.

This design exists for a reason - to deal with web forms that have multiple submit buttons

Web forms that have multiple submit buttons usually have each button mapped to different actions, and instead of requiring you to do manual dispatch on the server side based on which button is clicked (the name & value of the submit button clicked gets submitted to the server side along with the data), you can partition the API calls based on the name of the button (partition on name instead of the value is better, because that way it allows you to localize the value without worrying about breaking the script). 

For example, if you have a server-side-based calculator that has the +, -, *, /, = submit buttons, you can theoretically have the following scripts:


/api/add 
/api/subtract
/api/multiply
/api/divide
/api/equal 

And then have the buttons mapped to the name of **add, **subtract, **multiply, **divide, and **equal, and map the form's action to /api.  SHP will do the dispatching for you correctly.

JSON Request & Responses Besides working with query strings and XMLRPC request and responses, the same api script also can handle JSON requset & responses - you just need to POST the payload with the appropriate content-type, which is text/json.


POST /api/add2 HTTP/1.0 
Content-Type: text/json; charset=utf-8 

{ a : 50 , b : 90 } 

And the response will automatically be a JSON as well:


Content-Type: text/json; charset=utf-8 

140 

Since JSON does not have a method name parameter, it does not have a corresponding partial path dispatch rule, but the query string's partial path dispatch rule remains in effect. 

And of course if you are using JSON you will want to use JSONP, which you can by specifying an additional ~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 } 

Which will generate the following response as a JSONP result:


Content-Type: text/json; charset=utf-8

return myCallback( 140 ); 

That explains the basic rules with regards to using the web api.  The next post will discuss the syntax of the web API, as well as how to extend it so you can use other types.

Grant Rettke: Welcoming Chris Aldrich

Thu, 07/08/2010 - 13:35

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.

Programming Praxis: Chaocipher

Tue, 07/06/2010 - 10:00

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.


Programming Praxis: Contents: Chronological Listing Of Exercises

Fri, 07/02/2010 - 10:00

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.


Programming Praxis: World Cup Prognostication

Tue, 06/29/2010 - 10:00

Drawn by Kathryn BewigOn 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 \frac{1}{1 + 10^{(elo_{them} - elo_{us})/400}}. 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 elo_{new} = elo_{old} + KG(W-W_e), 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.


Grant Rettke: I love my M.U.T.T.

Mon, 06/28/2010 - 20:19

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:

  1. Meditating
  2. Purring
  3. Roaring!

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”!

Grant Rettke: Fun in the sun

Fri, 06/25/2010 - 13:56

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)

Programming Praxis: Learn A New Language

Fri, 06/25/2010 - 10:00

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.


Alex Queiroz: Praising macros

Thu, 06/24/2010 - 22:37

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.

Joe Marshall: Dr Scheme name change

Thu, 06/24/2010 - 20:31
I put together a page that compares the various names of Dr. Scheme by how often people search for them in Google.

Grant Rettke: The GO suit is ordered

Wed, 06/23/2010 - 05:09

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” :).

Programming Praxis: Matrix Operations

Tue, 06/22/2010 - 10:00

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.

  • Addition of two matrices is done by adding elements in corresponding positions, assuming identical dimensions. For example:

    \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} + \begin{pmatrix} 2 & 3 & 4 \\ 3 & 4 & 5 \end{pmatrix} = \begin{pmatrix} 3 & 5 & 7 \\ 7 & 9 & 11 \end{pmatrix}

  • Multiplying a scalar times a matrix is done by multiplying the scalar times each element in turn. For example:

    2 \times \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix}  = \begin{pmatrix} 2 & 4 & 6 \\ 8 & 10 & 12 \end{pmatrix}

  • The product of an m×n matrix A and an n×p matrix B is the m×p matrix C whose entries are defined by C_{i,j} = \sum_{k=0}^{n-1} A_{i,k} \times B_{k,j}. For example:

    \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} \times \begin{pmatrix} 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 5 \\ 3 & 4 & 5 & 6 \end{pmatrix} = \begin{pmatrix} 14 & 20 & 26 & 32 \\ 32 & 47 & 62 & 77 \end{pmatrix}

  • The transpose of a matrix interchanges the rows and columns of a matrix. For example:

    \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix}^{T} = \begin{pmatrix}1 & 4 \\ 2 & 5 \\ 3 & 6 \end{pmatrix}

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.


Per Bothner: Namespaces and compound symbols

Tue, 06/22/2010 - 03:29
This article talks about Kawa's support for compound symbols and namespaces. The basic support has been there for a while, but some features are new, and the documentation is more complete. (This is an extract from the SVN version of the Kawa manual.) Namespaces and compound symbols

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 objects

A 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.

— Procedure: namespace-uri namespace

Return the namespace-uri of the argument namespace, as a string.

— Procedure: namespace-prefix namespace

Return the namespace prefix of the argument namespace, as a string.

Compound symbols

A 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-spec
— Constructor: symbol 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.

— Procedure: symbol-local-name symbol

Return 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 symbol

Return the prefix of the argument symbol, as an immutable (and interned) string.

— Procedure: symbol-namespace-uri symbol

Return the namespace uri of the argument symbol, as an immutable (and interned) string.

— Procedure: symbol-namespace symbol

Return the namespace object (if any) of the argument symbol. Returns #!null if the symbol is uninterned.

— Procedure: 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=?.

Namespace aliases

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-name

Defines 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.

— Syntax: define-private-namespace name namespace-name

Same 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.

— Syntax: 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:

  • Every symbol in the namespace automatically maps to an element-constructor-type, as with the html namespace.
  • The prefix is a component of the namespace object, and hence indirectly of any symbols belongining to the 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")

Per Bothner: XML literals

Tue, 06/22/2010 - 03:21
XML literals are a new feature in Kawa. They make it more convenient to write XML data objects, especially if you're familar with XML syntax. (This is an extract from the SVN version of the Kawa manual.)

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-literal ::= #xml-constructor
     xml-constructor ::= xml-element-constructor
       | xml-PI-constructor
       | xml-comment-constructor
       | xml-CDATA-constructor
Element constructors
     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>&lt; &gt; &amp; &quot; &apos;</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.

QNames and namespaces

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-constructor ::= <!--xml-comment-content-->
     xml-comment-content ::= any characters, not containing --.
CDATA sections

A CDATA section can be used to avoid excessive use of xml-entity-ref such as &amp; 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 &lt; &gt; &amp; &quot; &apos; here.</p>

Kawa remembers that you used a CDATA section in the xml-element-constructor and will write it out using a CDATA constructor.