An invitation to FP for Clojure noobs

I’ve heard newcomers to Clojure ask how to get started with functional programming. I believe that learning to program in the functional style is mostly a matter of practice. The newcomer needs to become familiar with a handful of higher order functions, and how they are used in common idioms. This can be done by practice with simple, well defined problems. I assume that the prospective reader already has a grasp of the rudiments of Clojure, and can operate the Leiningen build tool.

Here is what I propose. I have prepared a set of annotated exercises illustrating typical Clojure fp idioms. The exercises are the first 31 Project Euler problems, one for each day of the month. I believe these problems are ideal for the purpose at hand. Each problem is succinctly stated, interesting, and well defined. Each lends itself to a natural functional solution.

I have packaged the problems as a Leiningen project. Each problem is stated, and then solved. Each problem is in its own name space, to enable code reuse across problems. Each problem is documented using the fabulous Marginalia literate programming tool. Running commentary tries to point out common idioms, and provides links to ClojureDocs documentation for newly introduced functions. Unit tests are provided to check the provided solution against the official Project Euler solution. The solutions use current Clojure (1.4.0 beta). Nothing is used from the old clojure.contrib. Each solution is written in an explicitly functional style. Many of the solutions consist solely of function definitions. Vars are used only to name data given as part of a problem statement, or data structures constructed from such data. All data is treated as immutable.

What I recommend is deceptively simple. Read each problem statement. Think about how you might solve it; do so if you like. Then read the provided solution. Read it actively: take the time to run the code, and to understand every function and every construct in the solution. Play with the code. Make changes, run things in the repl. Use ‘lein test’ to see whether your modifications still get the same answer.

Here’s the important point: once you understand the solution, delete it and then reconstruct it. Type it in. Look up functions you don’t remember. Did I mention you should type the code in? Knowledge enters the mind through the fingers, not just the eyes. Do this and I believe you will quickly jump-start your understanding of functional programming in Clojure.

Here are a few things to avoid.

Do not attempt to learn Clojure and new tooling, say Emacs+slime, at the same time. Keep it simple. Edit code using whatever editor you normally use, and run a Clojure repl in whatever terminal emulator you normally use. No fancy IDE or editor hacking is required. Separation of concerns applies to learning as much as to coding.

Don’t worry about parts of Clojure not immediately related to functional programming. In particular, don’t worry about concurrency constructs, STM, protocols, multi-methods, macros, transients, or whatever. Instead, worry about knowing how to define functions using any and all of (defn …), (def …), #(…), and (fn …). Learn map, filter, reduce, for, let, letfn, and iterate.

The Project Euler problems do require a bit of math. Don’t let that put you off. Worst comes to worst, I have already done the math for you. The goal here is to learn fp not math, so don’t get hung up on solving the problems ab initio. The problems are a device to present solutions written in a functional style. If a particular problem hangs you up, skip it.

Don’t worry about lambda calculus, type theory, category theory, monads, morphisms, or any such abstract concerns. Your functional programming journey may eventually take you to those, but you need not start there. Abstraction is best appreciated in the light of experience with concrete examples. Begin by reading and writing code to many solve small, concrete problems. See what the solutions have in common. That is what you want to learn. The more these solutions seem like variations on a theme, the better.

When I first started learning Clojure, I did so by working Project Euler problems. PE is a lovely and tasteful collection of problems, one that has provided countless hours of instruction and fun to many, many people. While the PE problems are outstanding, I do not claim any special virtue for my solutions. But they should not require any special virtue, that is the point. I want you to see functional programming as a simple and natural way to express intent, as one more way to get things done. If these solutions seem routine, then I have done what I set out to do.

The project repository is is available here. If you want a preview, you can jump straight to the Marginalia docs. Enjoy.

Tree reparenting

Chris Houser contributed the very pretty problem 130 to 4clojure. I won’t repeat the problem statement here, just my thoughts on how to approach the problem, and my solution.

The strategy is to decompose a complex task into a sequence of simpler tasks. The complex task is to transform a tree: we are given a tree with root r, and some designated node n. The goal is to rewrite the tree representation so that n is the new root. The further n is from r, the more complex the task. It turns out that the task is fairly simple if n is an immediate descendant of r. So the strategy is this. Find the path (sequence of nodes) from r to n, say it is [r a b c n]. We first rewrite the tree so a is the root. Then rewrite that tree so b is the root, etc. It’s that simple.

