Skip to main content


Showing posts from June, 2007

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 s

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 a

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: Keynote There 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 Talk You 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 sa

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

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 gsynaptics Set "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 disabl

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 exp