Archive for the ‘Shorties’ Category


Just for fun: map as ‘higher-order function’ in bash

March 8, 2008

Defined recursively, of course:

map () { 
  if [ $# -le 1 ]; then 
    local f=$1 
    local x=$2 
    shift 2 
    local xs=$@ 

    $f $x 

    map "$f" $xs 

I’m not going to explain everything, but note the ‘local’ commands to keep everything in function scope (to prevent strange bugs) and the quotes around $f in the recursive call to prevent a ‘function call’ of multiple words from being split.

Now you can do some completely nonsensical things, for which you really don’t need map, such as:

$ map touch aap noot mies

But also slightly more useful things such as

$ map "echo foo" aap noot mies 
foo aap 
foo noot 
foo mies 

$ map "echo file:" `ls` 
file: aap 
file: noot 
file: mies

To open up some more possibilities, I also defined a ‘rota’ function, with rotates the arguments of a command such that the last comes first.

rota () { 
  local f=$1 
  local args=($@) 
  local idx=$(($#-1)) 
  local last=${args[$idx]} 

  $f $last ${args[@]} 

I’m using a array (yes, bash has arrays) to easily get the last element, as you can see 😉

So, how about…

$ map "rota mv /tmp" aap noot mies

(Move the aap, noot and mies file to /tmp)

There are probably better (and more useful) examples of it’s usage, but you hopefully get the gist of it.

This code is just for fun (I don’t expect I’m ever going to use it, even), so it’s nowhere near being robust. There are a lot of (possible) bugs concerning spaces and undetected grouping of words (with double quotes). Use at your own risk 😉


Ruby and elegance: Transpose

March 10, 2007

I recently found that the Array class of Ruby has a zip method, which works much like Haskell’s zip function, except that it allows multiple arguments.

For example:

$ irb --simple-prompt
>> [1,2,3].zip [4,5,6], [7,8,9]
=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

The night after I did this little experiment I suddenly realized: this is a transpose function! I quickly got out of bed to document my little discovery:

def transpose(matrix)
matrix[0].zip *matrix[1..-1]

It’s the little things that make me like this language so much.

Update: I forgot the asterisk before matrix[1..-1] in the above method.


Summing it up

February 24, 2007

Today, I had a list of integers, and I wanted to sum it up. I guessed that I should write a script in Ruby, to make sure it would get done within 2 minutes. So I fired up my editor, and wrote the following script:

sum = 0 ;
$stdin.each do |line|
puts sum

Pretty straightforward. I’d rather had written the script in Haskell, but I figured I needed to get things done. This evening I tried the same thing in Haskell, but to I was surprised: it was even quicker and more straightforward than the Ruby version! Here it is:

main = interact $ show . sum . map read . lines

If you’d like more of these tiny tools, see Haskell Unix Tools.



January 7, 2007

Quite some time ago, when the sky of the internet was still blue, people didn’t have blogs and Wikipedia, but used so-called newsgroups to communicate and learn. Those newsgroups got lots of questions asked over and over again, so they started compiling a list of them, posting it each month, and naming it, appropriately, Frequently Asked Questions.

These days, the three-letter acronym is used mostly for documents that are a convenient way out of writing real documentation or structuring information on a website. There’s nothing wrong with that, but the difference with the original FAQ is that most of the time, the questions answered are never really asked.

Obviously, this kind of language polution is not the way to go. And because I have a big hole in my language ozon layer I got just annoyed enough to go and think of solution for this misbehavior.

Because I’m a realistic kind of guy, I don’t expect the whole word to use my made-up acronym to rebrand their FAQs. So I thought of something clever: find another group of words that discribe what’s really going on with the same acronym!

I’ve got three favorites, pick yours and hopefully you’ll think of it the next time you see ‘FAQ’:

  • Firmly Anticipated Questions
  • Fabricated Answered Questions
  • Fictionally Asked Questions

Breaking up

December 17, 2006

Sometimes you’ll have a project that’s starting to become very big. You’ll have a lot of actions attached to it, and the first five could all be the next action. My advice is to break them up into smaller projects. Sometimes the actions can literally be the projects’ names.

In my experience, you’ve got problem when the “big” actions aren’t physical anymore. As soon as you start to write something like “Get a hotel” on your action list, you’re screwed. But fortunately, the solution is easy, just make a new project and think of the necessary actions to complete it.

You’ll have a lot more projects if you do refactoring and planning like this, but you’ll get used to that. The big difference is that you’ve decided on the very next physical action, instead of having a blob of actions hidden in that one “action”.