Archive Page 2

Installing clbuild

After frustration with using an older version of sbcl and using asdf-install, I decided to try clbuild.  clbuild is a shell script that allows me to keep my lisp environment updated.  It is a little different from asdf-install, because it does not download tarballs, it gets the source code directly from their respective source code repositories.

So, the first thing I did was to get clbuild itself.  For some reason, I did not have darcs installed, so I had to install that first on my Kubuntu laptop:

~$ sudo apt-get install darcs

After that, use darcs to get clbuild:

~$ darcs get http://common-lisp.net/project/clbuild/clbuild

Make clbuild executable:


~$ cd clbuild
~/clbuild$ chmod +x clbuild

As far as I can tell, you need to run clbuild from this directory. So, the next step is to do a system check:


~/clbuild$ ./clbulid check

Now, time to get an update to sbcl. With my system, sbcl is natively located in my bin directory:


~/clbuild$ which sbcl
/usr/bin/sbcl
~/clbuild$ sbcl --version
SBCL 1.0.18.debian

Now, using clbuild to download and compile the latest version of sbcl:


~/clbuild$ ./clbuild update sbcl
~/clbuild$ ./clbuild compile-implementation sbcl

After a long wait, an sbcl implementation was placed in ~/clbuild/target/bin. To run it, use clbuild again:


~/clbuild$ ./clbuild lisp
This is SBCL 1.0.38.5, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org&gt;.
*

So, clbuild is using the newest version, but my older implementation is still there. Next time, I will set up SLIME with Emacs to point to this new target.

Chromium Tricks for the Lazy Programmer

One of the cool time-saving features in Chromium (better known as Google Chrome) is the custom search engines. It’s not a new concept. Mozilla Firefox has similar capabilities, but it feels like a hassle sometimes. You have to physically select the custom search engine in a separate combo box, then enter your search terms. That takes up extra time with all that mouse action, especially for a lazy programmer like me. Chromium goes on step further. The address box has a secondary function as a search box. If you were to enter anything but a URL or a domain name in the box, Chromium treats it as a search term and uses the default search engine. Google is default on mine, but any search engine that uses HTTP GET query parameters can be used.

If I was not a programmer, I may use my default search engine to do general searching. But, when I want to search programming language documentation, I would normally have to add the programming language name as a search term.  Given that a lot of programming languages have fairly common words as their names (python, ruby, lisp), you may waste some brain cycles filtering.  Again, for a lazy programmer, I want my information correct as well as fast.

So Chromium allows me to create a custom search engine to query a specific web site. In my example, I will be using lispdoc to search Common Lisp documentation. First, you need to go to the site and examine how a query is done. For lispdoc, the query is very similar to Google. However, there is another time-saving feature in Chromium. If you performed a search on the target site, there is a good chance that Chromium has already added a custom search engine for you:

Manage Search Engines

Wicked awesome! For lispdoc, the Chromium recognized that I searched on that site and added an entry for me. I don’t think there was anything special the site did, but you can add a search engine on your own if Chromium did not detect it for some reason.  The only issue that I have with it is the keyword property that Chromium selected. It put the domain name as the keyword, but why is that important?

The keyword is how you tell Chromium that you want to use a custom search engine instead of the default. It’s almost like what you would do if you went to the search engine directly with one important difference. If I entered the keyword (currently “lispdoc.com”) in the address box, space bar, then tab key, Chromium selects the custom search engine matching that keyword:

Using custom search

Then, I can enter more search terms. Unlike Firefox, I do not need to stop typing to tell Chromium what I want. The mouse is not even involved. Perfect for the lazy programmer? Not just yet. Since the keyword defaulted to the domain name (“lispdoc.com”), it has two usability problems.  Since I visited lispdoc.com, the URL shows up in my browsing history and will probably be the first selection. So, a chance a mistake can occur.  The second problem is that the name is too long for a lazy programmer.

The solution to both problems is quite simple: change the keyword to something else.  For lispdoc.com entry, I would change the keyword to “cl” for “Common Lisp”, which makes it less characters, no ambiguity, and easy to remember. Now, I can search documentation very quickly now. I have specific searches for other popular sites and assign them to shorter keywords, also. Here are some examples:

Try it out and let me know what you think!

Trying Pylons