In the code I will refer to labels rather than nodes. I think of the trees this way. We have a set L of labels. Trees are constructed by induction, as follows.

  • For any element x in L, [x] is a tree.
  • Any vector whose first element is a label and remaining elements are trees is itself a tree.

We consider only trees wherein all labels are distinct, otherwise the problem has no unique solution. Here’s the code.

(defn get-label [x]
  (when (sequential? x) (first x)))

(defn path-to
  "The path from the root of the tree to the label."
  ([label tree] (path-to [] label tree))
  ([path label tree]
     (let [lbl (get-label tree) path (conj path lbl)]
       (if (= label lbl)
         path
         (mapcat (partial path-to path label)
                 (rest tree))))))

(defn lift-local
  "Rewrite the tree so that label is the root.
   Here label is required to belong to a subtree
   immediately descended from the root."
  [tree label]
  (let [match  #(= label (get-label %))
        subtree     (first (filter match tree))
        but-subtree (remove match tree)]
    ;; append but-subtree to subtree
    (concat subtree (list but-subtree))))

(defn lift
  "Rewrite the tree so that label is the root."
  [label tree]
  (reduce lift-local
          tree
          (rest (path-to label tree))))

Final thoughts: I inductively defined trees in terms of vectors, but the code does not depend on vector specific operations, and should work with trees represented by either vectors or lists. For a very different take on this problem, see Meikel Brandmeyer’s solution using logic programming.

Pretty Adequate Proxy

Summary: how to use Pallet to configure and start an http proxy in the Amazon cloud, and then connect to it via ssh port forwarding.

Suppose you want to use an http proxy; you have several options. One is to use a free proxy. That does not suit me; I like to know what I’m connecting to. Another option is to subscribe to a commercial proxy service, or even a vpn service. I’d like to suggest a middle ground. Fire up your own on-demand proxy in the Amazon cloud. I see several advantages to this approach. You control the proxy, including the OS and software. It’s inexpensive, and it’s fun. Here’s how.

There are four elements you’ll need to get squared away.

  • Your Amazon EC2 account
  • Your ssh keys
  • Your browser network configuration
  • Your ability to execute Clojure code

I’ll make only brief remarks about each; detailed tutorials are readily available on the net. My instructions target linux. I imagine they can easily adapted to run on Macs, very likely on Windows too, with a bit more effort.

The plan is to fire up an Amazon EC2 instance, and to automagically configure it to provide proxy services via Privoxy. So you need to have an Amazon Web Services account. In particular, you’ll need to know your Access Key ID and your Secret Access Key. These can be found by going to your AWS account settings page, then picking Security Credentials. The values you want are on the Access Keys tab.

Once we have the EC2 instance running, we will connect to it via ssh. The setup I describe will expect to find two related keys in your .ssh directory, id_rsa and id_rsa.pub. For simplicity, don’t set a password on the keys, or if you prefer to set a password, also set up an ssh-agent. If per chance you are not familiar with ssh, take this opportunity to become familiar with an enormously useful software tool. There are many tutorials on the net; here’s one you might like.

You will need to configure your browser to use the proxy will set up. Using Firefox, for instance, go to Preferences::Advanced::Network::Connection Settings. Then select Manual Proxy Configuration, use localhost as your http proxy, and port 8118. These instructions assume nothing is already running on 8118. If you are already happen to be running something on that port, the simplest thing to do would be to turn it off for the duration of this experiment. Or you can adapt the instructions to use whatever port you prefer. I like to use the same port on both sides of the ssh tunnel, and Privoxy will be running on 8118 on the remote host.

Assuming your browser, ssh keys, and AWS account are ready, here’s the code we want to compile. It uses Pallet to provision and start an Amazon EC2 node running Privoxy. You can grab the code, and the lein project file, from my Mercurial repository. For a brief intro to Pallet, check out this article.

You’ll need to compile the above, and then run the launch function. Here’s the typical output:

