Skip to main content


Showing posts from 2007

OpenSocial talk at Google

I went to an OpenSocial talk at Google about a month ago. Sorry it's taken me so long to write a summary. Hopefully it won't be completely out of date ;) Here are a bunch of random notes:The talk was held in the same room that the Bay Area Python Interest Group normally holds its meetings. However, I knew right away that something was different when I got there a half an hour ahead of time, and the room was already filling up. During the meeting, I counted rows and columns, and estimated there were about 200 people present.

Google was making a big deal of the meeting. They were providing dinner, which they don't do for our group.

Looking at the JavaScript examples, the code looks strangely verbose.

Security is not defined in the spec. Dealing with third-party JavaScript is a challenge. Facebook's answer was FBJS. At least at that point in time, OpenSocial didn't have a well-defined answer to that problem.

One of the demos crashed.

They're taking the lowest …

Books: Isaac Asimov Predicted Wikipedia

I'm reading Isaac Asimov's book, "The Beginning and the End". I can't get enough Asimov, which is good, considering he's the most prolific author that ever lived.

"The Democracy of Learning" (Chapter 3 of "The Beginning and the End") is a short essay that appeared in "Know" magazine, which was a short-lived magazine that was put out by the makers of the "Encyclopaedia Britannica". It's ironic that Asimov was writing for the "Encyclopaedia Britannica" when he wrote:And I look forward to the time when computerization will place in every home a terminal connected to some central library which will place, in facsimile, or on the television screen, the resources of human generations at the very fingertips of even the least of humanity. But that, alas, was not in my time.Well, Asimov, you're right. Wikipedia is incredible, and I'm sorry you missed it.

Python: Some Concurrency Tricks

Here are a few concurrency tricks if you're stuck using threads. I used these tricks years ago to write a Swing application in Jython, and I found them to be helpful enough to warrant a blog post, albeit a few years delayed.

First, let's suppose you have a UI and you want to talk to an external program written in another language that might occasionally block. Use the main thread for the UI and use a separate thread to coordinate with the external program. In general, most things that might block should have their own thread.

Name your threads.

It's likely that certain code should only be run by the UI thread and vice versa. At the top of each method, do an assertion on the thread name.

Avoid sharing data. Sharing data involves mutexes, etc. which is generally painful and easy to mess up. Instead, constrain each bit of data to a single thread. If you need to interact with that data from another thread, "ask the other thread for help".

The way I like to do this …

Books: Ajax in Action

This is a review of Ajax in Action.

It's amazing how much the JavaScript world has changed.

This book has a relaxing style, and it was enjoyable to read. However, it no longer represents what I think of as "modern" JavaScript. For instance, it doesn't cover closures until appendix B, and even then it tells the reader to avoid them. These days, having studied Dojo, jQuery, and Douglas Crockford's videos, it's clear that closures are at the heart of how modern JavaScript is written.

The copyright for this book is 2006, yet the index doesn't even mention Firebug, YUI, dojo, or jQuery which are now staples of the JavaScript community. Dojo is at least mentioned in the list of Ajax frameworks and libraries, but the others aren't.

This book is an interesting relic from that period when Ajax was first gaining popularity, before the major JavaScript frameworks had gained a foothold. These days, for those wanting to learn modern JavaScript, I recommend watchi…

Python: Getting Genshi to Output FBML in Pylons

This took me quite a while to figure out, so I'm going to blog it for the sake of Google. To get Pylons to tell Genshi to output XHTML so that you can output FBML for Facebook, edit your and do:# Customize templating options via this variable
tmpl_options = config['buffet.template_options']

# Without this, all the FBML tags get stripped.
tmpl_options['genshi.default_format'] = 'xhtml'My templates now start with:<fb:fbml xmlns=""

Web: Flock

I've been trying out Flock lately as an alternative to Firefox. Although it's based on the same rendering engine, I've heard that Flock is more stable. Flock is interesting in the way it integrates with the many social networking and blogging sites I use, but since I'm a minimalist, it's not really my cup of tea. It's been more stable than Firefox, but it doesn't support the Foxmarks plugin, so I can't synchronize my bookmarks with it. This put me in sort of an awkward position since all my bookmarks are in Firefox, and although I was able to import them, I'm not ready to give Firefox and Foxmarks up yet. I've heard that it at least supports Firebug, which is another must have for me.

