Archive for August 2003

 
 

Google

Jeremy Zawodny has noticed that Google does take the word ‘for’ into account even though it says it isn’t.

While Google uses the publicized PageRank algorithm, the weight it gives to different links differs. Google analyzes the link topology and does statistical natural language processing in order to weight links.

To understand what the above means assume for a moment that you want to subvert PageRank in order to promote your website to a #1 position for a specific term. If links were all weighted the same, all you would need to do is have a web server with 1,000,000 dynamically generated pages that point to each other and to your website.

However, Google will notice that all pages reside on the same server and thus give the links less weight. It will also statistically analyze the text, compare it to other texts, and additionally weight down the links.

Manipulating Google thus becomes costlier: you need to appear on many different IP addresses (I don’t know if Google takes the owner of an IP range into account), and to generate pages that fit the natural topology and content.

Black != Black

Oh, this is lovely. The following expression:

Color.Black == Color.FromARGB (0, 0, 0)

evaluates to false.

The workaround is to compare (A,R,G,B) values:

c1.ToArgb () == c2.ToArgb ()

Here comes the best part: This is not a bug, it’s documented behavior:

“This method compares more than the ARGB values of the Color structures. It also does a comparison of some state flags.”

“Some” state flags? Oh, please don’t go into specifics, who needs those when programming?

Literary Flair

Erik Meijer: Many computer books are so heavy that lifting them causes hernia, yet they have less content than your favorite tabloid. Many academic textbooks are so boring that they turn your brains to dust, yet they don’t teach you anything that is of use in the real world.

Compilation Warnings

Speaking of C++: Visual Studio is seriously fucked up in regard to warnings.

In the C++ compiler, lots of very reasonable warnings are set to level 4. The compiler defaults to level 3, so most people won’t see them. Those who do try to venture into level 4 will be dissuaded by the myriad of useless warnings that also live there.

In the C# compiler, there is still no way to disable some warnings locally. This makes the checking the build results painful.

Rotor

I stepped onto a bug in the .NET Framework’s runtime a couple of days ago. Since I couldn’t find the symbols for the .NET Framework on the Symbol Server, I decided to see if I could learn something by wading through the Rotor sources.

The thing that surprised me the most is the absence of good C++ coding practices. Even the basic practices such as using constructors and destructors to manage memory are not used, let alone any of the Boost-like goodness.

Scary.

Macros

Whenever I mention macros people look at me as if I made farting noises with my armpit during high tea.

C and its successors give a bad name to two otherwise very useful language features: macros and unions. I’ll cover macros in this post and unions in a later one.

C macros perform dumb text substitution. That makes them not very useful and dangerous. See the section 38.4 of the C++ FAQ for four reasons why the C macros are dangerous.

However, Lisp and its variants have macros that don’t operate on program text, but instead on the abstract syntax tree.

An abstract syntax tree is a tree-like representation of the compiler’s input. The top node has sub-nodes such as variable declarations, functions, classes, statements. Class nodes further contain function nodes and variable nodes. Function nodes have sub-nodes with individual statements. An if statement has, for example, a condition sub-node and a body sub-node. Etc.

Lisp macros are effectively search and replace commands that detect a specific patterns in the AST and replace it with another pattern. Scheme, a variant of Lisp, extends that concept and introduces hygienic macros that elliminate potential for screw-ups due to name clashes.

What can these macros do? Two examples:

1. They can introduce new control structures. The C# foreach statement can easily be implemented using a macro.

2. They can do the AOP thing. Apply a macro to the whole file and it can detect functions and insert prologue and epilogue code.

And of course, you don’t need to think in terms of pattern substitution. Once you allow the users to hook into the compile process, you can let them write arbitrary routines for AST analysis and transformation.

Learning about another profession #2

There’s a good article on Kuro5hin about how car dealerships work in the U.S.

Learning about another profession

SlashDot has a fascinating interview with a Washington lobbyist Morgan Reed. Be sure to read the comments, too, as they are a magnitude more intelligent than the usual SlashDot chatter.

Why is IComparer an Interface?

Perhaps you are wondering why IComparer, which has only one method, Compare, is an interface and not a delegate? A delegate is much more versatile than an interface.

To answer that you need to look into one of .NET’s dirty little secrets, delegate invocation performance. Jan Gray from the Microsoft CLR Performance Team has writen a great article that contains a table showing how much various IL operations take. A virtual call on his box executes in 5.4 ns. A delegate invoke takes 41 ns. (For reference, an integer add operation takes 1 ns.)

So there you go. If .NET designers had created IComparer as a delegate and not an interface, the performance of methods like Array.Sort would suffer tremendously and they would get pummeled in the benchmarks.