pa-proxy.aws> (launch)
{:middleware #,
 :compute #,
 :blobstore nil, :parameters {:host {:us-east-1/i-970d1df6 nil}},
 :all-nodes ( webserverZONE/us-east-1a.REGION/us-east-1.PROVIDER/ec2 null
	amzn-linux paravirtual null amazon/amzn-ami-2011.02.1.i386-ebs
        RUNNING
	public: 184.73.78.88
        private: 10.196.174.101),
:user #:pallet.utils.User{:username "drc",
:public-key-path "/home/drc/.ssh/id_rsa.pub",
:private-key-path "/home/drc/.ssh/id_rsa",
:passphrase nil, :password nil, :sudo-password nil, :no-sudo nil},
:results {:us-east-1/i-970d1df6 {:after-configure nil, :configure nil, :pre-configure nil}},
:target-nodes (  webserver ZONE/us-east-1a.REGION/us-east-1.PROVIDER/ec2 null
		 amzn-linux paravirtual null amazon/amzn-ami-2011.02.1.i386-ebs
		 RUNNING
		 public: 184.73.78.88  private: 10.196.174.101)}

On my machine and network connection, it took about two minutes for the launch function to return the output shown above, so be patient. Look through the output and find the public IP address returned, 184.73.78.88 in this example. Then open a terminal, and ssh to that address, as follows:

ssh -i ~/.ssh/id_rsa 184.73.78.88 -L 8118/localhost/8118

This will open an ssh tunnel to the proxy, and connect localhost:8118 on your machine to the Privoxy listening port 8118 on the remote machine. Leave the terminal session open. For a more detailed look at ssh port forwarding, try this Redhat Magazine article.

If all went well, your browser should be ready to go. Occasionally I have gotten a stack trace during the launch; simply trying again seems to clear it up. Not really sure what that’s about.

I have not done any performance measurements, but YouTube video streams come across just fine. Not too shabby, considering your traffic is encrypted courtesty of shh, and as an added bonus, Privoxy will clean up quite a few ads.

Final thoughts: try heading over to whatismyip.com to verify that your browser is seen to be coming from the IP address of the EC2 instance. Don’t forget to terminate the EC2 instance once you are done with it, otherwise Amazon will keep charging you for the time. I like to terminate instances from the Amazon Web Console; guess I’m just old school at heart.

A simple parallel computation

The 2 June 2011 issue of The Economist contains an article on parallel programming. The article points out what is obvious to some, mostly because they have learned it the hard way.

You might expect a six-core machine to be six times faster than a machine with a single-core microprocessor. Yet for most tasks it is not.

Indeed. Every once in a while, if you pick the right problem and the right approach, you can get a significant speedup on a multi-core box. I’ll give you a simple example.

The problem is that old chestnut, computing the nth Fibonacci number, for large n. By “large n” I mean n=1,000,000 or so. By then fib(n) has enough digits to fill a book. For example, fib(1,000,000) has 208,988 digits and fib(2,000,000) has 417,975 digits.

To have a basis for comparison, here is a standard approach to computing the nth Fibonacci number.

(defn std-fib
  "A slow but simple way to compute nth Fibonacci number."
  [n]
  (loop [a 0  b 1  k n]
    (if (zero? k)
      a
      (recur b (+ a b) (dec k)))))

The algorithm is familiar, but a couple of points are worth noting. The first is that computing the nth Fibonacci number this way will require n additions. The second is that though this approach is tail recursive, it does not use constant space. The space usage will be linear in n, for the following reason. The number fib(n) grows exponentially with n. The standard ways to represent a number n grow logarithmically with n. The log and the exponential functions more or less cancel, and the space required will grow proportionally to n.

We’ll turn the iterative std-fib into a parallel computation in two steps. The first step is to rethink our approach, and switch to a matrix computation. Then we’ll tweak the matrix approach to make it parallel.

Here’s the quick review of matrix multiplication:

A=\begin{bmatrix}a&b\\c&d\end{bmatrix}
B=\begin{bmatrix}e&f\\g&h\end{bmatrix}
AB=\begin{bmatrix}a&b\\c&d\end{bmatrix}\begin{bmatrix}e&f\\g&h\end{bmatrix}=\begin{bmatrix}ae+bg&af+bh\\ce+dg&cf+dh\end{bmatrix}

Because it is tedious to work with LaTeX in WordPress, as above, I am going to change the notation a bit and write the 2 x 2 matrix A as [a b c d], etc. This simpler notation works well with both WordPress and Clojure.

Here’s the basis of computing Fibonacci numbers with matrices. Consider the matrix

F = [0 1 1 1]  = [fib(0) fib(1) fib(1) fib(2)]

