Negative space in operating systems

Unix advocates often say Unix is great because it has all these powerful tools. And yet practically every Unix tool has been ported to Windows. So why not just run Unix tools on Windows so that you have access to both tool sets? Sounds reasonable, but hardly anyone does that. People either use Unix tools on Unix or Windows tools on Windows.

Part of the reason is compatibility. Not binary compatibility, but cultural compatibility. There’s a mental tax for shifting modes of thinking as you switch tools.

I think the reason why few people use Unix tools on Windows is a sort of negative space. Artists use the term negative space to discuss the importance of what is not in a work of art, such as the white space around a figure or the silence framing a melody.

Similarly, part of what makes an operating system culture is what is not there. You don’t have to worry about what’s not there. And not worrying about something frees up brain capacity to think about something else. Having too many options can be paralyzing. I think that even though people say they like Unix for what is there, they actually value what is not there.

Partial function application in Python

My previous post showed how it is possible to do partial function application in C++ by using function objects. Here I’ll show how much simpler this can be done in Python.

As before, we want to evaluate a function of one variable and three parameters: f(x; a, b, c) = 1000a + 100b + 10c + x. Here’s an example how we could do this in Python using the functools module.

from functools import partial

def f(a, b, c, x):
    return 1000*a + 100*b + 10*c + x

g = partial(f, 3, 1, 4)

print g(5)

The code will print 3145.

The function f above is so simple that it may be hard to imagine why you would want to do such a thing. The earlier post gives a more realistic application, using partial function application in numerical integration and root-finding.

Functional programming in C++ with function objects

Here’s something I do all the time. I have a function of one variable and several parameters. I implement it as a function object in C++ so I can pass it on to code that does something with functions of one variable, such as integration or optimization. I’ll give a trivial example and then show the most recent real problem I’ve worked on.

Say I have a function f(x; a, b, c) = 1000a + 100b + 10c + x. In a sense this is simply a function of four variables. But the connotation of using a semicolon rather than a comma after the x is that I think of x as being a variable and I think of a, b, and c as parameters. So f is a function of one variable that depends on three constants. (A “parameter” is a “constant” that can change!)

I create a C++ function object with two methods. One method is a constructor that takes the function parameters as arguments and saves them to member variables. The other method is an overload of the parenthesis method. That’s what makes the class a function object. By overloading the parenthesis method, I can call an instance of the class as if it were a function. Here’s some code.

class FunctionObject
{
public:
	FunctionObject(double a, double b, double c)
	{
		m_a = a;
		m_b = b;
		m_c = c;
	}

	double operator()(double x) const
	{
		return 1000*m_a + 100*m_b + 10*m_c + x;
	}

private:
	double m_a;
	double m_b;
	double m_c;
};

So maybe I instantiate an instance of this function object and pass it to a function that finds the maximum value over an interval [a, b]. The code might look like this.

FunctionObject f(3, 1, 4);
double maximum = Maximize(f, a, b);

Here’s a more realistic example. A few days ago I needed to solve this problem. Given user input parameters λ, σ, n, and ξ, find b such that the following holds.

\int_0^1 \frac{1}{\sqrt{2}\nu} \Phi\left(\frac{\lambda \sqrt{2\nu n}}{\sqrt{\sigma^2(1 - 2\nu) + bn}}\right) , dnu = xi

The function Φ above is the CDF of a standard normal random variable, defined here.

To solve this problem, I wrote a function object to evaluate the left side of the equation above. It takes λ, σ, and n as constructor arguments and takes b as an argument to operator(). Then I passed the function object to a root-finding method to solve for the value of b that makes the function value equal ξ. But my function is defined in terms of an integral, so I needed to write another function object first that returns the integrand. Then I pass that function object to this numerical integration routine.  So I had to write two function objects to solve this problem.

There are several advantages to function objects over functions. For example, I would typically do parameter validation in the constructor. Quite often I also do some expensive calculations in the constructor and cache the results so that each call to operator() is then more efficient. Maybe I want to keep track of how often the function is called, so I put in some sort of odometer method that increments a counter with each call.

Unfortunately there’s a fair amount of code to write in order to implement even the simplest function. This effort hardly matters in production code; so many other things take more time. But it is annoying when doing some quick exploration. The next post shows how this can be done much easier in Python. The Python approach would be much easier for small problems, but it doesn’t have the advantages mentioned above such as caching expensive calculations in a constructor.

The probability that Shakespeare wrote a play

Some people object to asking about the probability that Shakespeare wrote this or that play. One objection is that someone has already written the play, either Shakespeare or someone else. If Shakespeare wrote it, then the probability is one that he did. Otherwise the probability is zero. By this reasoning, no one can make probability statements about anything that has already happened. Another objection is that probability only applies to random processes. We cannot apply probability to questions about document authorship because documents are not random.

I just ran across a blog post by Ted Dunning that weighs in on this question. He writes

The statement “It cannot be probability …” is essentially a tautology. It should read, “We cannot use the word probability to describe our state of knowledge because we have implicitly accepted the assumption that probability cannot be used to describe our state of knowledge”.

He goes on to explain that if we think about statements of knowledge in terms of probabilities, we get a consistent system, so we might as well reason as if it’s OK to use probability theory.

The uncertainty about the authorship of the play does not exist in history — an omniscient historian would know who wrote it. Nor does it exist in nature — the play was not created by a random process. The uncertainty is in our heads. We don’t know who wrote it. But if we use numbers to represent our uncertainty, and we agree to certain common-sense axioms about how this should be done, we inevitably get probability theory.

As E. T. Jaynes once put it, “probabilities do not describe reality — only our information about reality.”

Picking a color scheme

The other day Nils gave an interesting answer to a question on StackOverflow regarding color theory. 

NEVER ever use pure colors. … If you have no idea what color to start with, get a classic masterpiece of painting from the net. Blur it a bit and then pick some nice colors from it. If you use some common sense it’s hard not to end with pleasant colors this way.

He gave the example of extracting this color scheme

from this painting.

Monet painting lily pads

The uncanny valley of UI design

The uncanny valley is the space between being attractive and being disturbing for something non-human but human-like.

man dog

I mentioned this phenomena back in August when I pointed to a post by Seth Godin on the subject. That’s where the image above comes from.

Now Jeff Atwood has written a post applying the idea of the uncanny valley to web applications that act so similar to desktop applications that they raise expectations. Jeff suggests that users might appreciate browser-based software behaving a little more like desktop software. But when the software acts 99% like desktop software, the missing 1% becomes more irritating.

I had a similar experience when I tried some of the Linux desktops around 2000. The first Linux desktops worked very much like previous Unix desktops. Then they started to look and feel more like Windows. They were just enough like Windows that they raised expectations that were soon dashed. But then instead of continuing through an uncanny valley of behaving more and more like Windows, new Linux desktops such as Ubuntu have taken a turn and have developed their own design.

Why is TeX so popular in Germany?

A lot of good (La)TeX resources come from Germany. I assume from the amount of development and support activity, there are probably a lot of users as well. Does anyone know why TeX is apparently so strong in Germany? Is there something about the German language that TeX supports particularly well?

Faint praise for Expression Web

I really like Expression Web, when it doesn’t crash. It generates standard-compliant XHTML, it’s pleasant to use, etc. But I’ve had it crash many times. It crashes when I have too many files open, or when I edit too big a file for too long.

I need to find something better, but I haven’t taken the time to evaluate other HTML editing environments. I’d like to keep using it if Microsoft would fix the crashes. They have posted an update, but the description implies it doesn’t fix the problems I’ve seen.