h1

A Rapid Language Tour

April 25, 2008

I’ve been in Japan for 4 weeks now and my time here is not going to waste… between Japanese classes, I’ve been flirting with ocaml, scala, c (I read the K&R book) and now Smalltalk (with Squeak). My casual language survey is coming to an end, with no more obvious omissions, I would think. (covered before: Haskell, Erlang, Scheme and Common Lisp … and this goes without mentioning the others I touched: Python, Perl, Ruby, C++, Java)

No language is perfect. Performance seems indirectly proportional to expressiveness. This is the intuitive answer … and sadly, the one I found experimentally.

I mentioned before my list of programming exercises I try once I get past the introductions and tutorials. Always working on the same problems really helps understand the idioms of a new language.

I tried to code Tower of Hanoi and “benchmark” the time it takes to execute them for a few languages.

Tower of Hanoi, 20 rings:
* Ruby: ~20 seconds
* C: ~1.2 seconds
* OCaml: ~5 seconds
* Scala: ~16 seconds
* Haskell: >2 minutes … stopped it at that point

As for Smalltalk … this is a whole other story. The main motivation is Seaside, of course. Smalltalk is interesting in itself for many reasons:

  • You can see where Ruby got its inspiration
  • You can experience what object orientation really means
  • You can try “crazy” stuff like switching the garbage collector on the fly …
  • You can experience the-language-is-the-environment-is-the-IDE, which seems like both a blessing and a curse

I’m trying to get to the point where I can write a few webapps in Seaside and see if my whole world is transformed. If you want to understand “why Seaside”, you can watch The Heretic Web Framework - Seaside. The idea of continuations and the idea of assigning code blocks to hyperlinks (instead of named goto: URLs) are definitely something worth investigating.

It doesn’t mean that Smalltalk is a destination… it’s just one of the stops along the way.

h1

Fortune 5,000,000

April 22, 2008

Between DDH Talk – Startup School 2008 and The 4-Hour Workweek, a few common ideas are emerging: start small, do just enough to live, enjoy life. :)

The weird thing about success is that you can tell people exactly how to achieve it and they still won’t. It’s the reason why people like Tim Ferris can sell you his book without worrying about everybody doing the same. It’s also the reason great chefs can publish their recipes without being afraid of going out of business.

Are you going through the motions?

h1

Sinatra: The Simplest Thing that Could Possibly Work

March 5, 2008

This all started with me not wanting to install ImageMagick… Or, going back further, me being fed up with all the CSS and JavaScript drop shadow hacks which all had pros and cons…

I just got fed up with trying to find a simple and clean way to do drop shadows. I decided I would just create a new image, using ImageMagick, with the drop shadow embedded. However, doing the “whole” ImageMagick install thing, on multiple machines, wasn’t exactly my idea of fun.

That’s when the initial idea of providing ImageMagick services as a web service came up. It would be RESTful, you would POST your PNG/JPG file to a URL and the response would contain a PNG (…because of the transparency…) modified to include a drop shadow. Great!

To complete a proof of concept, however, I would have to install ImageMagick… which brings me to… abandoning this whole idea!

Let’s do something much simpler instead.

Problem statement: “What do you need, end to end, to send a file to a “RESTful” web service and have a modified version of it returned?”

Let’s do the simplest possible thing, upload a file and have its sorted content returned.

My initial test involved creating a new Rails application.

Here’s what I did, roughly:
* I created a new Rails app
* I skipped database configuration (what database, anyway?!)
* I generated a new controller
* I wrote the “create” function
* I enabled “map.resources”

Then I learned how to turn off the authenticity token (of course!).

Here’s how you POST a file, from the command-line:


curl -F "data=@filename" $IP:$PORT/$path

Where “filename” is the name of the file you want to upload. The binary data goes into the “data” key.

This worked … but it felt like taking out the limousine to drive to the mailbox.

This is when Sinatra comes into play.

I googled around trying to find a WEBrick tutorial. I got WEBrick to do what I want, but it didn’t feel very satisfying. I started to look for what else was out there. Rack had a nice list under “Supported Adapters”. I gave each one a quick look but was amazed at Sinatra. In my mind, it doesn’t get any simpler than what it does.

Here’s an example from their site:


require 'rubygems'
require 'sinatra'

get '/' do
  "Now that's a fine looking dame!"
end

You just mapped http://127.0.0.1:4567/ to return that string! How can you reduce that further?!

Here’s my “sorter” web service:


require 'rubygems'
require 'sinatra'

post '/sorter' do
  params[:data][:tempfile].readlines.sort
end

This all boils down to using the right tool for the job.

