Archive for category General

Lua and World of Warcraft

Ultimate Craft Queue add-on

A few people asked me what I was doing with Lua, so here it is: http://beust.com/ucq.

It’s a simple add-on called “Ultimate Craft Queue” that I wrote to help me craft glyphs. This will probably only mean something to WoW players, but in short, with some discipline, it’s possible to make a lot of money with this profession in WoW, but there are a lot of repeated operations involved in this process, so any automation you can come up with helps. This add-on is simply helping me streamline my process.

Back to Lua, I have to admit that the problems I described in my previous entry were pretty minor overall, and the hardest part of writing this add-on was the WoW Lua API itself, not the language. It is extremely powerful, if the number of add-ons in existence is any indication, but it takes quite a bit of effort to navigate through the scarce and sometimes nonexistent docs. The usage of extra libraries (such as AceGUI) is pretty much mandatory and there are quite a few holes (such as the tooltip API) that make a WoW add-on developer’s life absolutely miserable.

But once it works, it’s really rewarding…

Suffering in Lua

I have been writing a lot of Lua recently, and it hasn’t been a very pleasant experience.

The first thing that took a little while to get used to is the fact that table indices start at 1, not 0. Admittedly, it is possible to configure this, but the default is certainly confusing and I have been battling nil errors in tables that I knew couldn’t be empty.

But the worst was the following:

function f()
  print("f()")
end

f(2)

function f(n)
  print("f(n):" .. n)
end

This snippet will print "f()", indicating that when the interpreter read f(2) and couldn’t find a matching function (since it wasn’t defined yet), it decided to get rid of my parameter and call f() instead. And all this without any error or warning.

It doesn’t stop here:

function f(n)
  if n then print("f(n):" .. n)
  else print("f(nil)")
  end
end

f()

This will print… f(nil).

Here again, the interpreter couldn’t find a signature matching f() so it decided to pick f(n) and simply pass nil as parameter.

I am willing to suffer some discomfort when using a dynamically typed language, but this is really terrible and I dread the fact that it’s inevitably going to cause more bug hunting in the future….

A couple more things of interest:

  • Writing in Lua has confirmed me in my conviction that using end as a
    closing statement is really painful. Not only is it noise when I read a source but it just
    makes it impossible to match a closing end to its opening statement (you will also notice that
    there is not always such a thing: if requires a then but the declaration
    of functions doesn’t require anything). If you’re going to create a language, do me
    a favor and pick symmetric opening/closing tokens (or significant spacing, like Python).

  • Lua is doing something clever with its comment syntax, which I haven’t seen in any other
    languages: comment blocks are defined by --[[ and --]] but if you add
    a third hyphen on the opening part, then the commenting is disabled again:

      --[[
      This is commented out
      --]]
    
      ---[[
      ... but this is not
      --]]
      

    I like the practicality of this idea.

What I find disappointing is that Lua is a language that’s more recent than Python, so it’s hard to understand why it’s being so lackdaisical about signaling errors. Having said that, there is no question that Lua is alive and well and used increasingly more often as an embedded languages, especially in video games, so it’s most likely here to stay…

Oracle busy removing all traces of Sun from the Internet

Oracle is not kidding when they acquire a company, and Sun is no exception. They are actively replacing every single instance of “Sun” and Sun owned companies (such as MySQL) with “Oracle” everywhere.

Witness this post from Mark Matthews, which initially read (web archive link from 2006):

and which has now become:

Mark Matthews
Principal Software Developer – Enterprise Tools
Oracle

http://www.mysql.com/products/enterprise/monitor.html

In a few years, all traces of Sun will probably have been completely wiped off the Internet.

NoSQL explained correctly (finally)

Now here is a definition of “NoSQL” that I can agree with:

A very interesting write-up with one little oversight: you’re wrong.

I am part of a large program to write a NoSQL database for military applications. It’s not a backlash against paying Oracle (the DoD has a blanket license for Oracle installations) or a philosophical stance by the hippies in the defense arena; it’s the fact that RDBMSs are built in a different space in the CAP trades (see this article).

Google, Amazon, Facebook, and DARPA all recognized that when you scale systems large enough, you can never put enough iron in one place to get the job done (and you wouldn’t want to, to prevent a single point of failure). Once you accept that you have a distributed system, you need to give up consistency or availability, which the fundamental transactionality of traditional RDBMSs cannot abide. Based on the realization that something fundamentally different needed to be built, a lot of Very Smart People tackled the problem in a variety of different ways, making different trades along the way. Eventually, we all started getting together and trading ideas, and we realized that we needed some moniker to call all of these different databases that were not the traditional relational databases. The NoSQL name was coined more along the lines of “anything outside of the SQL part of the Venn diagram” rather than “opposed to SQL”.