So, I was looking into trying some of the Python web frameworks this past weekend.  I originally started to look into Django and TurboGears, but after seeing nxsy’s comparison, I decided to try Pylons. My initial thought was that all three have similar goals, but have different approaches. A decent Pylons book by James Gardner is available online, too. You can also get the dead tree version at Amazon.

A second reason that I wanted to try Pylons is that there is a well-known, real-world application written using Pylons. I think its a good thing to see how someone else uses a framework that you are evaluating. I may not want to copy their style, but it gives me great insight.

Nested Map

I was in the #lisp chat room at Freenode when someone posed a question about performing a map function over a nested lists. This was an interesting problem, so I thought that I would cover it here.

Suppose there was a complex tree of numbers:

((1 2) (3 4))

And you want to map each to a function (let’s say a squaring function) and maintain its structure. This is where a good utility function would be in order. The function must be able to handle trees of an unknown structure. So, the only solution that I know would be to use recursion:

(defun nested-map (fn item)
    (cond ((null item) nil)
          ((atom item)   (funcall fn item))
          ((consp item) (cons (nested-map fn (car item))
                                 (nested-map fn (cdr item))))))

Even though it looks complex, the function seems correct:

CL-USER> (nested-map #'(lambda (x) (* x x))
           '((1 2) (3 4)))
((1 4) (9 16))
CL-USER> (nested-map #'(lambda (x) (* x x))
           '(1 2 (3 4 (5 6 7))))
(1 4 (9 16 (25 36 49)))

I think I’ll keep this in my utility toolkit. I am concerned about the performance, but I won’t worry too much about it until it becomes a problem.

Snow In Bay Area

So my first night in the Bay Area was relatively painless. The big story here is that it snowed in the valley areas. I guess it is not a common thing here, because the funniest thing was that news footage of some kids playing in a small patch of snow. I don’t know why it is funny to me, but those kids seem to enjoyed it. Given that there’s a snow storm brewing that is going to hit the Cleveland area when I fly in, I expect to be delayed.

Travelling Light

I’m getting ready to fly to San Francisco tomorrow on business. This- will be my first flight since January 2004 when my wife and I went to Las Vegas. Some recent changes to “airline policy” will irk me. For instance, the airlines started to charge for luggage, which I think is the most prominent example of nickel and diming your customers.

Since my trip is business, I am reimbursed, but it still sucks for someone. Luckily, I am only going to be in San Francisco for a few days, but it would be different if I was taking a trip for a vacation. If I was spending two weeks in California, I don’t think one bag would be enough. So, the thought of being charge $100 for luggage would literally drive me nuts.

Eh, so next time I travel for vacation, maybe I take a train.

Installed Kubuntu Today

For the longest time, I have always had a goal to be Windows-free. Many people I work with feel that it is pure apostasy, because I have worked in Microsoft shops in the past 10 years or so. But frankly, I am particularly sick of Windows as a whole. If I can still continue doing my work without having Windows on on my HP Pavillion dv9008nr laptop, then I think I am set.

So, I installed Kubuntu 9.04 (Juanty Jackalope) today. It was the most painless installation of Linux that I had… ever. It was even less painful that my initial installation of Ubuntu 8.10 (Intepid Ibex) on the family desktop (recently auto-updated to Jaunty).

My laptop wireless has the ever painful Broadcom chipset, which historically has been a problem on both 32-bit and 64-bit systems. But I found out that they got off their butts and started to provide drivers for Linux. So, after enabling the closed source drivers, my wireless just worked period. There was no manual configuration that I had to do, no driver to look for, and no searching through outdated documentation for clues on configuring everything.  Do you have any idea how refreshing that is?

Here are other refreshing things:

  • The NVidia chipset for graphics acceleration worked with zero configuration.
  • All of my external devices worked.
  • Even though I like the GNOME interface in Ubuntu, I absolutely love the KDE interface in Kubuntu.  I am ecstatic that I went in that direction.
  • BZFlag looks / feels much better on Linux that on Windows.
  • The best system for tools I already use on Windows: Pidgin, GNU Emacs, Steel Bank Common Lisp, Mozilla Firefox, and others.
  • Even Adobe Flash has decent performance, even though there is no 64-bit native version for Linux. Most YouTube videos do work, even in full screen mode. So, I can deal with it for now.  (Adobe is now the new Broadcom, IMO).
  • The default Remote Desktop (RDP) client allows me to connect to my Windows desktop at work, basically completing my minimum requirements for total conversion.

So, I look forward to writing more about my experiences on Kubuntu.