Now I just need to decide what I’m going to do about those pesky drop shadows.

h1

Inconsistent Whitespace

February 26, 2008

Today, let’s talk about one of my favorite pet peeve: inconsistent whitespace.

For the sake of this discussion, I’ll divide whitespace into the following categories:

  • newlines
  • tabs
  • end of line whitespace

Newlines

Simply: this is about what character(s) represent the end of a line.

This is a classic! Historically, I would love to know how much time has been wasted on this. Command-line utilities have been built to address this problem. Editors had to accommodate this. Tools had to work around this. Before Mac OS X, we even used to have 3 flavors of end-of-lines ( newline representations and more )!

I could argue that for the sake of future generations, we should agree on one style, preferably line feed. However, tools have gotten better at dealing with this. The problem is tools that aren’t so good at dealing with “foreign” newlines!

Since I cannot impose my will, let’s just agree to be consistent … all the files in your project should be in the same style.

Tabs

Quick: how many spaces is equivalent to a tab character? 2,3,4 … 8?

( tabs in programming )

Maybe it’s even more complicated… Maybe it means something like “advance the cursor to the next such and such column (multiple of 8).”

Pro-tab people argue that a single tab character is always less characters in the saved file. This serves as a primitive type of compression, to be sure. Nobody can agree on how many spaces a tab character is, whereas everybody agrees how many spaces a space is (1!). The choice seems obvious.

Once again, this problem could be bearable if text editors were consistent, within the same file! Eclipse, for example, will gladly insert spaces, or tabs, depending on what you typed to indent your line at the specific moment. Another “gem” includes opening a tab-indented file and using space-indented lines for new lines (or vice versa).

This is classic “but it works on my machine” reasoning. You know what works on all machines, all the time? … Spaces!

End of Line Whitespace

This one is more of a personal one.

What happens in your text editor when you type a line of code and press a few whitespaces before pressing return?

That’s right … those “precious” whitespaces are kept, invisibly, for you, at the end of the line.

This makes it harder to rework the text later: pressing delete on that line will bring the next line, after the useless whitespace. Incidentally, that depends of what text editor you use.

I’m not going to recommend you constantly monitor your typing and avoid pressing the spacebar at the end of a line… This is more of a tool issue— why do text editors do that? Is there any language/purpose where invisible end of line whitespace is meaningful (as opposed to ignored)?

I use spacehi in Vim and I love to open other people’s files and see how much rework has gone through a file. End of line whitespace is like the secret history of your files!

Recommendations

You can use whichever text editor you want… really!

However, may I respectfully ask you to learn more about the tool you’re using. If a carpenter didn’t know what the claw part of his hammer did ( claw hammer ) and tentatively explained that he didn’t look it up, or never intended on using it, you would be justified in drawing your own conclusions.

In the light of the above text, here are my recommendations:

  • agree on newline character, within your team
  • turn off newline conversion in your favorite version control tool
  • have your text editor substitute all tabs for spaces

In vim, this is done with these settings: (feel free to replace 2 with your favorite number—and, yes, this is a whole other discussion)


set expand tab
set shiftwidth=2
set tabstop=2
  • have your text editor substitute all tabs for space, in existing files

In vim: (using the above settings)


:retab
  • if you want to purge end-of-line whitespace the regular expression /s+$/ will help

In vim, I use:


nmap _$ :% s_s+$__g <CR>
vmap _$ :  s_s+$__g <CR>
  • in vim, there’s a plugin called spacehi that will highlight all kinds of whitespace infractions
  • do whitespace-only commits, this will help greatly in diff-ing revisions if you know all changes from a specific revision to the next are cosmetic only

Remember my parallel with the carpenter above, and use Google.

h1

Explaining Refactoring to Non-Technical People

December 14, 2007

Does this sound familiar?

programmer:
“We need to refactor this code…”
manager:
“Why?”
programmer:
“It’s horrible unmaintainable code!”
manager:
“But it works!”

From the outside, the idea of “clean” code or “dirty” code doesn’t make much sense. Code seems to be an entity with a binary quality: works/doesn’t work. Bugs might appear more similar to dust needing to be wiped from a surface rather than loosening duct tape that is barely holding everything together.

I’d like to propose a new way to communicate the multiple whys of refactoring to non-technical people.

Wikipedia describes a Rube Goldberg machine as:

… an exceedingly complex apparatus that performs a very simple task in a very indirect and convoluted way.

Something like that:

When requirements change and programmers start cringing it might be because they know that something simple like “make the light turn on faster” might require adjusting the size of the marble rolling down a slide or changing the color of the cat that gets scared in the process of a balloon popping.

John Panzer said:

