Clawk = Awk cut with Clojure

March 3rd, 2013

I know Clojure pretty well. I don’t know Awk quite as well and don’t need it quite enough to ever learn it deeply. I don’t want Perl either. I’d rather just write Clojure code for simple text processing. So, lately I’ve been using Clawk. It works for me. Bad idea, or worst idea? A tiny example:

$ echo -e "1\n2\n3\n" | clawk -r '(* $ $)'
1
4
9

clojure

Using a Wysiwyg Forms with Seesaw and Clojure

March 20th, 2012

At Clojure/West I mentioned that it was pretty easy to use forms built with wysiwyg UI editors seamlessly with Seesaw. I added an example and a section to the wiki that describes building a simple form with WindowBuilder in Eclipse. The basic principle should apply equally well to the ui tools in NetBeans and IntelliJ.

For someone that knows CounterClockwise well (that doesn’t describe me), I imagine the setup would be even more pleasant since changes to forms could be reused immediately from Clojure code without leaving Eclipse.

Finally, because everyone likes screenshots:

clojure, seesaw ,

Best of ClojureWest 2012

March 19th, 2012

I sat down to go over my Clojure/West notes and write some thoughts. An hour later, I had several long paragraphs and had only covered two talks. Clearly this process wasn’t going to scale. So I pondered a bit on how to express the awesomeness of Clojure/West without writing “War and Peace”. Based on a couple tweets I saw, I settled on a “Best of” approach.

Doing it this way is deeply shallow (?!) and silly. Hopefully, it’s also more fun than paragraphs of my incoherent ramblings on Datomic.

So, in rough chronological order, my “Best of Clojure/West 2012″:

All (most) of the slides for Clojure/West can be found on github. If you get “blob is too big” for a file, you’ll have to clone the repo and view locally :(

As a three-track conference, I missed at least 2/3 of the awesomeness of Clojure/West. What were your “Best of” moments?

clojure ,

Regenemies: A very simple game in Clojure

February 26th, 2012

Lately I’ve been working on several things in Clojure with the goal of getting a better handle on general app development as opposed to library dev. Working on Seesaw and other libraries is fun and an interesting challenge in API design, but wrapping up Java interop is quite different from building a functioning app.

Anyway, one of my little experiments is a game called Regenemies. A long time ago a friend and I had the idea for “regex invaders” where regular expressions fall down the screen and you have to type in matches for them to “kill” them as fast as you can. Well, I finally got around to it this weekend. The whole falling regex thing didn’t work that well, so I opted for just showing 1 or more expressions in a grid, each with a little countdown timer to tell you how long you’ve got.

The game itself isn’t really that fun. In fact, it’s a little stressful since every missed pattern is a strike against your skills as a programmer, and therefore, your worth as a human being. But it was a useful exercise in building up the game representation and defining state transitions in a mostly functional way.

The UI, which is rudimentary in the extreme, is currently implemented in Seesaw, but I will probably give porting it to ClojureScript and canvas a try.

The game is hosted via JavaWebStart here, the code’s on github, and here’s a screenshot since people like those:

Comment and criticism welcome, especially on the game state representation. Regex generation could also use a little more love as well.

clojure ,

ClojureScript One Execution Flow

January 28th, 2012

Last night I puzzled through the execution flow of the ClojureScript One sample app. I even took notes while I was doing it.

The results are here.

I have to say ClojureScript One is an impressive achievement. Someone should build “Clojure One” now :)

clojure ,

A Seesaw Tutorial

December 7th, 2011

It was recently pointed out to me that Seesaw’s “amazing and wonderful”, but not still not that friendly for developers with no background in Java or Swing. By coincidence, I was scheduled to give a talk on Seesaw at Ann Arbor’s CraftsmanGuild, so I took the opportunity to try to improve the situation.

I’m usually not a fan of slides, so I did the talk completely in the REPL. The result was, I think, a nice introduction that assumes no Java or Swing knowledge and shows off some of Seesaw’s cool high-level features.

You might want to view it in its native habitat since this dumb fixed-width layout will hide some of the text. Also, depending on your fonts, my lovingly crafted screenshots might look like crap. Sorry about that.

In any case, here it is. Feedback welcome and encouraged.

clojure, seesaw ,

VimClojure – Easy

October 12th, 2011

Update 1/2013: The future of Clojuring with Vim is tpope’s foreplay.vim. You can find a tutorial here.

I promise this is the last VimClojure post for a while.

I get the feeling that my post describing my VimClojure setup is a little too involved, especially for someone that just wants something working quickly. Also, from what I’ve seen on #clojure, there’s some frustration out there. With that in mind, I put together a minimal example configuration with instructions.

So, without further ado, vimclojure-easy.

Feedback welcome.

clojure, vim , ,

Familiar: Clojure plus Ruby

