Sunday, April 11, 2004

Weird Documentation is funny but it's natural to end up with weird things like that. The trouble is that things that make sense in one context (that of the author, who has been using some product during development) don't make sense without that context. This is why user testing is so important. You get to learn that you had gotten so used to some particular way of thinking that you don't realize how it has affected your thinking.

Sunday, April 11, 2004

If you ever wanted to learn to program but thought the books were too boring, this guide to Ruby is for you. You may end up running away screaming back to the boring books, but it's worth taking a look. You'll also have “chunky bacon” in your head for the rest of the week.

to
Sunday, April 11, 2004

There are two lines of thoughts for pointers vs. references. One says to use pointers when something can be null and references elsewhere. The other says to use pass pointers when something is mutable and pass const references when it's immutable, because if you use non-const reference parameters it's hard to tell at the caller that something might be mutated.

I tend to prefer using references almost all the time. So I was looking for something that could address the mutability issue without my having to switch to pointers. Here's one solution:

  template<typename T>
  struct receivable {
    explicit receivable(T& receiver): receiver_(receiver) {}
    T& get() { return receiver_; }
    operator T& () { return receiver_; }
    T& operator = (const T& v) { receiver_ = v; return receiver_; }
   private:
    T& receiver_;
  };

  template<typename T>
  receivable<T> receive(T& receiver) {
    return receivable<T>(receiver);
  }

It's a small helper class that annotates the argument. Instead of the caller using f(x) for both immutable and mutable parameters, it'll use f(x) for immutable and f(receive(x)) for a mutable parameter. Here's some sample code:

void f(receivable<int> i) {
  i = 5;
}
 
int main() {
  int j;
  f(j);              // this line causes a compile-time error
  f(receive(j));      // this line works
}

Just as auto_ptr is the standard way to use the type system to mark the transfer of ownership, receivable is a way to use the type system to mark that an argument may be mutated. There may be other kinds of annotations that can use the same technique.

Sunday, April 11, 2004

A few years ago I started exploring an idea I call “smart numbers”. In C we had pointers and numbers. In C++ we tend to use smart pointers instead of pointers. Why not smart numbers instead of numbers? Read more...

Sunday, April 04, 2004

Fun scenic drive this weekend—we went to Lake Tahoe on highway 50, from Sacramento to South Lake Tahoe. The weather was warm so there was much snow melting, feeding waterfalls and streams.

Something new: the Heavenly Gondolas just a few blocks from the casinos. Previously, you had to drive in from the main street (highway 89) to find Heavenly. Since I wasn’t there to ski, I never bothered driving to Heavenly before, but now that it’s on the main street, I might take their gondolas to the top just for sightseeing. They cost $20 for a round trip (per person) and take you from the lake level (6000 feet) to the top of the mountain (9200 feet).

This is the first time I went up to Tahoe and back in one tank of gas. 12.2 gallons, 450 miles. Driving at 45–55 mph (on highway 50) really helps with gas mileage. If we hadn’t used the air conditioner and if we had waited until the tank was empty, we could’ve made 500 miles on one tank of gas. (No, I don’t have a hybrid; I have a 10 year old Saturn SL2.)

Total cost of the day trip: $49 = $25 for gas, $19 for food and snacks, $5 for slot machines.