Software Development is a knowledge acquisition activity, not a manufacturing activity.

Developing software involves some level of experimentation. During the course of development, programmers understand more and more about the problem they are trying to solve. Unfortunately, the first working solution they might put together will very rarely be the most straightforward or the most elegant.

Alan Perlis said:

Simplicity does not precede complexity but follows it.

The Rube Goldberg machines of software exists because the scaffolding of an application might work very similarly to the finished application.

There is a difference between “is it working?” and “is it done?”. That difference might well in the “how”.

Caveat: There are plenty of reasons not to refactor whether economical or otherwise. However, changes to an existing code base usually takes much longer than expected because of its not uncommon Goldbergish qualities.

h1

$50

December 11, 2007

Last night, I stopped by the ATM and withdrew a large amount of money (I don’t especially like to visit the ATM, I usually “batch” my withdrawal needs). I cringed when the ATM’s slot opened and $50 bills appeared. $50 bills are weird beasts … they are technically legal currency, however, they are always treated like fake money.

This, of course, wasn’t the first time it happened to me. I tried to figure out what large dollar amount would not trigger the lets_dump_fifties(…) function, but, as far as I can understand the ATM software, it will dispense according to something like:

(desired_amount is divisible by 20, it goes without saying)


bills[50] = (desired_amount / 100) * 2
bills[20] = (desired_amount - bills[50] * 50) / 20

The problem, once you have the undesired bills, is how to get rid of them.I tried to share my amusement-pain with a clerk at Indigo:

me: (takes out and hands over a $50 bill)
clerk: (cringing face, goes through the step of verifying it)
me: "you know ... a real $50 really feels like a fake $50 ..."
clerk: (uncomfortable/nervous) "what do you mean?"
me: "well … they are treated the SAME"

And that is just with places that even bother taking $50 bills. Try to purchase something that’s $2 with one and you’ll see how well it gets received.

At the other end of the spectrum there are coins. And the same problem exists. Here’s an interesting section from Wikipedia:

Legal tender of Canadian coinage is governed by the Currency Act which sets out limits of:
40 dollars if the denomination is 2 dollars or greater but does not exceed 10 dollars;
25 dollars if the denomination is 1 dollar;
10 dollars if the denomination is 10 cents or greater but less than 1 dollar;
5 dollars if the denomination is 5 cents;
25 cents if the denomination is 1 cent.
Retailers in Canada may refuse bank notes without breaking the law. According to legal guidelines, the method of payment has to be mutually agreed upon by the parties involved with the transactions. For example, convenience stores may refuse $100 bank notes if they feel that would put them at risk of being counterfeit victims; however, official policy suggests that the retailers should evaluate the impact of that approach. In the case that no mutually acceptable form of payment can be found for the tender, the parties involved should seek legal advice.

Time to start making repeated $80 withdrawals.

h1

Like Slime, for Vim

October 3, 2007

I started reading Practical Common Lisp yesterday. No discussion about Lisp can be complete without talking about Slime. Slime basically turns Emacs into an IDE for Lisp development. Peter Siebel thinks this is important enough to dedicate the second chapter to it. He even repackaged Lisp + Emacs + Slime as Lispbox to help people get started faster. For an excellent book (so far), available for free, and Lispbox, thank you Mr.Siebel.

After actually downloading, installing, and running Lispbox, I can see the advantages. Slime solves the problems you would have with any interactive REPL-type environment.

Let’s take Ruby’s irb as an example more people are going to relate to:

  1. you start irb
  2. you start a text editor (vim, textmate, emacs, …)
  3. you do a few tests in irb
  4. you copy and paste to a text editor
  5. you clean things up in the text editor
  6. you copy and paste back to irb
  7. you make a mistake
  8. you fix things up in the text editor
  9. you hesitate copying and pasting, because it’s painful now
  10. you write some tests
  11. you exit irb and run the tests to do your experiments

Let me present the dilemma another way: irb is great to get answers quick but it is also temporary because you know nothing you do in irb will be saved. However, the moment you start living in a text editor, you give up a lot of the power of REPL. Or, at least, your REPL becomes 10 seconds instead of 1 second. That changes the way you work. And that explains why Slime exists.

Slime creates a new interactive session with Lisp and you are able to copy and paste text from a text buffer to the session with one keyboard shortcut. That’s great! Now you can type, organize, pretty-print your code in a text editor, type C-c C-c to “refresh” the interactive session. This does not close and create a new session, the function definitions are reloaded into the current session. So, all your testing objects, those carefully crafted lists and hashes of objects (or whatnots) still exist—the world just changed around them.

Yeah, Slime is great. I’m just not an Emacs fan.