October 9th, 2011

Last week I had three separate conversations with people about using Clojure’s data structures and concurrency primitives from a language that’s not Clojure. Something about parens or insisting on using a less capable language :)

So, this weekend I played around with using Clojure from Ruby, in particular JRuby. I haven’t done much Ruby in about a year, so I spent most of my time remembering that. Anyway, I ended up with a proof of concept: Familiar. See the readme there. Here’s an example:

That’s it. This gives full access to the clojure.core API including lazy seqs, STM, and all those goodies. Good idea? Idiotic? I don’t know, but it was a fun exercise.

clojure, ruby , ,

Taming VimClojure 2.3.0

October 7th, 2011

Update 1/2013: The future of Clojuring with Vim is tpope’s foreplay.vim. You can find a tutorial here.

In honor of the release of VimClojure 2.3.0, I’ve updated my post on taming VimClojure. Thankfully, very little has changed in the setup. Cheers.

clojure, vim , ,

Clojure Update Literacy

October 4th, 2011

I want to write briefly (ok, not that briefly) about my understanding of Clojure‘s various “update” functions, in other words, functions that take a function argument, apply it to some value and do something with the result. These include swap!, alter, commute, send, send-off, alter-var-root, update-in, alter-meta!, vary-meta, and probably several more. From here on out, I’ll call a function in this family an update function and the function passed to it a transform function.

Note that update functions are most commonly encountered when using Clojure’s reference types, i.e. vars, refs, atoms, and agents. Their signatures are all very consistent:

    (<update-fn> old-state <tranform-fn> & args)
    ;=> new-state

That they’re so consistent is a testament to the thought that has gone into the design of Clojure’s core API.

Nonetheless, a newcomer to Clojure, overwhelmed by all the other new concepts they’re learning, might find update functions a little confusing. They might find themselves calling reset! a lot because swap! is scary. Of course, if the value passed to reset! (or ref-set) depends on the previous value of the ref, you’ve thrown away all the nice concurrency guarantees that atoms and refs are supposed to give you. For example, the prototypical id generator:

  ; BADBAD Don't do this!
  (defn id-generator []
    (let [id (atom 0)]
     (fn []
       (reset! id (inc @id)))))

No No No No No

Of course, everyone knows to use (swap! id inc) for a canonical example like this, but in the thick of a larger app, feeling like you’re in over your head, it’s easier to make mistakes.


So, learning to read (and write) an update function can take you a long way along the road toward writing more idiomatic Clojure. For someone with an OO background, it might be easier if we mentally re-wrote the signature above like this:

   state = transform_fn(state, arg0, arg1, ...);

that is, we’re applying some transformation to the current value of state and storing the value back in state. See, swap! and friends are just a function call in disguise. Their signatures are completely consistent with Clojure’s argument order conventions, but they slightly obscure what’s going on because the state and transform function are switched. This makes sense since state is the important argument, but it took me a little while to realize this and make the mental adjustment.

Once I reached this conclusion, I found writing in a functional style with state transitions much more straightforward.

Note that I find this a useful way to *read* update functions. It’s not a replacement for thinking hard about the semantics of the update function you’re using


Here are some general guidlines that I find helpful:

  • Always write pure functions that represent state transitions or transformations. They take in the current state and maybe some additional arguments and calculate a new state. This is obvious, but sometimes I have to keep repeating these things to myself. Kind of like in Tcl, “everything’s a string, everything’s a string, everything’s a string, …”
  • reset! (and its cousin ref-set) is for exactly what its name says: “reset this atom back to some initial state dammit!” Only use it if you’re resetting your app, or if the new value truly doesn’t depend on the old value. In the latter case, randomly generated values or user input come to mind.
  • Always give your transform functions a name. Passing an anonymous function to swap! means you just wrote a function that’s harder to test or experiment with at the repl. Besides, a descriptive name is more readable than most anonymous functions.
  • Limit the number of call sites for update functions in your app. A system that’s sprinkled liberally with (dosync) blocks and calls to swap! will be more difficult to reason about than one where the state transitions are localized.
  • Don’t forget the args! I’ve often fallen into the trap of passing an anonymous function when I needed to pass args to my state transition function.
  • Don’t forget that most things are functions and, therefore, candidates for transform functions!
        ; A contrived example
        (def signal (atom :red))
        (def transitions { :red :green, :green :yellow, :yellow :red })
        (swap! signal #(get transitions %)) ; <- NO
        (swap! signal transitions) ; <- YES
    

and finally, as a wise man once said “functions and data!”


In conclusion, I hope this sheds some light on an area of Clojure that I’ve personally found to require a great deal of mental deprogramming. As I’ve gained confidence with these concepts, my code has been easier to read, easier to test, and easier to reason about. Happy Clojuring.

clojure