I completely failed to explain to a group why I think C# 3.0’s pile of features are a poor design. Somehow people keep missing my point. Can you believe English is my first language? If anyone is reading this post, please tell me if this makes any sense to you.

Imagine how Anders, head of the C# design team, might think about the next version of C#. Ten different groups within MS propose 10 brilliant features to add to C# 4.0. Things like pattern matching, concurrency, transactional memory, assertions, categories, etc. Big, complicated, cool features. How does he decide which one to implement? Anders would think long and hard about which feature will have the biggest impact. He’ll choose 1 or 2 and the rest will get shot down. C# 4.0 introduces a few big new features, and this process repeats itself for version 5.0.

If I were running the C# team, I would resist adding any features to C# for fear of feature creep. Instead, I would tell all 10 groups to implement their features as libraries. They will grumble and complain, then they will build a prototype using some insane hackery to get around some limitations in C# and the CLR. I would study those gross hacks, not the features themselves, because that’s where they ran into a roadblock with the language. The goal of language design is to reduce the number of gross hacks needed to implement complex libraries. Because if I can fix C# so these guys can implement their 10 great features as libraries more easily, then I’ve magically enabled hundreds of groups outside MS to also implement their very complex features.

The changes I envision making to C# would be much more subtle than a giant feature like LINQ. I would tinker with some dynamic typing features, better integration with code generation tools, and maybe a way to use attributes within the body of a method (i.e. a parallel loop declaration above a foreach stmt). Small, subtle changes that would have wide impact on library writers, but not most programmers. I’m against adding feature X. Instead, I want to change C# so you can write feature X as a library. Does this make sense?

IE vs. Safari Javascript test

September 7, 2007

I rant this Javascript performance test in both IE 7 and Safari 3 for Windows. IE tooks 3454 ms, whereas Safari took 219 ms. The exact numbers don’t matter, it’s the magnitude of the difference that is shocking. Why is IE so insanely slow?

iPhone Review

September 4, 2007

My gal got an iPhone, which means I’ve been playing with it nonstop and she’s been begging to use it. The iPhone is fantastic. It is insanely great. For the record, I’m not an Apple fanboy. The only Apple product I own is a 1st gen iPod I got as a gift. So here are the few things that are less than perfect with the iPhone:

Read the rest of this entry »

I watched Linus Torvalds rant on Git and distributed source control management (SCM). First of all, Torvalds is a hard-core jerk. He is stunningly obnoxious and egotistical; the very embodiment of the poorly socialized nerd stereotype. As for the talk, he takes a lot of credit for some fairly well known ideas (much like Linux OS).

Read the rest of this entry »

The primary benefit of static type checking is that a compiler can catch a wide variety of bugs at compile-time. With dynamic languages, on the other hand, some bugs aren’t revealed until they actually blow up in your code. Between run-time and compile-time, however, there exists “binding-time”. This is when you actually load all the libraries you are using into a runtime to begin execution. It might be useful to delay type checking until this point to allow runtime manipulation of modules and environments. I can generate code and interfaces at binding-time, then run the type checker and report errors. This gives you most of the flexibility of dynamic code, but preserves most of the safety of statically typed code. You won’t discover the error until you load everything into a runtime. I know of some early static checking tools for C that did this, but I don’t know of any statically typed languages that move checking to this phase of development.

Inventing a new PL

August 21, 2007

I’d like to implement a new programming language for my personal use. Here are some qualities I’m interested in:

  • small: It should be as small as possible, like lambda calculus.
  • extensible: All syntactic sugar added here. Also, must support compiler extensions.
  • concurrent: need abstract notion of concurrency built in.
  • typed: static is better than dynamic typing, but it should support both.
  • lazy: the implementation can still be strict, but lazy gives more freedom to programmers
  • modules: need a simple, yet reflective, module system.
  • FFI: should be able to easily access foreign code, preferably C-like.

It seems like I could build my language on top of Clean. I’ll try writing some programs in Clean first.