The matrix powers of F have a nice property. For integers n > 0:

Fn+1 = [fib(n) fib(n+1)  fib(n+1) fib(n+2)]

So we’ll compute the nth Fibonacci number by computing Fn+1 and extracting its first entry. At first glance that might seem crazy. Multiplying two matrices will involve several multiplications and several additions, whereas std-fib did only a single addition. How can the proposed matrix approach possibly be faster?

Suppose we want to compute F1000. We will not perform 1000 matrix multiplications. Instead we’ll note that F1000 is the square of F500. Suddenly half of our multiplications are gone. And of course F500 is the square of F250, and so on, recursively.

We’ll compute matrix powers by squaring when we can, and multiplying when we have to.

(defn mat-power
  "2x2 matrix M raised to nth power"
  [M n]
  (cond
   (= 0 n) [1 0 0 1]
   (even? n) (recur (mat-sq M ) (/ n 2))
   :else  (mat-mult M (mat-power M (dec n)))))

The mat-power function is defined in terms of two other functions, mat-mult and mat-sq. Let’s take a look at them.

(defn mat-mult
  "Matrix multiplication for 2x2 matrices, both arguments are powers of the same
symmetric matrix. Note that this version of multiplication is _not_ correct in the
general case. In particular, the product of symmetric matrices need not be symmetric.
This function should be used only to compute a positive integer power of a symmetric
matrix. Such a product is guaranteed to be symmetric."
  [[a b _ d] [e f _ h]]
  (let [[ae bf dh af bh] (map *
                              [a b d a b]
                              [e f h f h])
        [w x y] (map +
                     [ae af bf]
                     [bf bh dh])]
    [w x x y]))

(defn mat-sq
  "Square of a symmetric 2x2 matrix"
  [[a b b c]]
  (let [[aa bb cc x]
        (map *
              [a b c b ]
              [a b c (+ a c) ])

        [w y]
        (map +
              [aa  bb]
              [bb  cc])]
    [w x x y]))

(defn fib
  "Compute the nth Fibonacci number."
  [n]
  (let [F [0 1 1 1]
        M (mat-power F (inc n))]
    (M 0)))

Above I exploit a feature of the problem at hand to reduce the amount of work done. We are interested in computing powers of the symmetric matrix F = [0 1 1 1]. A positive integer power of a symmetric matrix is guaranteed to be symmetric. The two off-diagonal elements must be equal, so instead of computing four entries, I can get away with computing only three, cutting the work to be done by 25% or so.

Let’s see how the matrix approach compares to std-fib when timed on largish values of n. On my machine, I see

fast-fib.fib> (time (do (std-fib 1000000) nil))
"Elapsed time: 44284.767864 msecs"

fast-fib.fib> (time (do (fib 1000000) nil))
"Elapsed time: 3208.876229 msecs"

Down from 44 seconds to 3 seconds; std-fib took 13.8 times as long as fib. Nice. Let’s go a little higher.

fast-fib.fib> (time (do (std-fib 2000000) nil))
"Elapsed time: 168510.795379 msecs"

fast-fib.fib> (time (do (fib 2000000) nil))
"Elapsed time: 12722.213307 msecs"

Again, std-fib took over 13 times as long as fib.

Now let’s see how to use those extra cores. We’ll write parallel versions of our earlier functions, and distinguish them by prefixing the function name with a “p”.

(defn pmat-mult
  "Matrix multiplication for 2x2 matrices, both powers of a single symmetric matrix"
  [[a b _ d] [e f _ h]]
  (let [[ae bf dh af bh] (pmap *
                               [a b d a b]
                               [e f h f h])
        [w x y] (pmap +
                      [ae af bf]
                      [bf bh dh])]
    [w x x y]))

(defn pmat-sq
  "Square of symmetric 2x2 matrix"
  [[a b b c]]
  (let [[aa bb cc x]
        (pmap *
              [a b c b ]
              [a b c (+ a c) ])

        [w y]
        (pmap +
              [aa  bb]
              [bb  cc])]
    [w x x y]))

(defn pmat-power
  "Symmetric 2x2 matrix M raised to nth power"
  [M n]
  (cond
   (= 0 n) [1 0 0 1]
   (even? n) (recur (pmat-sq M ) (/ n 2))
   :else  (pmat-mult M (pmat-power M (dec n)))))

