Sunday, July 8

$12 USB Pedals = Excellent

Spending many many hours in front of the computer, both for work and leisure; I've invested heavily in setting up the best human-computer interface I could. Even tiny improvements in productivity add up quickly when multiplied by the hours/month/years I'll be able to take advantage of them.

In that spirit I don't shy away from tools or systems that have steep learning curves if I believe they offer some efficiency improvement once mastered. This has pushed me towards things like Linux, the dvorak key layout, GNU Emacs, and the Kinesis keyboard.

[Here is a picture of my desk at work. I've attached a large touchpad to the top of my keyboard so I can put the entire keyboard in my lap and not have to move my arms to use the mouse.]

Obviously having the above sitting on your desk at your office, makes you stick out a little (especially in conformist Japan). During one discussion with a coworker I was joking that the Kinesis even offers an optional foot pedal for those interested.

Now at least the old Kinesis foot pedals simply generated a key press to help with something like holding down the shift key to reduce strain on your hands or arms. Thinking further though, I wondered if someone hadn't come out with a generic USB foot pedal that could do something more.

While still chatting with my coworkers a quick search turned up exactly what I was looking for. Amazon now sells a $12 USB foot pedal!

Some Googling around quickly determined that these pedals have some driver software that's leaves you a little wanting, but which updates the hardware so it knows which key press to transmit when stepped on. A number of issues here, yada yada yada; but the hardware will connect to anything using the USB HID keyboard driver!

I didn't want to mess with the hardware, but I figured if it used a standard USB keyboard driver then I could code something up and make it do whatever I so desired ($ sudo make me a sandwich).

Talking to a friend about my idea, he later pointed me to Aleksandr Levchuk's VIM Clutch which was the exact kind of thing I wanted to do. Still wanting a bit more flexibility to define pedal actions, and to prevent burning myself while soldering; I just tossed together a tiny ruby script/driver to handle the pedal.

Now after getting everything working, using ruby and libusb; I've re-created the VIM clutch in software using the xautomation package. You can drop in your own onpress and onrelease functions though to enable the above script and $12 pedal to do anything you want.

I still haven't decided how to best use my new pedal yet, but here are a few ideas;

  • Play/Pause for music
  • Meta-key for Emacs
  • Bring my chat window to center screen when pressed, then return when released
  • Record keyboard macro for Emacs while held down, playback macro when pressed quickly.
  • Next tab in Firefox
One of the nice things of implementing the driver in Ruby, is that I can easily have it do all of the above just by detected what my active window is.

Anyways, hope this helps!

Tips & Tricks with Clojure Reducers

After noticing a few others encounter the same issues I ran into when first playing with Clojure's reducers, I thought I should collect some of what I discovered into a quick blog post.

First off, reducers are *AWESOME* and fully realize the power of parallel sequences but as they are still alpha have a few rough edges to work around. I'm sure in the near future it will become much more polished but until then be aware of the follow.

Note, clojure.core.reducers will be abbreviated as "r" below;

  • In many cases r/map and r/reduce are faster than their core counterparts, but not in all cases. At this point in time I only use the r/ variants for larger collections (> 1000 elements) and that has worked well.
  • The parallel part of reducers doesn't kick in until you use r/fold instead of reduce. For r/fold to be faster than r/reduce though, it needs to be able to "divide-n-conquer", and hence needs to be able to quickly divide up the collection.
    Summary: r/fold is only faster than r/reduce when operating on a vector.
  • (into [] (r/map inc (vec (range 10)))) works, but uses r/reduce instead of r/fold.
    Instead it's faster to use the following to take advantage of fold;

    (fold-into-vec (r/map inc (vec (range 2000))))
  • Reducing into map is many times slower than reducing into a single value or vector. Unfortunately merge and merge-with become the bottlenecks here, and this is the biggest rock in my sandal at the moment. :(
  • Don't forget mapv, which was introduced in Clojure 1.4 I believe. It provides a nice middle ground between core/map and core.reducers/map.

The function I'd specifically like to tune further with reducers is the following;

Wednesday, July 4

Datomic with examples in Clojure

So for some quick background, Rich Hickey the inventor of Clojure created yet another NoSQL database called Datomic. I was quite skeptical at it's release with the plethora of other NoSQL solutions available, but was converted by a simple question asked during Clojure Conj West. 

"What is faster, a local spinning disk or an SSD connected via a fat pipe?"

Hearing this I suddenly realized that the significant changes that have occurred with large memory, many locally connected machines, and SSD's really have changed the game and that a re-architecture of databases was called for. 

For more details on that topic, I high recommend starting with Jay Kreps blog post here.

Anyways, Datomic's idea of moving much of the read-only query work to the client, and abstracting away data storage, is very attractive. Loads more details here.

Finally jumping in to Datomic, after I started playing with working sets many times larger than available RAM; I ran into a couple issues that I thought I should mention to hopefully help any other "datomic clojure intro howto" googlers.
  1. Grab the latest greatest version of datamic from here.
  2. Second, unzip it and do;
    $ mvn install:install-file -DgroupId=com.datomic -DartifactId=datomic -Dfile=datomic-${VERSION}.jar -DpomFile=pom.xml

  3. Where ${VERSION} is the numbered version of datomic that you download.
  4. Check out some Clojure examples, and project, I extracted from official Datomic tutorial found here.Examples ->

Hope it helps ;)