Open Source Consultant, Software Developer and System Administrator

If you are interrested in hiring a consultant for the effective use of open source software on an enterprise grade, take a look around in the About section to see, what I have to offer.

Blog and snippets

Various snippets or code parts I found useful, so I keep them here for reference.

Groovy `each` - or why everything is a nail

With the aspiring groovyist there is a tendency to use each for everything. When coming from an imperative programming language you did all the heavy lifting with for, while, if, etc. so each gets adopted again for that style of programming. This at some point will end with the question: how to break out of an each. And the simple answer is: you can't (well, you shouldn').

In Groovy many things look like some basic instruction from the language, so each looks like some loop instruction from the Groovy language, right? [1,2,3].each{ println it }? Well actually each is just a method, that takes a clojure as param, for this list and Groovy allows you leave out parentheses in that case. Does this still look like something basic like for: [1,2,3].each({ println it }) ?

What does each do then? It runs a for loop and passes each element to your provided closure. Your return value is ignored. No break, no continue makes sense here. Actually return early in your closure provides continue behaviour. Also note, that the return value of the each method is the list itself.

So here are a few each anti-patterns:

each instead of a map:

// NO!
def results = []
[1,2,3].each{
        results << (it*it)
}
// YES!
def results = [1,3,4].collect{ it*it }

each instead of a filter:

// NO!
def results = []
[1,2,3].each{
        if (it>1) {
                results << it
        }
}
// YES!
def results = [1,2,3].findAll{ it>1 }

each to find first:

// NO, really NO!
def result
[1,2,3].each{
        if (it==2) {
                result = it
                break // does not work
        }
}
// YES!
def result = [1,2,3].find{ it==2 }

each instead of a reduce:

// NO!
def sum = 0
[1,2,3].each{
        sum += it
}
// YES
def sum = [1,2,3].sum()
// or as an actual reduce, if you prefer:
def sum = [1,2,3].inject(0) { r,it -> r += it }

So what when you really need the behaviour of for? Well it's not forbidden in groovy. Just use it, it's even faster than each.

Make the Figwheel REPL work in vim-fireplace

I just have created a pull request with Vim-Fireplace, that allows passing down an expression to :Piggieback. This allows using the Figwheel REPL without much hassle.

First follow the instructions to create a Figwheel project. E.g. lein new figwheel example-project. Check the generated project.clj file and remove the comment on the line, that sets the nREPL port (:nrepl-port 7888, pick any port number you like).

To make Vim-Fireplace pick up the nREPL port create an .nrepl-port file containing the port number. E.g. echo 7888 > .nrepl-port. Otherwise connect from the Vim command line with :Connect nrepl://localhost:7888 (or follow the dialog with just :Connect).

In Vim then open any ClojureScript file (e.g. the generated src/example_project/core.cljs) and then enter at the Vim command prompt:

:Piggieback! (do (require 'figwheel-sidecar.repl-api) (figwheel-sidecar.repl-api/cljs-repl))

Now saving ClojureScript or CSS files will automatically (and statefully) reload in the browser. And all the regular things in Vim-Fireplace like evaluating expressions or requesting the docs work too.

For repeatability add this alias in your .vimrc (or in an after script for Clojure or Vim-Fireplace):

command! Figwheel :Piggieback! (do (require 'figwheel-sidecar.repl-api) (figwheel-sidecar.repl-api/cljs-repl))

Change what vim considers a keyword in fireplace for clojure

Clojure allows for a lot more chars in a symbol than many other languages. Vim-Fireplace takes care for you by adding lots of the often used additional chars (e.g. ? is the postfix for predicates, symbols starting with : are keywords).

If you are not happy with the choices, you can remove/add simply by creating a ~/.vim/after/ftplugin/clojure.vim file and manipulate the iskeyword there. E.g. set iskeyword-=/ will make the / char a barrier, where word motions stop. Check with calling set iskeyword on the command prompt what is configured.