(defn pfib
  "The k-th Fibonacci number, parallel version."
  [k]
  (let [F [0 1 1 1]
        M (pmat-power F (inc k))]
    (M 0)))

Basically, I replaced map with pmap. That was the plan all along, and the reason I wrote the matrix multiplication functions using map. So does it work? Well, I have a four core box. Check it out.

fast-fib.fib> (time (do (fib 1000000) nil))
"Elapsed time: 3184.672283 msecs"

fast-fib.fib> (time (do (pfib 1000000) nil))
"Elapsed time: 1029.386271 msecs"

That’s a ratio of about 3.1. Let’s double n.

fast-fib.fib> (time (do (fib 2000000) nil))
"Elapsed time: 12660.566862 msecs"

fast-fib.fib> (time (do (pfib 2000000) nil))
"Elapsed time: 3617.482009 msecs"

That’s a ratio of 3.5. We see fib taking about three times as long as pfib. Recall that we are computing three numbers. A speedup of three is about all we could hope for. If you want to grab the code and play around with it yourself, you can get it here.

I wrote this code because I wanted an unequivocal example of the four cores on my machine speeding up a computation. An earlier attempt at much the same computation was misconceived. I tried a similar approach, but the devil is in the details. I used the matrix Fibonacci computation, but explicitly computed what binary powers of F would need to be multiplied together, computed them using only squaring, and then used a home-brew parallel reduce operator to multiply the resultant matrices in parallel. This was no faster than fib, and more complicated. I was taken in by a too-clever scheme which focused on making the wrong thing parallel. Multiplying whole matrices in parallel did not work nearly so well as the simpler approach I showed you here.

Final thought: I raced through the explanation of the matrix approach to calculating Fibonacci numbers. The method is well known, and there are detailed explanations available online. I like one I ran across not too long ago, on Code Overflow.

map, mapp, and mapc

In a 1988 paper called Algebraic Identities for Program Calculation, Richard Bird wrote:

Probably the most useful law about map is the fact that it distributes over functional composition: (map f) . (map g) = map (f . g)

Bird’s paper predates Haskell, and instead uses a language called Miranda, but Haskell later adopted very similar notation:

GHCi, version 6.12.1: http://www.haskell.org/ghc/  :? for help
Prelude> let f x = x * x
Prelude> let g x = x + 1

Prelude> ((map f) . (map g)) [1 .. 5]
[4,9,16,25,36]

Prelude> map (f.g) [1 .. 5]
[4,9,16,25,36]

I am a sucker for nice notation, and that is some very nice notation. It got me thinking about how I might write the same thing in Clojure. Here is my first cut at a literal translation:

user> ((comp (partial map sq) (partial map inc)) (range 1 6))
(4 9 16 25 36)

user> (map (comp sq inc) (range 1 6))
(4 9 16 25 36)

The Clojure code looks a little noisy by comparison, mostly due to the explicit use of partial. I came up with a couple of variations on map that clean up the presentation. The first I call mapp:

(defn mapp
  ([f] (partial map f))
  ([f x & args]
     (apply map (partial f x)
            args )))

Here are some examples of mapp in action:

;; Using regular old map
user> ((comp (partial map sq) (partial map inc)) (range 1 6))
(4 9 16 25 36)

;; We can clean that up a bit with mapp
user> ((comp (mapp sq) (mapp inc)) (range 1 6))
(4 9 16 25 36)

;; Or you can do stuff like this
user> (mapp * 100 (range 6))
(0 100 200 300 400 500)

user> (mapp + 1/2 (range 6))
(1/2 3/2 5/2 7/2 9/2 11/2)

My other variation on map is called mapc.

(defn mapc [& args]
  (let [[fns xs] (partition-by fn? args)
        g (apply comp fns)]
    (if (empty? xs)
      (partial map g)
      (apply map g xs ))))

Here are some examples of mapc in action.

;; Map the (implicit) composition of two functions
user> (mapc sq inc (range 1 6))
(4 9 16 25 36)

;; We can compose more than two functions
user> (mapc inc sq inc (range 1 6))
(5 10 17 26 37)

;; Or use mapc like plain old map
user> (mapc sq (range 1 6))
(1 4 9 16 25)

;; Or by providing only functional args, produce a function
user> ((mapc sq inc) (range 1 6))
(4 9 16 25 36)