I did some research and Vim has no mode to support asynchronous sessions like Emacs. In essence, all that’s needed is a software that will spawn what you really want to run, say irb, control stdin/stdout/stderr, capture its own stdin/stdout/stderr and tunnel those to the child process. Also, it would be nice if it could open a port to receive external commands to be able to script stdin…

That’s when I remembered an article I read about scripting gnu-screen. To make a long story short, screen does everything we want, and more.

Here’s what we want to accomplish:

  1. start a named screen
  2. name the screen window
  3. start irb
  4. start another terminal
  5. start vim
  6. define a function/class/object
  7. have it “transported” to irb

Here are the instructions:

  1. screen -S session01
  2. C-a A—window01
  3. irb
  1. vim
  2. (type code)
  3. vip (select paragraph)
  4. “ry (copy to register r)
  5. :call system(“screen -S session01 -p window01 -X stuff ’” . @r . ”’” ;)

And BLAM, you just did some magic!

At this point, you are coming to 2 realizations:

  • this is WAY cool
  • you want this automated

Thankfully, I can help with the automation. Get slime.vim and put it in ~/.vim/plugin/ .

A few notes:

  • the magic key is C-c C-c (like Slime, surprise!)
  • the first time, you’ll be prompted for the “session name” and the “window name”
  • subsequent times will be automated
  • you can reprompt for “session name” and “window name” with C-c v
  • by default, C-c C-c will select the current paragraph and copy-paste it
  • but you can make your own selection first, and send it over with C-c C-c

As a final note, I’d like to drive the point that this can automate ANYTHING running in a screen:

  • bash
  • top
  • irb
  • python
  • any lisp/scheme REPL
  • mysql

One thing is for sure, this will definitely change the way I work.

(For extra points, write your own Textmate plugin … this hack is not limited to Vim!!)

h1

999_999_999

September 27, 2007

The puzzle came first:

puzzle

The answer followed:

answer

Don’t click on the answer if you don’t want it spoiled. You have been warned.

I don’t believe that posting the answer ruins anything. Nobody else can claim this as their own because they would still have to explain how they achieved this result.

Believe me when I say that I can go into excruciating details. :)

Also, in my case, it was an excellent way to practice Erlang. Nothing beats solving a “real” problem to imprint a programming language in your head.

h1

7998 Romans

September 18, 2007

Daniel and I were discussing how to test candidates before hiring them. You can push the requirements further when the candidates get a “take-home” test. So, what would such a test look like?

It must be easy enough so that the candidates don’t discourage. However, it must be challenging enough to test their problem solving skills and be able to produce some code we can discuss. Ideally, I’d like to see a code portfolio: a set of interesting problems and accompanying solutions. My take is that the following problem will be able showcase the attributes I’m looking for:

  • ability to research
  • flexible solution
  • good coding style

Given a file with roman numbers and their integer values in the following format:

487 -> CDLXXXVII
1442 -> MCDXLII
MCCXCVII -> 1297
211 -> CCXI
MCLXIV -> 1164

Find the lines where the roman and integer values don’t match. How many lines are there? Which ones?

h1

The Mac Mini and the Soldering Iron

September 12, 2007

I had been planning to buy a Mac Mini for a while now. I wanted to turn it into a web application server. I was going to install Gentoo on it and drop it somewhere/anywhwere in the house. These plans came to fruition 3 weeks ago when I dropped by the Apple store.

I took my time and configured everything just the way I like it. I rebooted it a few times to check that all services just started by themselves. When I brought it to the living room and pressed the ON button, I sat back in the couch and kept an eye on a “ping” to see how long it would take to boot up. The ping never was answered.

I brought the monitor and the keyboard to the living room (read: hassle) and booted the Mini. It booted without problems. I took out the keyboard and rebooted: no problem. I took out the screen and rebooted: no dice.

I knew the answer before google came back: the Mac Mini was never designed to run headless—the firmware wants a monitor.

This is not for the faith of heart but I found a few links with the same solution: a VGA dummy.

I resisted the idea at first, I knew my soldering skills were not excellent. I had never understood the explanations from the books I had read. I recruited youtube on this one, here are the good videos I found:

“how to solder”

How did we ever get anything done before the Internet?

The soldering itself is a long story: wrong solder, bad soldering iron, soldering cup technique and all. I managed to get it done, however.

Then came the moment of truth. I held my breath and closed my eyes and pressed ON again. Imagine the sweat rolling down my face as I waited to see if it would burst into flames OR have ping print “64 bytes from 192.168.0.112: icmp_seq=141 ttl=64 time=1.255 ms”.

Yes, it worked.