The NoSQL databases are a pragmatic response to growing scale of databases and the falling prices of commodity hardware. It’s not a noble counterculture movement (although it does attract the sort that have a great deal of mental flexibility), it’s just a way to get business done cheaper.

This is a comment to this article.

The commenter is dead on. There is nothing (well, very little) wrong with SQL. It’s an old language, but it’s still the best language that we have today when we need to retrieve data stored in tables. Nothing comes even close. And as a matter of fact, NoSQL products have typically very crippled query functionalities compared to SQL.

This is not to say that NoSQL is useless, but as the commenter correctly points out, NoSQL is just an extension of the current model to meet certain specific needs.

I bet that in ten years from now, we will still have a majority of SQL based systems complemented by a small portion of NoSQL frameworks.

Battle of the fonts

I decided to revisit my choice of programming fonts recently, mostly inspired by this article.

After trying the various fonts in this article, I narrowed down my choices to Consolas and Inconsolata. Here is what they look like:

Consolas 12 Inconsolata 12
Inconsolata 13

They all look great in Eclipse. The Inconsolata font is freely available but Consolas is a bit more tricky to obtain on Mac since it’s a font created by Microsoft and usually shipped with Microsoft products.  Here are instructions how to install it on your Mac.

Any other suggestions for good programming fonts?

New blog

Those of you reading this on the web probably already noticed that I changed my blog. I upgraded from Movable Type 2 (yes, 2) to Wordpress.

My older blog is still available at the address http://beust.com/weblog2 and I made sure to update the RSS feeds and put in place all the mod_rewrite rules necessary to make this transition absolutely transparent to everyone, so hopefully, I didn’t lose anyone in the process.

Supporting unit testing natively in programming languages: follow-up

There were quite a few interesting comments on my previous entry about supporting unit tests directly inside a language, so I thought I’d address some of these observations.

Michael suggests to keep the unit tests near the method they test:

@Tests({
@Test(3, 4: 7),
@Test(-2, 0: -2)
})
public int add(int x, int y) { return x + y; }

My main hesitation about this approach is that the production code is now littered with test code, and even if you use an IDE that conveniently lets you fold these tests away, it’s still painful to read such code in non-IDE environments, such as web browsing, code reviews, terminal diff, etc… This is one of the reasons why I suggested to have the unit test section in one place.

There is also the problem that unit tests usually require more than just “parameters in, result out”: very often, you will need to initialize your objects or perform some arbitrary code to set things up.

Dan is worried about pulling test dependencies in your production code:

What about test-only dependencies? Your production code would depend on mock libraries, Hamcrest expressions, etc.

Yes, this is used to be my strongest argument when I was against the idea of mixing unit tests with code, but this objection disappears if you actually embed this functionality in the language. I argued in my post for a new keyword called unittest that would define a brand new section, so I don’t see why this section couldn’t include its own imports as well:

unittest {
import org.testng.Assert;
public void positiveNumbers() {
Sum sum = new Sum();
Assert.assertTrue(sum.add(3,4) == 7);
}
}

This code will only be compiled if the compiler is invoked with the option -unittest, and otherwise, it will be simply ignored.

Dan adds:

the main gotcha is standardizing on how to run unit tests

Exactly, and that’s my point: this aspect is very underestimated and it’s the reason why so much code is written every day without accompanying unit tests. If you move this functionality inside the language, you create a universal framework across all companies and all projects that make testing a very natural part of the coding process in that particular language.

When you receive a piece of code for review, you now expect the accompanying unit test to be part of that file.

A few people chimed in to advocate Maven, but regardless of my feelings toward this tool, Maven doesn’t solve the problem I’m trying to address here since it’s yet another tool that’s external to the language, which means that it won’t always be available wherever that language is used.

A reader called Mikew is using something similar to my suggestion in Java at his workplace. He and his teammates are using inner classes to put test code inside their production code, and it seems to be working for them, despite the downsides of such an approach. As I pointed out, a lot of these downsides would disappear if such a functionality was supported natively.

Python’s Doctest doesn’t seem very scalable to me, especially because it makes you write code in comments and that the scope of the tests that you can write is extremely limited, but I agree with the underlying intention.

Phil Goodwin brought Eiffel into this discussion:

This was an assertion framework, and so did not quite support the whole testing story. Nevertheless, it provides a substantial foundation for embedding test code into source.

Eiffel’s support for testing, and the whole idea of Design by Contract in general, has always struck me as a toy that only works in trivial cases. Eiffel supports preconditions, postconditions and invariants, but in my experience, these concepts only work for foundation and library classes (e.g. containers) but scale very poorly in the real world (good luck coming up with an invariant for a class that’s manipulating database records while managing transactions).