To wrap this up, note that I wanted to come close to something like

(map f) . (map g) = map (f . g)

The best I could do was

(comp (mapp f) (mapp g))  =  (mapc f g) 

That’s not half bad. I rather like mapp and mapc. But I genuinely wonder whether anyone else will. Play around with mapp and mapc, let me know what you think.

Update: In the comments, MarkusQ pointed out that (comp (mapp f) (mapp g)) = (mapp (comp f g)). In particular,

user> ((comp (mapp sq) (mapp inc)) (range 1 6))
(4 9 16 25 36)

user> ((mapp (comp sq inc)) (range 1 6))
(4 9 16 25 36)

MarkusQ’s equation preserves symmetry by using mapp on both side of the equals sign. I think this is much prettier than the version I came up with. Keats observed that “Beauty is truth, truth beauty…”. The version Markus sent in makes me believe that mapp may well be a worthwhile abstraction.

I’m smiling today

Whenever I start a Leiningen project, I always want to add the same couple of dev-dependencies to the project file: swank-clojure and Marginalia. Being the lazy sort, I got to wondering whether there was some way to configure lein to automatically add user selected dev-dependencise as part of the new task. I googled for an answer and came up empty, so I asked about it on the Clojure google group. No luck there either.

Being the lazy and stubborn sort, I had a look at the Leiningen source. It turned out to be relatively straight-forward to do what I wanted done, and more. I submitted a pull request, and got it accepted. I love open source.

Monty Hall problem

There is currently an active discussion of the Monty Hall problem on the Clojure discussion group. The discussion centers on the simulation of the problem; here I want to look at it from first principles. The problem is actually an easy one to reason about when looked at from the right perspective.

Here is how the Monty Hall problem was stated in the discussion mentioned above.

Suppose you’re on a game show and you’re given the choice of three doors [and will win what is behind the chosen door]. Behind one door is a car; behind the others, goats [unwanted booby prizes]. The car and the goats were placed randomly behind the doors before the show. The rules of the game show are as follows: After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one [uniformly] at random. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you “Do you want to switch to Door Number 2?” Is it to your advantage to change your choice?

Let’s generalize the problem. You are presented with N doors, behind one is the car, behind the other N-1 doors there are goats. Monty knows what is behind each door. You choose a door, then Monty opens all but two of the doors, yours and one other. Behind the N-2 open doors are goats. Two doors remain closed. Should you switch from your original choice?

Not to ruin the suspense, but for N > 2 you should switch. Let’s see why.

We need to consider the probabilities of several events; here is some notation to describe the relevant events.

  • C: the event that your original choice of door hides the car.
  • C: the event that your original choice of door does not hide the car.
  • M: the event that Monty opens N-2 doors, none reveal the car.
  • MC: both M and C occur.
  • MC: both M and C occur.

By the time you are asked to reconsider your choice, event M has happened, and one but not both of C and C has happened. Another way to put it is that MC xor MC has happened. These two events are mutually exclusive, and one or the other occurred, but you don’t know which. So you need to decide which was more probable.

The choice before you is to decide which is larger: P(MC), the probability of MC, or P(MC), the probability of MC. If P(MC) is larger, you should stick with your orginal choice. If P(MC) is larger, you should switch. If the two are equal, it does not matter whether you switch.

The first key observation: P(M) = 1. No matter what door you chose, Monty always can and always will open all doors but yours and one other, and not reveal the car. He can easily do this because he knows what is behind every door.

The next key observation concerns the notion of probabilistically independent events. Events A and B are independent iff P(AB) = P(A)*P(B). This is a special relationship; not all events are independent. But we have here a special case. An event of probability 1 is independent of any other event.

In particular, since P(M)=1, then M is independent of C, hence P(MC)=P(M)*P(C)=P(C). Similarly, P(MC)=P(M)*P(C)=P(C).

This reduces the choice before us to deciding which is larger, P(C) or P(C). But this is trivial: P(C) is 1/N, and P(C) is (N-1)/N.

An interesting special case of the game is for N=2. There are only two doors, Monty opens no doors, and it makes no difference whether or not you switch doors. For N>2 you should switch.

If you are not convinced that it pays to switch, I have a proposition for you. Let’s play the game a few times with a deck of cards, say using 10 red cards as goats, one black card as the car (N=11). You play the role of Monty, I’ll be your opponent. I’ll consistently play the always-switch strategy. Play is for a dollar a round (more if you prefer). Monty pays if the opponent gets the car, the opponent pays otherwise. I’ll be happy to play for long as you like.

