Foognostic blogs Seeking knowledge of foo

14Jun/09Off

Put that for loop down

Standard disclaimer: Clojure is a new hobby.

I've been spending a lot of time with Clojure recently to prepare for the ICFP 2009 contest. It hasn't been the easiest thing, but the difficulty has come from trying to grasp many new concepts at once. The documentation has been pretty good, and the IRC channel has been pretty worthwhile.

I'm trying to settle on a specific task to accomplish when learning a new language. Something concrete but still a little academic... implementing cosine similarity using character bigrams isn't much code, but it covers enough bases to be useful.

Part of the process involves splitting a string into overlapping character pairs.

Bad old me instinctively thinks "for loop".

Good new me thinks... bad old me probably has it right. But it doesn't feel very Clojure-y. This solution is a little more Clojuriffic, probably still a long shot from idiomatic:

(defn split-bigrams [text]
  (map
    (fn [l r] (str l r))
    (seq text)
    (rest (seq text))))

Bad old me (BOM) would have iterated over the string using a for loop with an index variable, cycling length - 1 times.

Good new me (GNM) had to take a different approach. I converted the string into two sequences; the first was just the string, but the second was the string minus the first character.

sequence A : [A B C D E F]
sequence A': [B C D E F]

The (map) function takes a callback and a number of sequences. The callback function gets the nth element from each sequence, and the output from the callback is collected and returned by (map). I don't have to specify a length or repetition count, as (map) stops processing when any of the collections run out of data.

user=> (split-bigrams "ABCDEF")    
("AB" "BC" "CD" "DE" "EF")

This hasn't taken a lot of time, but more than I like. It has taken A LOT of patience, energy, and focus during that time. But I like finding new ways to solve problems. Now I have a new tool in my nerdbelt, one that pushes the for loop back a little bit.

Filed under: clojure, code, lisp Comments Off
Comments (0) Trackbacks (0)

Sorry, the comment form is closed at this time.

Trackbacks are disabled.

Foognostic blogs is Digg proof thanks to caching by WP Super Cache