Tuesday, January 29, 2008

Programming Languages are Languages too

One of the reasons that people keep inventing new programming languages is that humans are good at using language and computers are not. So was we improve computers and add more complexity, programmers endeavor to make using these new features simpler and less painful. As a result, computer languages are moving in a general direction towards more natural human language. There will likely always be differences, but programming languages and human languages are strikingly similar if you understand some of the widely used syntax.

Here's an example. When you see something like this
z = x * y;
print(z);
it means that you want the computer to "store the value of x times y in the varibale z, then display z on the screen." As you can see, some programming syntax is borrowed from math. This example includes arithmetic and a function. Functions can also be though of as verbs, with variables as the nouns. In object oriented programming, variables can be nouns which are capable of performing actions. If you had a digital carrier pigeon, and you wanted to tell it to carry a letter to your grandmother's house, you might say something like:
myPidgeon.payload = myLetter;
myPideon.flyTo(grandma.house);
In human language, there are always multiple ways to say the same thing, and the same applies in programming. The programmer might just as easily design the program to give grandma the letter like this:
myLetter.setRecipient(grandma);
myPideon.deliver(myLetter);
Now for some fun. What do the following code snippets mean?
  1. if (jack.getWorkPercent() == 100.0 &&
    jack.getPlayPercent() == 0.0) {
    jack.dullBoyFlag = true;
    }
  2. Pie aPie = new Pie();
    Song aSong = new Song(sixpence);
    aSong.sing();
    fill(pocket, rye);
    aPie.add(new Blackbird()[24]);
  3. Mouse mice[3];
    for (i in range(3)) {
    mice[i] = new BlindMouse();
    }
    observe(run(mice));
  4. party = new Party(jack, jill);
    party.setTarget(water);
    party.equip(pail);
    party.ascend(hill);

Wednesday, January 23, 2008

A spoiled programmer

I've been writing quite a bit of Python code recently and I've become a bit spoiled. It's easy in Python to define new classes on the fly, create new functions, pass them here and there, and return arbitrary collections from a method. C will always have a special place in my heart (I think everyone's first language does), but I often think of ways I could make it a bit easier to do certain things like have functions that return functions or have a function return multiple values.

To explain by way of example, it would be fun to do something like this:
/* A function that returns multiple values */
int, char, int myFunction(int a, int b, int c, char d) {...}

...
/* Invoke the function and store the results */
int x, y;
char c;
{x, y, c} = myFunction(5, 6, 7, 'Z');

The above is a fairly Pythonic way of doing things, and it seems like it should be possible in C. The first way I thought of is using structs. I like to think of a struct as the precursor to a class. It allows the arbitrary grouping of variables into a single collection where they can be referred to by name. (In a couple of earlier posts, I showed how you could use structs to simulate classes in C.)

If I define a struct for each one of my multi-variable-returning functions, I can create functions which effectively return multiple values instead of just one. Yes, technically I am returning one value, the struct, but you know what I meant :-) Namely, if you look at the program's stack, there is probably no perceptible difference between returning a struct and returning multiple variables.
/* Create a 2 member struct to hold the return value */
struct myFuncReturn {
int first;
char second;
};

/* A function that returns an int and a char */
struct myFuncReturn myFunc(int a, int b, int c, char d) {
struct myFuncReturn to_return;
to_return.first = (a+b)*c;
to_return.second = d;
return to_return;
}

int main() {
struct myFuncReturn pattern;
pattern = myFunc(2, 3, 4, 'Z');
printf("Pattern: %i, %c\n", pattern.first, pattern.second);
}
This works ok, but I would like to avoid having to create a new struct for each one of my functions. It might be easier if I didn't have to worry about types at all, so the natural choice is to have the function return a type-less void pointer (void*). The calling code would then be responsible for interpreting the function's return struct correctly. If I want to return a new anonymous struct from a function, it might look something like this:
void* myFunc(int a, int b, int c, char d);
If I use the above, I'll need to allocate memory for the struct and return it's address. This is a bit of a bother as well, because now I need to worry about cleaning up that memory later. Instead of having the function allocate a new structure to return, why not pass in a structure and have the function modify it? The code I would need to write would be more aesthetically pleasing (in my opinion) for both the function definition and the calling code which invokes it, and it might even be more efficient.

If I pass in a pointer to the result struct as the first parameter to the function, my program could look like this.
/* Function definition, the out parameter is the return value */
void myFunc(void* out, int a, int b, int c, char d) {
((struct{int first; char second;}*)out)->first = (a+b)*c;
((struct{int first; char second;}*)out)->second = d;
}

int main() {
struct{int first; char second;} pattern;
myFunc(&pattern, 2, 3, 4, 'Z');
printf("Pattern: %i, %c\n", pattern.first, pattern.second);
}
Look ma, no type declarations! Now you might say that writing out the entire struct definition each time is a bit unpleasant, but you could always define a struct and use it instead. I wanted to show that you don't really need to declare a type for each function, which could create a bit of a mess if you start using multi-return functions everywhere. With the above pattern, you could also start to play some interesting games by having functions that actually return different structs in different situations (provided the out pointer's reserved space is large enough for the data you want to send back). If I've lost you by now, I do apologize.