Well, I've been using Flock for a week or so now, and I can really see why some people would like it. However, it's just not my thing, and it finally crashed on me. It's probably Mozilla's fault that it crashed, but I'm now tempted to swit…

Python: Walking Recursive Generators

import types

__docformat__ = "restructuredtext"

def walk_recursive_generators(generator):

"""Walk a tree of generators without yielding things recursively.

Let's suppose you have this:

>>> def generator0():
... yield 3
... yield 4
>>> def generator1():
... yield 2
... for i in generator0():
... yield i
... yield 5
>>> def generator2():
... yield 1
... for i in generator1():
... yield i
... yield 6
>>> for i in generator2():
... print i

Notice the way the generators are recursively yielding values. This
library uses a technique called "bounce" that is usually used to
implement stackless interpreters. It lets you write:

>>> def generator0():
... yield 3
... yield 4
>>> def generator1():
... …

On Paul Graham and Joel Spolsky

I've often enjoyed reading the works of Paul Graham and Joel Spolsky, but there's always been something that bothered me about them, especially Paul Graham. Paul Graham writes his arguments like a mathematical proof. Each step in the process seems reasonable, and by the time you reach the end, you don't feel like there's any room to disagree. However, I just don't think life is so black and white.

My buddy Alex Jacobson finally explained it to me. They are good "story tellers". Apparently, this is even part of the culture in New York, where Joel is from. Hence, it's enjoyable to listen to their arguments. However, there's a problem with good story tellers. Their tales are often so enjoyable that it's easy to be lulled into a false sense of security and overlook the exaggerations and mis-truths. Like listening to a good talk-show host, it's easy to forget to be objective.

For instance, it's somewhat frustrating to listen to Paul …

Books: Founders at Work

I just finished reading Founders at Work: Stories of Startups' Early Days. I've been nibbling away at it over the last five months or so. It's now one of my favorite books. If you work at a startup or are thinking of starting a startup, this book is a must read!

I like to interview, so when I'm looking for a new job, I tend to interview a lot. The last time I was looking for a job, I felt like this book was my personal guidebook to Silicon Valley (which loosely includes San Francisco). So many of the people and companies I was interviewing for were in the book. I felt like I was getting the inside scoop. Even when they weren't in the book, the book gave me insights on what a good startup looks like.

Now that I've finished building Free or Best Offer, it's time for me to look for my next startup. I wonder where the book will lead me next. Although they aren't mentioned explicitly in the book, I'm currently leaning toward Metaweb.

Free or Best Offer

Today, we launched our Facebook app Free or Best Offer. I wrote most of the code, whereas my co-worker Alex Jacobson designed most of the features. We've been working on it for the last few months.

In other news, I finally finished reading "Agile Web Development with Rails" cover-to-cover. 685 pages! Man, my head hasn't hurt this bad since I decided to read "Design Patterns: Elements of Reusable Object-Oriented Software" cover-to-cover.

Anyway, it's been quite a day. If you get a chance, checkout my app and get a free beer ;)

OOP: Alan Kay

In "Dreaming in Code" on page 289, Alan Kay, the creator of Smalltalk and of the windowing paradigm, said, "I made up the term object-oriented...and I can tell you, I did not have C++ in mind." In fact, he said that the OOP that we see today is a bastardization of his original ideas.

One thing that he had in mind was that objects would be actors. An actor is an object + a thread + a message queue. Just imagine if each object had its own thread and they passed messages to each other asynchronously. This idea is gaining popularity these days in languages like Erlang, Scala, and Groovy. I like to say that what we have today is one employee (i.e. thread) wearing many hats (i.e. running the code for many objects) vs. one employee per hat.

For a while I've been intrigued by Alan Kay's thoughts on OOP. My buddy Mike Cheponis sent me this, Dr. Alan Kay on the Meaning of "Object-Oriented Programming".

Interestingly enough, the two OO-haters I know actua…

'fsck' Apple, I'll take my freedom!

<rant mode>
The newest version of OS X just came out, and my buddy was telling me about all its great new features. Many of those features have existed in the Linux world for years; some haven't.

He sent me email saying, "There is a big chasm and OS X is driving at 1000 miles an hour to close it on the Unix side. Now if Linux gets it's act together and does all the things OS X does!" Hmm, if "Linux gets its act together..."

Macs are nice. I won't deny that. However, let's face it. A big part of the success of OS X was that they were able to make use of existing software like FreeBSD, KHTML, bash, Python, gcc, etc. OS X can "drive a 1000 miles an hour" because there's so much outstanding open source code to draw on. The reason why the Linux world can't keep up with all the innovation in OS X is because things like Cocoa, Aqua, and Quartz aren't open source. Frankly, I'd love to take someone els…

Linux: Xubuntu 7.10 on a Compaq Presario C500

I was frustrated with Ubuntu 7.10 on my Compaq Presario C500, so I thought I'd give Xubuntu a try. So far, I really like it. It's crazy fast, and I have almost a gig of RAM free :)

Like Ubuntu, the non-standard display resolution worked correctly out of the box. Sound works, although it was crackly during install. In Ubuntu, suspend crashed my machine, but hibernate worked; I haven't tried it under Xubuntu.

Note that since the wireless card doesn't work by default, it's best to be plugged into a wired network during install. The installer makes use of the Internet connection to download various things.

Since this is a laptop, it's best to turn on sub-pixel hinting in Applications >> User Interface Preferences.

I'm not sure if it's needed for the instructions below, but I always like to enable all repositories: Applications >> System >> Synaptic Package Manager:
Settings >> Repositories:
Click on all of them except sourc…

Linux: Ubuntu 7.10 on a Compaq Presario C500

I just installed Ubuntu 7.10 (Gutsy Gibbon) on my Compaq Presario C500. Things went really well. Have I mentioned how much I love this little $375 laptop?

My laptop has enough room for Windows Vista (which I never use) and two copies of Linux. I like to keep around the old version of Ubuntu while upgrading to the new in case something goes wrong and I need a working system. This time, it recognized the other copy of Linux and migrated the users and their settings. By settings, I mean the settings for Gaim, Mozilla, and Evolution. This seems like a rather odd feature, considering it didn't copy all of the other files. Nonetheless, it didn't hurt anything.

Note, that it's probably better to be plugged into a wired network during the install so that it can setup repositories and download security updates. I wasn't, so I had to setup the repositories later.

Happily, the weird resolution (1280x800) just worked this time. Unfortunately, attempting to suspend crashed my…

Computer Science: What's Wrong with CS Research

I absolutely love this blog post: What's wrong with CS research.

I'm a wannabe language designer. I've written three articles on Haskell, but I adore Python. I've been thinking of going back to get my Ph.D so that I can try to move the industry forward. I could never figure out why programming language research had to be so dang complex or mathematized.

A lot of his points matched the points I made in one of my articles, Everything Your Professor Failed to Tell You About Functional Programming, especially in the "What's Up with All the Math?" section.

I'm so glad that I read this post! I feel like I've been set straight. Now I know that hanging out with Guido is probably more useful than trying to understand all those crazy research papers ;)


So it seems like Firefox is having problems and everyone has been complaining about it a lot. I sure hope they fix it quickly. It's crashing on me constantly when I indulge in my YouTube addiction, and it uses up an ever-increasing amount of memory. A lot of my friends are enjoying Opera, but I just can't bring myself to install a proprietary browser.

I decided to give KDE and Konqueror another shot. I'm actually pretty pleased with it. Although Konqueror doesn't support two of my favorite Web sites, GMail and YouTube, it is very stable and very snappy. Even better, it uses half as much memory. It has a menu option to open the current page in Firefox, which is helpful for the times it doesn't work. This matches what a lot of Mac users do: they use a mix of Firefox and Safari.

On the other hand, something strange happened when I was installing KDE. I accidentally uninstalled the Ubuntu flashplugin-nonfree package. Today, when I went to YouTube, Firefox asked…

Computer Science: Prototypal Match Templates

In object-oriented programming languages, you can subclass an existing class and override a few of its methods. This allows you to take an existing piece of code and tweak it for your own use. However, it's only as granular as the methods that you are overriding. If you want to change one line in a 30 line method, you either have to refactor that 30 line method into several methods (which is the right thing to do if you're in control of the code) or you have to copy the 30 lines and modify that one line (which may be the only thing you can do if you're not in control of the code). Sometimes I actually do both. If I'm using a third-party library that has a 30 line function that I want to change one line of, I copy the whole function into my class, and then refactor it there as if I were refactoring the superclass.

Genshi has a cool mechanism called match templates. I assume XSLT has this too, but since I don't know XSLT, I can't say for certain. Genshi'…

Python: PyWeek

I just finished PyWeek! (Here's the code.) It's a contest where you have one week to write a video game using PyGame. We also used PGU, which is a pretty helpful library for writing video games. This time, my buddy Adam Ulvi participated with me. We took two days off from work and wrote about 800 lines of code. I'm proud to say we created what I think is a pretty impressive and fun game.

I leaned pretty heavily on object-oriented programming this time. I know a lot of people like to talk smack about OOP, but I often find it helpful. The player, the enemies, and even the artillery all subclass a class called SuperSprite that takes care of things like integrating per-frame movement, per-frame animation, collisions, etc. OOP lets me say "these guys should all act exactly the same except in these slightly different ways." Often times, the subclass is no more than a few class-level constants, like a different image. Sometimes they behave slightly differently, …

Python: Useful Utility for PGU's leveledit

I'm participating in PyWeek right now, and I'm using PGU. If you're not using PGU, you can skip this post.

If you're like me, you sometimes get confused about when you're editing the tiles and when you're editing the background. My buddy drew an entire level, and the tiles and background were totally messed up. Rather than redo the entire level, I wrote a little utility to force all the tiles into the background. It's quick-and-dirty, but quite useful when you need it:#!/usr/bin/env python
# Copyright 2007 Adam Ulvi, Shannon Behrens
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of

Computer Science: Smart People Have Weird Hangups

Have you ever noticed that smart, interesting people have weird technical hangups? Often, they take a good idea to its logical conclusion in such a manner that it dominates their lives. For instance:

I'm an open source fanatic. I'll put up with a lesser product if it means the difference between being open source or not. For instance, I think Apple has a better desktop experience than Ubuntu does, and I also think they have slicker laptops than Dell has. However, I refuse to buy a Macbook because it's not open source, despite the fact that all the people around me have Macbooks--even my heros Guido van Rossum and Bram Moolenaar.

My buddy Mike C. hates OOP. Mike's a wicked sharp guy from MIT, so he's earned the right to his opinion. (As an aside, it's strange how vehement many Lisp hackers hate OOP, despite the fact that OO systems exist for Common Lisp.) It'd be one thing if he were simply a fan of Scheme over Java, but Mike often codes in Python and …

What's Going on with my Wireless?

Yesterday, my Dish Networks satellite went out and took 20 minutes to come back.

Also yesterday, my wife's bluetooth headset kept disassociating itself from her phone. She had to reset it several times.

Last night, my access point stopped working. From the access point, I could ping my DNS server. From my laptop, I could establish a wired and/or wireless connection to the access point, but from my laptop, I could not ping my DNS server. The same was true of my wife's laptop. I hadn't changed anything on my AP in months. Finally, I gave up, restored it to factory defaults, and set it up again from scratch. Now it works.

What's going on? Was there a solar flare I didn't hear about? Might it be that my 100 year old house is not providing "clean" electricity? Any ideas? Weird.

Computer Science: Popular Languages Never Die

It's interesting to me that while a modern Web application seems to have a shelf life of two years, popular programming languages never die. This isn't news, but I thought I'd just point out a few:FORTRANFORTRAN is still a favorite among scientists.COBOLCOBOL is still alive and well in ERPs and banking systems.CC isn't dead by a long shot. Kernels (e.g. Linux) and interpreters (e.g. Python) are still written in C.LispEven though Lisp was first written about 40 years ago, Lisp is still used at various companies like Orbitz, and rest assured that as long as Paul Graham lives, he'll never stop talking about it ;)APLAPL seems dead, but it's not. Every once in a while, I'll meet a strange hacker who can translate a long algorithm into a single magical incantation of funny symbols in APL.ForthForth is alive and well at the firmware level.PascalPascal's not dead. It's still being taught as a first programming language.AdaAda is still being used by the …

Ruby: All Your Method are Belong to Me

Ruby has a curious approach to protecting instance variables, constants, and private methods.

I've often heard Java programmers criticize Python because it doesn't enforce privacy in any way. Personally, I think that it'd be great if Python could be fully sandboxed like JavaScript can, but sandboxing is a completely separate topic. Preventing a programmer who works on my team from calling a method that I've named _private_method isn't all that interesting to me. If he sees the fact that I've named the method with a leading underscore, and he still feels the need to call it, so be it.

Ruby does provide private instance variables, constants, and private methods, but really, those are just suggestions.

For instance, if you override a constant, you just get a warning:irb(main):001:0> A = 1
=> 1
irb(main):002:0> A = 2
(irb):2: warning: already initialized constant A
=> 2
irb(main):003:0> puts A
=> nilIf you have an object, and you want to call a private…

Treo 650 on Ubuntu 7.04 (Feisty Fawn)

I got my Treo 650 working under Ubuntu 7.04. I think some stuff is broken, because this is harder than it should be.

Create /etc/udev/rules.d/10-local.rules with:BUS=="usb", SYSFS{serial}=="PalmSN12345678", KERNEL=="ttyUSB[13579]*", SYMLINK="treo"Then do sudo /etc/init.d/udev restart

Add visor to the end of /etc/modules.

Run sudo modprobe visor

Setup JPilot. The device should be /dev/treo. The speed should be 57600. Yes, I know this shouldn't matter for USB devices, but it won't work if you don't set this.

Remember to hit the hardware sync button and then the JPilot sync button.

Here are some random tips:

Pay attention to the logs: sudo tail -f /var/log/messages

See what /dev/treo is being set to: ls -l /dev/treo

Make sure your user is a member of the dialout group. Mine was by default.

Operating Systems: OpenDarwin Shutting Down

I totally missed this: OpenDarwin is shutting down:OpenDarwin has failed to achieve its goals in 4 years of operation, and moves further from achieving these goals as time goes on...The original notions of developing the Mac OS X and Darwin sources has not panned out. Availability of sources, interaction with Apple representatives, difficulty building and tracking sources, and a lack of interest from the community have all contributed to this.I can't say I'm surprised. When it comes to playing fair in the open source world, I simply trust the Linux guys more than I trust Apple. Besides, Darwin isn't even the most interesting thing about OS X--Cocoa is. Tragically, it's closed source.

As you all know, I've been pondering operating systems lately. I just don't think people are going to tolerate Apple's walled garden / vendor lock-in forever. I don't get the sense that Vista is a huge success. Based on my attendance at Linux Expo for the last seven y…

Python: Coding in the Debugger for Beginners

Python has a wonderful interactive interpreter (i.e. shell). IPython is a third-party Python shell that's even nicer, but that's a topic for another post. It's fairly common to code in the shell until you have the code working correctly, and then copy-and-paste it into your program. Developing super-interactively is a great way to keep bugs at bay.

However, sometimes you need more setup before you can start coding. For instance, when writing a Web app in, say Pylons, you might need an actual request and a database connection before you can start coding what you want. You might even need a form POST before you can start. Ideally, you'd be able to start the shell from in the middle of your application at just the right spot. I'm pretty sure that someone out there knows how to get IPython to do the right thing, but I find using pdb, the Python debugger, really helpful for this purpose.

First of all, add the following wherever you want to break into the debugger, …

Python: Database Migrations

As part of my day job, I've written a Rails-style database migration script. This lets you write migrations from one version of a schema to the next. This allows you to develop schemas iteratively. It also lets you upgrade or downgrade the schema. Best of all, if an attempted upgrade fails, it can back it out even if you're not using transactions. Of course, this is based on writing "up" and "down" routines--it's practical, not magical.

I'm releasing this code in the hope that others will find it useful. It's well-written, solid, and well-tested. This is the type of thing you could probably write in a day. I took four, and polished the heck out of it.

It uses SQLAlchemy to talk to the database. However, that doesn't mean you have to use SQLAlchemy. Personally, I like writing table create statements by hand. You can do either.

My database configuration is stored in a .ini file ala Paste / Pylons. Hence, the script takes a .ini file t…

Vim: VimOutliner

I make heavy use of a nicely indented notes file and a TODO file. Until recently, I had never used an outline editor, even though my files were basically outlines. I saw my buddy, Alex Jacobson, using his outline editor, and I decided to try out the one for Vim. Within a couple hours, I was hooked!

Actually, there are several outline plugins for Vim, but I think that VimOutliner is the best.It has nice syntax highlighting for the different levels.It manages Vim's folding as you would expect.It understands how to put a paragraph of text under a heading and how to automatically turn on line wrapping.It supports checkboxes, and it's really smart about working with them.It supports inter-document linking.It has a nice menu, so you don't have to memorize the documentation before getting started.Best of all, since it's a Vim plugin, it fits right in with my blazing-fast, Vim editing skills.

Pondering Operating Systems

For a long time, my goal has been to develop a higher-level, natively-compiled programming language, and then to develop a proof-of-concept kernel in it. Well, someone else beat me to the punch.

House is a proof of concept operating system written in Haskell. It has some simple graphics, a TCP/IP stack, etc. Naturally, it's just a research project, but achieving proof of concept was my goal too.

On that subject, I'm also keeping my eye on Microsoft's Singularity. It's a microkernel, and much of it is written in C#. Unlike most microkernels, the different components do not run in separate address spaces. The VM does protection in software, rather than hardware. I had been toying with this idea too, but my buddy Mike Cheponis informed me that VM/360 did it decades ago.

Is anyone other than me bummed that BeOS never took off? I'm sadly coming to the conclusion that Linux might not ever make it on the desktop. It's just not a priority. Too many greathackers

Python: Look What the Stork Dragged In

Well, this is supposed to be "a purely technical blog concerning topics such as Python, etc.", so let me start by showing off a quick little Python utility that I had to write at a moments notice:#!/usr/bin/env python

"""Help Gina-Marie time her contractions."""

import time


last_start = None
while True:
print "Press enter when the contraction starts.",
start = time.time()
if last_start:
print "It's been %s minutes %s seconds since last contraction." \
% divmod(int(start - last_start), SECS_PER_MIN)
last_start = start
print "Press enter when the contraction stops.",
stop = time.time()
print "Contraction lasted %s seconds." % int(stop - start)
printIf you want to find out more, read the comments ;)

Computer Science: Coping with Unknown Types

What do "void *" (a la C), polymorphism (a la C++ classes), interfaces (a la Java), generics (a la C++ templates), and duck typing (a la Python) all have to do with one another? They're all ways in which you can write code that works with types that you didn't envision when writing the code.

A "void *" in C is a pointer to something of unspecified type. You can't do very much with it unless you know what type the something is. However, you can still pass it around. You can store it in a list or tree. You can take it and later pass it back to a callback function. All of these things are useful, and, in fact, this functionality still exists in Java (albeit, it's a lot safer in Java). However, instead of casting to "void *", you cast to "Object".

Polymorphism in languages like C++ and Java let you take an object and call methods on it without necessarily knowing exactly which subclass the object is a member of. Let's suppo…

10 Reasons Big Projects Suck

Have you ever noticed that big projects inevitably get a bad rap? Here are 10 reasons why:Let's assume for a moment that there's one bug for every 100 lines of code. If a big project has 10 times as much code as a small project, it has 10 times as many bugs. In reality, because big projects are harder to understand and intrinsically harder to change quickly, it probably has more than 10 times as many bugs.
If a big project implements some feature A, there is bound to be some bug in it. That proves that the big project is buggy. Furthermore, inevitably, the feature isn't exactly what you need. That means it's inflexible.
If, on the other hand, the smaller project doesn't implement feature A, it can't possibly have the same bug the big project has. Hence, it's not buggy. Furthermore, since you'll need to implement feature A yourself, you'll probably implement exactly what you need. That means it's more flexible.
Furthermore, there are a lot o…

Random Comments from Google Developer Day

I went to Google Developer Day. Yeah, yeah, I know, that was weeks ago, and I'm only finally blogging about it now. Better late than never! Here are some random, sparse comments:
KeynoteThere were about 1500-5000 developers world wide attending this event. A ton of APIs were launched in 2006. He mentioned Yahoo Pipes. Google Mashup Editor is a mashup of mashups. I felt pretty overwhelmed pretty quickly. Gears is about offline access for Web apps. It supports all major browsers and all major platforms. It's pretty weird to see SQL in JavaScript. It's based on SQLObject. There is a managed "sync" process. Google Reader will soon work offline. They're working closely with Adobe (e.g. Apollo). It was weird to hear the Adobe guy say, "Works on Linux". Sergey has a great sense of humor.

Gears TalkYou can configure a set of URLs for it to capture for use offline. This stuff is stored in a place separate of the normal browser cache. I saw a …

Computer Science: Smart Code Reloading

How do you reload code at a per-module level? How do you deal with the data that the module might contain?

Reloading code on the fly is something that the original Lisp machines were famous for. Erlang/OTP is famous for this too. In my own project, Aquarium, which is a Python Web application framework, I use to do this trick as well.

In Python, reloading code is relatively easy (with a bunch of caveats having to do with import "graphs" and inheritance hierarchies). However, what do you do with the data? When you reload the module, the old data in that module is lost.

I've always wondered how the Lisp guys did it. How did they cope with changes in the data format? If you have a list of tuples of length 3, what happens if the new code expects a list of tuples of length 4?

In Rails land, they have database migration scripts. Hence, you specify the entire schema as an iterative set of changes to the database, starting from an empty database. You can also back out a migr…

Linux: Ubuntu 7.04 on a Compaq Presario C500

I got Ubuntu 7.04 working on a new Compaq Presario C500 laptop. It's running really well, and it only cost me $479 :-D

The Ubuntu installer voluntarily resized sda1 (the primary partition) to 41595mb. I'm super impressed that it knows how to resize an NTFS partition! Hence, dual-booting Ubuntu and Windows Vista was really easy. By the way, I left sda2 alone. It's 5946mb, and it contains the Compaq restore image.

By the way, does anyone else feel that Compaq computers running Windows are simply an ad delivery mechanism? The default 512mb is scarcely usable in Vista. Fortunately, it's just fine under Ubuntu.

I setup wireless using ndiswrapper.

I kept hitting the touchpad with my thumb, which was messing me up when I was typing. Hence, I did:apt-get install gsynapticsSet "SHMConfig" to "true" in the touchpad section of /etc/X11/xorg.conf.I restarted X.I ran the touchpad preferences utility at System :: Preferences :: Touchpad. I disabled tapping.T…

Ruby: A Python Programmer's Perspective

As a "language lawyer", it's fun to learn new languages and see how they differ in subtle ways. Here are some of the many ways Ruby is different from Python, etc. Most of these aren't necessarily good or bad, they're just different. Looking at the differences, it's fun to try to peek into the design decisions behind the languages. If you've noticed more interesting differences, post them below as comments!In Ruby, Classes, modules, and constants must begin with an upper case letter. Actually, this reminds me of Haskell.
Ruby uses "end" instead of indentation. That's fine unless you're a Python programmer like me who keeps forgetting to type "end" ;)
Ruby doesn't have true keyword arguments like Python. Instead, if you pass ":symbol => value" pairs to a function, they get put into a single hash. Python can act like Ruby using the "**kargs" syntax, but Ruby cannot act like Python; it cannot expli…