Two security experts described some ways to improve voting machines. In designing a secure voting machine, the central assumption should be that the machines will be hacked. Therefore, it’s foolish to rely on one machine from one company. Instead, as these guys describe, one machine should generate a machine-readable paper record of the vote that can be verified by the voter and scanned in by another machine. A voting site might have a dozen voting machines and 1 optical scanner. It’s still possible to hack the optical scanner to manipulate votes. So I propose that each voting machine map the candidate names to a set of random numbers: (Machine1 Bush 8204). Every machine is different. After voting, the receipt will say you voted for Bush, but the optical scanner will read in the number 8204 (and 2947 from machine 2, 1695 from machine 3, etc.). The scanner tabulates the number of votes for 8204, but it has no idea what that means. Therefore, a hacker wouldn’t be able to manipulate votes because he doesn’t know what these numbers represent. The scanner sends these random numbers to the central computer. Again, the central computer has no idea what these numbers represent. Finally, the voting machines send their mappings and votes to another central computer. Now the central computers can map (8204 -> Bush) to determine the final tally and verify it against each voting machines records. The central computer can send a report back to each voting station for poll workers to manually verify the total against the voting machines’ numbers.

How can a hacker defeat this system? If he hacks the optical scanner or the first central computer, he’ll only see a bunch of meaningless random numbers. If he hacks the second central computer (the one that gets the mappings and votes), he can’t do anything because the results must match the first central computer. If he hacks both central computers, he still can’t do much because the numbers will be double-checked against the voting machines. If he hacks all the voting machines, he could assign Bush’s number to Gore; therefore, the voter see “Gore” on his paper ballot, but optical scanner reads Bush’s number. However, the poll workers can spot check the numbers to ensure they are different. This seems like a decent solution, though it’s rather complicated. It needs to be simplified because poll workers are fairly dumb. You can’t rely on them to do anything right, especially when there are several independent steps. Nevertheless, I don’t think it’s difficult to build a secure electronic voting system. It would certainly be different from the one we’ve got today.

WS-BPEL is neato

August 14, 2007

WS-BPEL is an XML specification for a distributed programming language for coordinating web services. With this you can write a “business process” that sends data to A, then B, then collects the response. Unfortunately, it looks like all the intermediate data will go through the WS-BPEL execution engine. That makes the engine the bottleneck in a distributed system. I think a WS-BPEL spec should be converted into CPS and executed by the services themselves, not by the execution engine. That is, you can send data to A; A sends its output to B; B sends it output back to you. See? You’ve avoided receiving A’s intermediate data. In a sequence of a dozen services, you can avoid receiving a dozen intermediate values. With existing technologies (AFAIK) like BizTalk, you receive all the intermediate values; therefore, BizTalk is the bottleneck in a distributed system. Nevertheless, WS-BPEL, now that I sorta’ understand, is really useful and powerful.

I wrote a Yahoo! widget that displays the energy cost of running a computer. Based on Google’s paper on data center energy consumption, it uses CPU load as a good approximation of energy usage. You can calculate your computer’s peak power requirement by adding up all the components in your system.  Since your power supply loses some energy to heat, you should divide by it’s efficiency rating (mine’s 85%, but most computers are ~60%). This total number will be significantly higher than the true peak power load because manufacturers list very conservative (i.e. high) numbers. Google found their server ran at 60% of the “nameplate” value. I’d say take 80% of your total to get closer to a real peak power number.

At 0% CPU, a computer still consumes 50% of peak power. It’s linear from 0% to 100% CPU, so it’s easy to compute how much power is consumed: (50+(CPU load/2))% of peak power(W/hr). Multiply this by your cost per kW/hr to get the energy cost. You can also compute how much pollution was generated to provide you with that energy using this table: http://www.eia.doe.gov/oiaf/1605/e-factor.html. The point of all this is to illustrate that the energy required to run your computer is a significant cost per year. If my computer sits idle all year, it costs about $70 $200 to power it. [edit: I misread my power bill]

Stream Programming

August 8, 2007

Stream programming is a style where one describes a graph of interconnected actors that process a stream of data. See StreamIt. The data can be split and joined; therefore, it’s not the typical simple linear stream found in I/O libraries. There are three types of parallelism to consider:

  • Task parallelism: two tasks running in parallel on separate data streams
  • Data parallelism: a task that can be applied independently to every element in a data stream
  • Pipeline parallelism: a linear set of tasks that can be merged together

I’d like to build a stream programming language that runs on top of Hadoop. This is a project at Apache that implements something like Google’s distributed filesystem, MapReduce and BigTable. MapReduce is, I think, a subset of stream programming (though I’m not sure about “reduce”). Anyway, I need a benchmark that is large enough to exercise a group of machines on Amazon’s EC2.