For added effect, note that the anonymous structs don't need to match, you just need to make sure that the shape of the structure is the same so that you don't overwrite data. I could have written myFunc like this:
void myFunc(void* out, int a, int b, int c, char d) {
((struct{int first;}*)out)->first = (a+b)*c;
((struct{int x; char second;}*)out)->second = d;
}
Or if you want to go even further, like this:
void myFunc(void* out, int a, int b, int c, char d) {
*((int*)out) = (a+b)*c;
((struct{int x; char second;}*)out)->second = d;
}
Ah, the joys of programming. It's little games like this that make programming lots of fun. It's like working on a big wide open puzzle that you get to build yourself. No wonder I'm spoiled.

Monday, January 14, 2008

Twitter

If you've never tried Twitter, it might just be worth your while. I've been using it for a few months now and I'm quite pleased. As much as I try to make frequent blog updates, writing an entire entry sometimes feel like a large task. In contrast, twitter imposes a strict 140 character limit. This limit is both challenging and freeing in some ways: How much can you pack into a sentence or two? In addition to providing a place to share small updates, Twitter introduces a social aspect as well. By using @username notation, you can let everyone know your post was directed to a specific person so that they have a window into the conversation.

If you are familiar with Facebook, using Twitter is a bit like having a website made of just your profile status and your wall. These are my two favorite features of Facebook, so perhaps this is why I enjoy Twitter. The main difference is that you never post on someone else's wall, your posts show up on their wall if they choose to "follow" you (subscribe to your updates). I've never really used my phone to twitter (yes twitter is also a verb) or receive updates, but supporting posts from multiple platforms is a big selling point for some users.

My Twitter page is here and I also include a feed viewer gadget here on my blog to display my last few Twitter posts. If you have an account post it below!

Sunday, January 06, 2008

Trying out the XO Laptop Operating System

In a recent post I mentioned that I had ordered an XO Laptop from the One Laptop Per Child program. It is still on order but being the slightly impatient person that I am I decided to see if I could test drive the software on the laptop before it arrives. It is based on Linux after all which usually means the software is freely available somewhere on the Internet.

Taking the XO for a spin turned out to be pretty easy and I have been able to add all of the applications I've wanted so far. I mentioned in my last post about the XO that I wanted to use it for programming and web browsing so I had a few requirements in mind. The laptop comes preinstalled with a custom web browser and Python but I often like to program in C and C++ so I wanted to install gcc. The web browser has a few wrinkles too, in the development build I tested I wasn't able to get some flash plugins to load (could be the version of flash or the fact that the XO version I downloaded wasn't a production release). The browser is tabless and it is a bit difficult (though not impossible) to figure out where downloaded files are stored. In short it wasn't quite was I've grown accustomed to, so I thought I would try installing Firefox. He's my step by step instructions for trying out the XO Laptop virtually and customizing it.

I began with the XO's wiki and found out that there are instructions for emulating the XO and VMWare virtual machine images for recent builds of the system. VMWare is a program which creates a simulated computer that runs within your current operating system. For the past few years I've tested all of the Linux distributions I've considered on VMWare Server (free to download and use at home). Once I started VMWare, I opened the ship.2-OLPC-655.vmx file and started it up.

After the initial configuration, I wanted to add gcc, a collection of open source compilers. I thought it was going to involve downloading several RPM files, but I found out about a tool called yum which manages RPM packages. This is similar to Ubuntu's apt-get. As root I was able to run
yum install gcc
and it downloaded and installed all prerequisites.

Next I wanted to install Firefox, and to download it I thought I would try Lynx (a text based web browser). Installing Lynx was just as easy, as root I ran:
yum install lynx
I ran lynx www.google.com and searched for firefox and downloaded the tar.gz Linux version. After downloading I unpacked the archive using
tar zxvf firefox-2.0.0.11.tar.gz
I tried running firefox, but got an error about a missing shared object library. Yum was able to find this as well. One final time as root, I ran
yum install libstdc++.so.5
After installing the C++ library, firefox ran just fine. The menus and graphics in Firefox matched the XO's theme, which I thought was pretty nifty. I was also able to install Flash. Well there you have it, why not take it for a test drive yourself.

Tuesday, January 01, 2008

New Year's Resolutions

Well folks, it's that time of year again. Time to set goals with the best of intentions and aim high to better myself. I'm borrowing quite a few of my new years resolutions from last year, there were a couple that didn't go as well as I had hoped. Daily time for devotions, reading, and mediation tops the list. More frequently journaling and blogging also made the cut.

I noticed a handy goal tracking website on Lifehacker which I'm using at the moment. However, I often find that the online nature of tools used to track things like to-do lists and finances can create a small inconvenience which leads to an eventual breakdown. A plain old pen and paper still holds an important place.

In any case, here's to a new year and to best-laid plans.