Saturday, December 22, 2007

Volta, Continuation-passing style

Over a year ago, I pointed to a particular pattern in C#, using delegates with asynchronous methods, that used continuation-passing style (CPS) to make writing scalable IO-heavy code easier:

A lot of work? Yes, but better than people who write business code for a living having to work in a nest of hand-written continuations just to get scalability.

If the folks advising asynchronous code are serious about recommending this approach to scalability, then the enabling tools need to be available. It's conceivable that the CLR could do this automatically, with some kind of [AutoAsync] attribute, along with a couple of utility methods to access the generated Begin/End pair via reflection or whatever. That would keep the C# language clean while leaving the CLR open to a lazy implementation approach (using ThreadPool threads), but also with the power to create the transformations discussed above.

Now it looks like some of the folks over at MS are having similar ideas, in their Volta preview. It's not quite the same, you have to write your async method in a particular way, but with the automatic transformation of the callsite into the appropriate format, it's a good step forward:

Asynchronous Calls

Hiding network latency requires asynchronous calls. In the first technology preview, Volta allows programmers to add asynchronous versions of methods on tier boundaries.

To make a method asynchronous, define the CPS-equivalent method signature and annotate it with the Async attribute. Volta will generate the body and modify the call-sites accordingly.

    [Async]
    public static void F(string s, Action k);

If the programmer invokes an asynchronous method F, then Volta will launch the invocation on another thread and invoke the continuation upon completion of the call to F.

I'm not entirely delighted with some of the ideology behind Volta - I don't think hiding the network's existence in and of itself is necessarily a good thing - but making the right kind of code easier to write is definitely a step in the right direction.

Monday, December 10, 2007

Cygwin

It's been a long time since I last posted. I've been working on the Delphi compiler all the while, but with uninteresting bug fixes (usually too boring to talk about), learning more about the code base (not general enough to talk about) and working on new features (not public enough to talk about), it's been rare enough that I found something interesting enough to talk about. So, I've decided to take a different tack.

I've had the "opportunity" to set up a number of PCs and laptops recently for my personal use, general and development work. Quite a bit of customization is necessary before I'm comfortable with a system. Apart from the usual handful of utilities (Firefox with extensions, Winzip, Winamp, Forte Agent), there's one other thing that I can't really live without - Cygwin. The bash shell running in an rxvt terminal window is my main interface with Windows.

There's one big reason for this. The shell is very programmable, so any time I need to do work of a repetitive nature, I can write a script. Whenever I find myself doing similar things, I can refactor my work and write a new utility script containing the commonality. My life would be a lot harder without Cygwin. Sometimes I wonder why it isn't more popular than it is; but then, the default Cygwin setup isn't very appealing. I remember when I first installed it, and got to use the usual Unix utilities I was familiar with from Linux, only this time in Windows, but I was still using the crippled cmd.exe shell from NT, running in the crappy console that Windows provides by default. I'm going to write a series of posts on how I beautify my Cygwin environment.

Installation

The first step is to install Cygwin. I do this in a four-step process:

  1. Download setup.exe from cygwin.com.
  2. Run setup.exe, and tell it to download (but not install) everything to a local directory. I choose c:\cygwin\opt\var\cygwin-cache. I then rename the ugly directory name it generates (based on the mirror you chose) to something briefer.
  3. I then run setup.exe again (setup.exe normally resides in c:\cygwin\opt\var\cygwin-cache on my system), and perform an install, selecting those packages that I know I want and need. Those include:
    • All the programming languages, from clisp and SWI-Prolog through byacc and cocom to gcc and nasm.
    • The text editor joe and the rxvt terminal.
    • ImageMagick, Ghostscript, TeX - stuff I seldom use, but like to have available.
  4. Finally, I add the main binaries directory (c:\cygwin\bin by default) to my system path.

Actually, I'm lying. I don't normally use setup.exe to download the cygwin-cache directory, since I already have one. I actually use wget to download the cygwin packages directly from a mirror on a monthly basis, but that presents a bootstrapping problem: one wouldn't normally have wget without already having installed cygwin.

In any case, once I've gotten Cygwin installed, it's time for me to set up my home directory (the ~ directory in Unix parlance; defaults to c:\cygwin\home\<username>). This is created the first time you run a Cygwin login shell, such as from the shortcut the setup.exe program creates (or by running bash --login). All the stuff up until now is pretty regular Cygwin orthodoxy: people usually stumble along this far all on their own. I know I did the first time, but I found bash running in NT's command window pretty unpleasant to use. Here's where I make Cygwin usable, at least to me.

Beautifying

The main objective is to get bash running inside rxvt. This can be done pretty trivially:
  • Create a shortcut to c:\cygwin\bin\rxvt.exe (assuming one chose the default install directory)
  • Modify the shortcut and change the target so that it has a few extra arguments: "c:\cygwin\bin\rxvt.exe -e bash --login".
That tells rxvt to use bash rather than sh as the shell, and tells bash to run ~/.bash_profile (amongst others) as its startup script, rather than ~/.bashrc.

However, the default shell is still pretty unappealing: an ugly white window with black text. That's why I use some customizations. Rxvt reads in .Xdefaults from your home directory when it starts up, even though it's a Windows program, not an X one. .Xdefaults uses a pretty simple line-oriented file format. '!' starts a comment, which extends to the end of the line. Here are some lines I add to make things more suited to my preferences:

Rxvt*geometry:120x43

Rxvt*background:rgb:00/00/20
Rxvt*foreground:rgb:C0/C0/C0

Rxvt*color1:red
Rxvt*color2:rgb:72/A0/32
Rxvt*color4:skyblue

Rxvt*color3:yellow
Rxvt*color5:magenta
Rxvt*color6:rgb:20/C0/A0
Rxvt*color7:rgb:C0/C0/C0

Rxvt*color9:red
Rxvt*color10:rgb:72/A0/32
Rxvt*color12:skyblue

Rxvt*color11:yellow
Rxvt*color13:magenta
Rxvt*color14:rgb:20/C0/A0
Rxvt*color15:rgb:C0/C0/C0

Rxvt*colorBD:rgb:C0/C0/C0
This remaps the 16 console colours a little, inverting the colour scheme. I get the names for these variables (called resources in X parlance) from the rxvt manual page, available from "man rxvt". Here are some other relevant lines in my .Xdefaults:
Rxvt*jumpScroll:True

! I use Dina-9, from the font Dina, which I installed separately
!Rxvt*font:-*-lucidatypewriter-medium-*-*-*-12-*-*-*-*-*-*-*
Rxvt*font:Dina-9

! I have an ego
Rxvt*title:Barry's Bash

! Scrollbar on the left looks odd.
Rxvt*scrollBar_right:True

! In case I forget something; this is somewhat better than cmd.exe's usual limit
Rxvt*saveLines:30000

Rxvt*termName:rxvt

! This is the number of pixels between text rows; aesthetic issue, depends on font and size
Rxvt*lineSpace:1
After having done this, I have something I can live with.