I wrote a lot of code in Eiffel a long time ago and I distinctly remember that writing either of these contracts became plain impossible very quickly.

Having said that, Eiffel is the only language (besides D) that I can think of that supports arbitrary blocks of code to be included in classes while having a special status attached to them (“this is test code”).

Overall, the concept of something similar to a unittest section in a programming language continues to be very appealing to me and I am betting that if a language supporting this feature emerges in the next few years, the overall quality of code written in that language will be significantly higher than what we are used to.

Solution to the gambling game

A few people answered correctly to my little challenge, but not everyone.

At first sight, the rules look pretty favorable to the player: half of the time, I lose my money, but the other half, I get back at least as much as I bet.

Or do I?

Well, no. If you look at the rules carefully, you realize that what you are getting back if the roll is over 50 is not as obvious as it looks. Take the 66-75 range: you get 1.5 times your money, but you need to remember that part of this is the original bet. So if you bet $1, rolling between 66 and 75 will only make you richer by $0.5 and not $1.5. And the same applies to the other rolls.

Your gain expectation therefore is:

-1*0.50 + 0.5*0.10 + 1*0.24 + 2*0.01 = -0.19

For every dollar you bet, you will lose 19 cents.

Here is a simulation in Ruby:

fortune = 0
max = 1000000
for i in 1..max do
n = (rand * 100).round
if (n < 50) then fortune = fortune - 1
elsif (n >= 50 && n <= 64) then fortune = fortune + 0
elsif (n >= 65 && n <= 75) then fortune = fortune + 0.5
elsif (n >= 76 && n <= 99) then fortune = fortune + 1
elsif (n == 100) then fortune = fortune + 2
else puts "#{i}: n:#{n}"
end
end
puts fortune

and the output:

$ ruby ~/t/game.rb
-184887.0

The mistake that a few commenters made (and which I made as well initially) was to have a few extra "ones" in their gain calculation.

Do you want to play a game?

You put down some money and you roll a die between 1 and 100. Depending on your roll:

  • 1-50: I keep your money.
  • 51-65: You get your money back.
  • 66-75: You get 1.5 times your money (if you bet $1, you get $1.50)
  • 76-99: You get 2 times your money
  • 100: You get 3 times your money

Do you want to play?

Update: here is the solution

Of Kindle and web usability

Jakob Nielsen wrote a good review of the Kindle usability. All his comments match my experience.

I haven’t been bothered too much by the shortcomings that Jakob found on the Kindle, probably because my expectations are low in the area of non-linear navigation and I’m fully aware of the current limitations of electrophoretic displays. Still, Amazon should take note of these comments and try to improve the overall UI experience for the next version.

Having said that, I still find Jakob Nielsen’s web site pretty ugly. Functional, yes, pleasant to read, no. Which is paradoxical for someone who takes web usability so seriously. The most offending aspect of his articles are the frequent bold face uses.

Here is an excerpt of Nielsen’s article:

To me, these highlighted words are like high-pitch screams in the middle of a soft-spoken speech. They make me feel like I’m opening a brand new book and finding random words highlighted in yellow marker. It’s not just distracting, it actually goes against my reading because my eyes can’t help being attracted toward the emphasized words despite all my efforts to force them to follow the natural flow of the text.

If you want to communicate some kind of synthesis of your articles to your readers, take the time to write a real conclusion (or introduction) instead of resorting to this lazy word highlighting.

Overall, Nielsen’s Kindle article is still reasonably readable compared to some of the other web defiling atrocities that he usually commits on his web site (take a look at the useit.com landing page to see a good example of a web page that is functional but ugly).

Another major web offender is, of course, Paul Graham, who persists writing his columns with a hard formatting at 70 columns. Check it out, he actually inserts <br> tags manually. It’s quite comical.

The problem with this is not just that it shows utter disrespect to your readers (try resizing your window horizontally or reading his articles on your iPhone) but that it shows that Graham just doesn’t understand the underpinnings of the presentation layer of the web. On the web, you are supposed to write the content, provide a default presentation (ideally specified in CSS) and then let the consumer of your text ultimately decide what it will look like.

That consumer can be a human on a big, medium or small screen. It can be an RSS feed or a phone with a twenty column display . You just can’t know ahead of time, which is why you should perform as little formatting (especially line formatting) in your text as possible. Paragraph breaks should be your only formatting instructions, and then you leave it up to your readers to interpret what these breaks mean and how they want them formatted.

The same remark applies to emails, by the way: you should not use the return key to end your lines. Just type your text continously and when you are done with your paragraph, type return twice. If you insist on providing your own formatting, people who read your email on, say, a phone, will see it completely mangled.