Archive for the “programming” Category

Hacking Vim 7.2

A couple years ago, I wrote a brief review of the book Hacking Vim by Kim Schulz. The publisher, Packt publishing seemed to like my review so they sent me the second edition of the book, Hacking Vim 7.2 to review as well.

The latest edition of the book, released just earlier this year, has been revised and expanded to address some new features of Vim 7.2. The good thing about buying such a book is that Vim releases are infrequent and always backwards compatible. There’s very little chance of this book becoming redundant and outdated, unlike that Visual Basic 4 bible you have sitting on your shelf.

What is Vim?
For the uninitiated, Vim is an open source editor that has been used by programmers and developers for many years. Although it doesn’t look fancy, it is actually one of the most powerful pieces of software out there in terms of customizability and flexibility. However, unlike your basic text editor, it is difficulty to just jump in and start using it as there is a bit of a learning curve. This book is not for beginners, as it assumes an understanding of the basic editing modes of Vim. If you’ve never used Vim before, the book has a few suggestions on getting up to speed — most noticeably, by going through the vimtutor program that comes with most installations of Vim.

Topics Covered
The first part of the book gives a fairly complete history of the Vim lineage, from the original UNIX based ed editor to Vi, to it’s derivatives, and finally to the Vim we now know and love. Then the book dives right into basic personalization tweaks with an overview of the different configuration files — what they do and where they go. I consider these simple tweaks essential for any semi-serious user of Vim to create their own personalized .vimrc file.

For a lot of readers, the first two chapters may already been enough of a customization but the real meat of the book lies in the latter chapters, to help moderate users become power users with navigation tweaks, recipes to help with code completion and project management. If one follows all of these suggestions, Vim can turn into a full-fledged IDE.

With the sheer number of recipes and scripts, I would suggest implementing them a little at a time in order to get used to using them. Going through all the changes at once may be a bit overwhelming.

The last few chapters of the book teach take Vim customization to the next level by giving a tutorial on how to write your own scripts and configuration files. Most may not need to go into this much detail but if there is functionality that you can’t find a script for, then writing your own may be the only choice. The good news is Vim scripting is not too difficult, especially with the tutorial provided in this book, which is one of the reasons there is such a large community supporting it.

Recommendation
If you’re a user of Vim and would like to work more effectively and become a Vim guru, this book is definitely for you. If you’re already a Vim poweruser but feel there is some functionality lacking, this book is a great place to learn how to write your own Vim scripts to contribute to the Vim community.

If you’ve never used Vim before but would like to start using it, this book may not be your first choice; you may wish to try out Vim for a bit first to see if you actually enjoy the style of editing, and if so then pick up this book to go to the next level.

Popularity: unranked [?]

Comments 1 Comment »

I saw this piece of code mentioned on reddit and it absolutely blew my mind.  The code below is written in the Ruby programming language and when compiled, produces compilable Python code which is impressive in itself.  And when you compile the outputted Python code, it produces Perl code, which generates Lua code, which generates OCaml code, which generates Haskell code, which generates C code, which generates Java code, which generates Brainfuck code, which generates Whitespace code, which generates Unlambda code.  And as a finale, the Unlambda brings everything full circle and generates the original Ruby code!  Truly an amazing piece of work.