The transpose function

I am going to discuss a function I think belongs in the Clojure core language. The function is called transpose. It is defined as follows.

(defn transpose [xs]
  (apply map vector xs))

Here is what it does:

user> (def m [ ['a 'b 'c 'd] [1 2 3 4] ])
#'user/m

user> m
[[a b c d] [1 2 3 4]]

user> (transpose m)
([a 1] [b 2]  [d 4])

user> (transpose (transpose m))
([a b c d] [1 2 3 4])

Frequently we are presented with data physically organized as rows or records. These rows may be semantically meaningful, but even so, we often want to consider the same data as columns. The transpose functions allows us to easily move between the row and column views of the data. Here’s a typical example.

Suppose we took measurements of some test subjects. For each subject we record height in inches, weight in pounds, age in years. The data looks like this:

user> (def data [ [60.0 180.1 22] [62.0 197.4 19.1] [58.8 166.6 29.1] [59 174 31] ]) 

It is typical to want to compute the sample means for the data. No problem:

user> (map mean (transpose data))
(59.95 179.525 25.3)

Here's another use case. We have several functions f,g,h etc. We want a way to apply all the functions to the same argument x, and return the functions in the order corresponding to (sort (f x) (g x) ...). The problem is a bit contrived, but will serve to illustrate what I think of as the TST pattern: transpose, sort, transpose. Here's the code.

(defn f [x] x) ;; set up test functions
(defn g [x] 3)
(defn h [x] (* x x))
(defn i [x] (* 2 (- x)))

(defn vals [funcs x]
  (for [f funcs] (f x)))

user> (vals [f g h i] 13)
(13 3 169 -26)

With that machinery in place, here's the code showing the transpose-sort-transpose pattern.

(defn fsort [funcs x]
  (let [v (vals funcs x)]
    (->> [v funcs]          ;;line A
         (transpose)
         (sort-by first)
         (transpose)
         (second))))

This will return the functions in the desired order. Here's why. Look at the [v funcs] pair in line A. It looks like

[ [(f x) (g x) (h x) (i x)]  [f g h i] ]

Running that through the first transpose results in

[  [(f x) f ] [(g x) g] [(h x) h] [(i x) i]  ]

Then that is sorted on the first coordinate, reordering it, say to

[  [(g x) g ] [(i x) i] [(h x) h] [(f x) f]  ]

Now the functions are in the order we want. The second transpose decouples the functions and values, resulting in

[ [(g x) (i x) (h x) (f x)]  [g i h f] ]

Running this result through second leaves us with just the functions in the desired order. If you are of a mind to test this, here's one way

(defn in-order? [funcs x]
  (apply <= (vals (fsort funcs x) x)))

user> (every? true? (map (partial in-order? [f g h i]) (range 50000)))
true

I have found the transpose-sort-transpose pattern pops up with surprising regularity. But a pattern pops up in part because we have reified it by giving it a name, and so can recognize it. Giving the transpose function a name makes it much easier to see uses for the TST pattern.

The transpose function is not something I made up. It has a long tradition in linear algebra, where it is called transpose. I hope the transpose function can make the jump into Clojure core. In the meantime, I'll just keep its definition loaded as a yasnippit shortcut.

Synergy, ftw

These are some notes on running Synergy over an ssh tunnel.

The problem: I use two computers at work. The one named Beavis runs Ubuntu, the other, named d73649, runs Win7. Each has its own monitor, mouse, and keyboard, but I prefer to use a single mouse and keyboard as much as possible. Synergy is a sweet piece of free and open software designed for just that purpose. With Synergy running, I can use the mouse to drag the cursor from one monitor to the other. The keyboard addresses the machine whose monitor the cursor is on, and I can copy/paste from one machine to the other.

Here’s the setup. I run the Synergy server, synergys, on Beavis, and the client, synergyc, on d73649. The server is configured via a single config file, ~/.synergy.conf. Mine looks like this:

section: screens
   beavis:
   d73649:
end

section: links
    beavis:
           right = d73649
    d73649:
           left = beavis
end

section: aliases
    d73649:
          d73649.myjob.com
end