# ruby
l=92.chr;eval s="s=s.dump[r=1..-2].gsub(/("+l*4+"){4,}(?!\")/){|t|'\"+l*%d+\"'%(t
.size/2)};5.times{s=s.dump[r]};puts\"# python\\nprint(\\\"# perl\\\\nprint(\\\\\\
\"# lua"+l*4+"nprint("+l*7+"\"(* ocaml *)"+l*8+"nprint_endline"+l*15+"\"-- haskel
l"+l*16+"nimport Data.List;import Data.Bits;import Data.Char;main=putStrLn("+l*31
+"\"/* C */"+l*32+"n#include<stdio.h>"+l*32+"nint main(void){char*s[501]={"+l*31+
"\"++intercalate"+l*31+"\","+l*31+"\"(c(tail(init(show("+l*31+"\"/* Java */"+l*32
+"npublic class QuineRelay{public static void main(String[]a){String[]s={"+l*31+"
\"++intercalate"+l*31+"\","+l*31+"\"(c("+l*31+"\"brainfuck"+l*64+"n++++++++[>++++
<-]+++++++++>>++++++++++"+l*31+"\"++(concat(snd(mapAccumL h 2("+l*31+"\"110"+l*31
+"\"++g(length s)++"+l*31+"\"22111211100111112021111102011112120012"+l*31+"\"++co
ncatMap("+l*32+"c->let d=ord c in if d<11then"+l*31+"\"21002"+l*31+"\"else"+l*31+
"\"111"+l*31+"\"++g d++"+l*31+"\"22102"+l*31+"\")s++"+l*31+"\"2100211101012021122
2211211101000120211021120221102111000110120211202"+l*31+"\"))))))++"+l*31+"\","+l
*63+"\""+l*64+"n"+l*63+"\"};int i=0;for(;i<94;i++)System.out.print(s[i]);}}"+l*31
+"\")))))++"+l*31+"\",0};int i=0;for(;s[i];i++)printf("+l*63+"\"%s"+l*63+"\",s[i]
);puts("+l*63+"\""+l*63+"\");return 0;}"+l*31+"\");c s=map("+l*32+"s->"+l*31+"\""
+l*63+"\""+l*31+"\"++s++"+l*31+"\""+l*63+"\""+l*31+"\")(unfoldr t s);t[]=Nothing;
t s=Just(splitAt(if length s>w&&s!!w=='"+l*31+"\"'then 501else w)s);w=500;f 0=Not
hing;f x=Just((if x`mod`2>0then '0'else '1'),x`div`2);g x= reverse (unfoldr f x);
h p c=let d=ord c-48in(d,replicate(abs(p-d))(if d<p then '<'else '>')++"+l*31+"\"
."+l*31+"\");s="+l*31+"\"# ruby"+l*32+"n"+l*31+"\"++"+l*31+"\"l=92.chr;eval s=\"+
(z=l*31)+\"\\\"\"+s+z+\"\\\""+l*31+"\"++"+l*31+"\""+l*32+"n"+l*31+"\""+l*15+"\""+
l*7+"\")"+l*4+"n\\\\\\\")\\\")\"########### (c) Yusuke Endoh, 2009 ###########\n"

To properly try this, you’ll require the following versions of each compiler:

* ruby 1.8.7-p72
* Python 2.5.2
* perl v5.10.0
* Lua 5.0.3
* OCaml 3.10.2
* ghc-6.8.2
* gcc 4.3.2
* java "1.5.0_17"
* beef 0.0.6-2
* whitespace 0.3-2
* unlambda 2.0.0-5

Credit goes to Yusuke Endoh for this masterpiece of programming art.

Popularity: 1% [?]

Comments 5 Comments »

You’ve probably never heard of Eric Vasilik but his work affects millions on a daily basis.  He is a programmer and also the creator of the innerHTML element property.

The innerHTML element property is commonly used in Javascript (and therefore Ajax) scripts that so many sites use these days.  Basically anything on the web that is dynamicly updated without a page reload is probably using the innerHTML property to change content.

Web developers may know that using innerHTML on <table> elements does not work in Internet Explorer.  And the reason for this? Eric Vasilik didn’t implement it properly way back in IE3 when he was writing the parser for the DOM almost 12 years ago!

Yes he is the inventor of innerHTML but he is also the cause of a lot of modern headaches!  The funny thing is, his misimplementation came back to bite him in the butt 10 years later.

Luckily, the workaround for this problem is pretty simple but the morale of the story is: poor coding not only affects everyone, even you!

Popularity: 3% [?]

Comments 29 Comments »

Over the last week, Google has released a whole bunch of new features for Gmail to push it further into the lead in the race for the best web-based e-mail platform. The feature list includes:

  • Offline access to mail via Google Gears
  • Greater integration of labels (to encourage their use I presume)
  • Multiple inboxes — it’s only a matter of time until multiple accounts!
  • Brand new buttons!

Although the first three features are the most staggering, the one I’m most impressed with are the new buttons.  Not only are the beautiful in how they look, but they are beautiful in design.

Gmail Buttons

The designer, Doug Bowman, has a full breakdown of all the steps involved in designing and coding these buttons.  Remember, these buttons are not images but rather the intricate weaving of HTML, CSS, and Javascript into what can only be described as “art”.

Definitely worth a bookmark!

Popularity: 2% [?]

Comments 29 Comments »

Microsoft ZuneIf you haven’t heard, Microsoft recently had a huge fiasco involving almost ALL of their 30gb Zune’s (the Microsoft equivalent of an Apple iPod).  Two days ago on December 31, 2008, all of the 30gb versions of the Zune crashed simultaneously and would not turn back on.

There are frequent stories of iPods crashing and bricking but never of ALL of them crashing at the same time.  Given the proximity of the incident to the New Years, many suspected a bug with the date handling.  And as it turns out, that is exactly correct.

Taking a look at the source code, we find the following offending function:

BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
{
    int dayofweek, month, year;
    UINT8 *month_tab;

    dayofweek = GetDayOfWeek(days);

    year = ORIGINYEAR;

    while (days > 365)
    {
        if (IsLeapYear(year))
        {
            if (days > 366)
            {
                days -= 366;
                year += 1;
            }
        }
        else
        {
            days -= 365;
            year += 1;
        }
    }

    month_tab = (UINT8 *)((IsLeapYear(year))?
monthtable_leap : monthtable);

    for (month=0; month<12; month++)
    {
        if (days <= month_tab[month])
            break;
        days -= month_tab[month];
    }

    month += 1;

    lpTime->wDay = days;
    lpTime->wDayOfWeek = dayofweek;
    lpTime->wMonth = month;
    lpTime->wYear = year;

    return TRUE;
}

Anyone spot the bug?  Here’s a hint, it’s in the leap year handling:

while (days > 365)
{
    if (IsLeapYear(year))
    {
        if (days > 366)
        {
            days -= 366;
            year += 1;
        }
    }
    else
    {
        days -= 365;
        year += 1;
    }
}

The bug creeps up on the last day of a leap year (day 366).  The function goes into an infinite loop since the day 366 is too large to break out of the while loop but not large enough to execute the nested if statement.

This is why the Zunes crashed and were unable to boot up since this function gets called at boot up. The simplest way to fix this bug is to add an else clause to the nested if function to break out of the loop.

        if (days > 366)
        {
            days -= 366;
            year += 1;
        }
        else
        {
            break;
        }

The announced solution to this problem from Microsoft is to simply wait until the next day and the Zune works again… until the last day of the next leap year!  I’m not sure why this bug only affects the 30gb version since I would assume all versions of the Zune to use the same firmware.

Regardless, this is definitely a PR disaster for Microsoft and not one that I see them recovering from quickly.  They need to release a firmware update and get everyone to update (not an easy task).  Personally, I don’t own a Zune but I will no longer consider purchasing one.  I guess it’s going to be Apple products for me, even though I’m not Apple’s biggest fan.

Popularity: 3% [?]

Comments 33 Comments »