Basically I am identifying the allowed client(s), and specifying that the monitor for Beavis is to the left of the monitor for d73649. The server is started by running the synergys command with no options. It runs in the background and listens for client requests.

The drill is to first start the server, then the client. I like to tunnel the Synergy traffic through ssh, to protect it from snooping. I do by starting the client with the following script.

#!/usr/bin/sh
## Connect windows box running synergy client to synergy server listening on port 24800.
## Windows machine has cygwin installed, and we are using the cygwin ssh client.
## Connection is tunneled through ssh to prevent snooping of keyboard traffic.

#------- FQHN of machine running the synergy server
server=beavis.myjob.com

#------- Location of syergy client on local box
#------- Note use of cygwin paths
client=/cygdrive/c/programs/synergy/synergyc.exe

#------- Either the ssh key should have no password set, or there should be
#------- an ssh agent configured to provide the password at execution time.
key=~/.ssh/frd_rsa

ssh -i ${key} -f -N -L localhost:24800:${server}:24800 ${server} && ${client} localhost

I leave the connection running for days at a time. Works like a champ.

Other thoughts: Synergy works with Macs too. There are various gui's for configuration and running the client, but I have not tried them. You'll still need to have a mouse and keyboard on both machines, for dealing with reboots and times when the client session is locked. This is great software. It fills a specific need, and does so quite well.

Sow the wind, reap the whirlwind

At the most recent meeting of TriClojure, I had the pleasure of chatting with Michael Fogus, one of the authors of The Joy of Clojure. I mentioned that I had done some Mathematica (Mma) programming, and Michael asked me about a couple of Mma constructs called Sow and Reap. Sow and Reap are always used in tandem, and together form a powerful debugging tool. I’ll try to illustrate the what they do with some simple examples.

By itself, Sow behaves much like the identity function:

In[1]:= 3 + Sow[4]
Out[1]= 7

To make Sow useful, we have to enclose it inside a call to Reap:

In[2]:= Reap[3 + Sow[4]]
Out[2]= {7, {{4}}}

Disregarding all the nesting for a moment, notice we got back the result of the computation, 7, and the value of the expression wrapped in a Sow call, 4. Together Sow and Reap let you easily examine intermediate results inside of computations. Let’s look at a more complicated example.

First we’ll define a couple of zero argument random functions; one returns an even integer, the other an odd integer.

randEven[] := 2 * Random[Integer, {1, 5}]
randOdd[] := randEven[] - 1

Next we define a function of one argument which uses both of the functions above.

f[x_] := x + randEven[] + randOdd[] + randEven[]

Evaluating f[2] will return a random integer. What if we wanted the option to know what random intermediate values were used to compute the final output of f[2]? We can use Sow and Reap to instrument f in a way that does not disturb its normal behavior, but allows us to look inside a call to f by simply wrapping that call in a Reap.

Here’s the instrumented version of f:

f[x_] := x + Sow[randEven[]] + Sow[randOdd[]] + Sow[randEven[]]

The revised version of f behaves exactly like the original version: it returns a random integer. But if we want to look inside a call to f, we can wrap it it a Reap:

In[4]:= Reap[f[2]]
Out[4]= {15, {{2, 5, 6}}}

We see the final value of the call, 15, and the three intermediate results, {2,5,6}. But why does the Reap output have the double nesting {{2, 5, 6}}? It is because we have the option to decorate our calls to Sow with tags of our choosing, and Reap will collect the values in separate buckets for us.

Here’s the idea. Let’s use tags to separate the odds and evens; the tags can be arbitrary.

f[x_] := x + Sow[randEven[], foo] + Sow[randOdd[], bar] + Sow[randEven[], foo]

Now a call to Reap shows us the odds and evens in separate bins as it were:

In[6]:= Reap[f[2]]
Out[6]= {15, {{4, 2}, {7}}}

The instance of Reap used to enclose our Sow calls need not immediately enclose:


In[9]:= Reap[Min[0, f[2]]]
Out[9]= {0, {{2, 10}, {5}}}

My examples are contrived, but I think they illustrate the idea. A bit of thought might just make you wish you had this facility available in your favorite language. Reap and Sow can be just the thing for getting insight into what is going on inside a computation.

And I have to give mad props to whomever picked such evocative names as Sow and Reap. I am reminded of Hosea 8: “They sow the wind, and reap the whirlwind”. Pure genius.