Beware of assertions

What I write below might be universal knowledge, but I was personally bitten by this more than once, so I feel the need to emphasize it once again.

Clojure's assert form can be used for quick&dirty verification and consistency checking in your code. It is convenient to have them during development because they may discover incorrect usage of functions before the mistake drops deeper into the callstack and fails with something like NullPointerException or java.lang.Long cannot be cast to clojure.lang.IFn. And for this task assert is perfectly fine — it is there out of the box, and you can disable the assertions in production by setting clojure.core/*assert* var to false.

The problems begin when you stick to assertions for prod-time data validation (once again, you may already be smart enough not do it. I wasn't).

Read more ->>

I finally managed to polish a thing that lived on my hard drive in disassembled state for years. ns-graph is initially a fork of the abandoned clojure-dependency-grapher. As vain as it may seem, this tools is often very useful to me. It is surprisingly descriptive when you need to understand the high-level architecture of some project. Recently I wanted to catch up with the changes in cider-nrepl and figure out where exactly it uses its new dependencies. Well, sometimes you should think carefully what you wish for.

Read more ->>

Imagine the following setup: service A serves a stream of data items by exposing the latest batch of these items as an HTTP endpoint. Application B polls service A every now and then, fetches the recent batch and puts the unwrapped items onto a core.async channel. The consumer(s) on the other side of the channel may come and go. The nature of the data is also such that it is droppable (not every item has to be processed) and becomes stale over time.

Read more ->>

This post was originally written in a notebook. Check out Gorilla REPL if you haven't done it yet!

If you don't know yet what a transducer is, or how they work, there are two amazing talks to get started, both by Rich Hickey: Transducers and Inside Transducers. I watched those talks a couple of times each, and I moderately use transducers in my projects; thus I have a decent understanding of transducers. Or so I thought.

Yesterday my coworker and I delved into reading the already implemented transducers in clojure.core, and started pondering why some seq-operating functions don't have a transducer counterpart. Multiple-collection map? Probably missing because it doesn't fit the single-stream semantic very well. take-last and drop-last? Those two can actually be implemented as transducers by using a queue. And then… cycle? Can we do cycle?

As it turned out, my knowledge of transducers was limited. I could use them, and I got the idea behind them, but until I implemented one I lacked the perception of the underlying machinery. Today I will guide you step by step through how we implemented cycle transducer, so you might also get a better comprehension of this topic.

Read more ->>

This post was originally written in a notebook. Check out Gorilla REPL if you haven't done it yet!

A sizeable number of Clojure developers had some Common Lisp experience in the past. When asked what the main Clojure advantages over CL are they often mention having a single equality operator (compared to Lisp's eq, eql, equal, equalp). It might come as a minor point, but in practice, it is very cognitively exhausting to keep track of which one you should use. What's, even more, jarring is that eql — not the most intuitive one — is usually the default. Can you explain with a straight face to a beginner that their string-keyed hashtable didn't work because it was created with a wrong equality operator? I never could.

But Clojure has a similar sin of its own — the multitude of list type predicates. If woken up at 3 A.M. and asked what the standard Clojure data structures are, you would likely name lists, vectors, maps, and sets. But how do you tell if the given object is a data structure of a certain type? "Well", you'd say, "there are vector?, map?, set?, and… list?? Leave me alone, man, I'm trying to catch some z's."

Gotcha! The thing is, list? is a weak predicate. It checks if the object is precisely a PersistentList, but there are plenty of things in Clojure that look like lists without being ones.

Read more ->>

TL; DR: Omniconf is a new configuration library for Clojure that unifies environment variables, command-line options, and config files; and ensures the configuration is complete and correct before the main application code runs.

Configuring your application is often a daunting and thankless task. It very much depends on the way you launch your program, so it is difficult to solve the configuration problem for the general case. Twelve-factor app guidelines suggest using environment variables for everything, but that rule is unnecessarily rigid. If you have many options, configuration files are more appropriate. When you launch the app from the command line (on a dev machine, for example), command-line arguments are preferable. But now you suddenly need a unified access to all those configuration sources.

There are already libraries that solve the configuration problem in Clojure, namely: Environ, Aero, Nomad, Fluorine. All of them are quite good at what they do; however, we at Grammarly needed extra functionality — to check the final configuration state before the main program executes, and make sure there are no missing or incorrect options. What began as a few helper functions were extracted into a separate library and called Omniconf.

Read more ->>

Until now, Boot documentation had imperfect instructions on how to setup Boot to fully work with CIDER. I've updated the page to include a better way which separates regular repl (launched from terminal, better be quick to load) from the heavy CIDER repl with all the necessary dependencies. Here we go, add this code to ~/.boot/profile.boot:

(require 'boot.repl)

(deftask cider ""
  (reset! boot.repl/*default-dependencies*
         '[[org.clojure/tools.nrepl "0.2.12"]
           [cider/cider-nrepl "0.10.0"]
           [refactor-nrepl "2.0.0-SNAPSHOT"]])
  (reset! boot.repl/*default-middleware*

Then in Emacs do M-x customize-variable cider-boot-parameters and set it to cider repl -s wait.

Read more ->>

Clojure 1.7 finally saw a feature many people have been asking for — reader conditionals. It enables writing of platform-independent reusable code, where by platforms I mean Clojure, CLJS or ClojureCLR. With reader conditionals you can write code like this:

[1 2 #?@(:clj [3 4] :cljs [5 6])]
;; in clj => [1 2 3 4]
;; in cljs => [1 2 5 6]
;; anywhere else => [1 2]

This is cool, but unfortunately the list of features is currently limited to just three platforms. Additionally, the only place where you can use this syntax is inside .cljc files. So, goodbye to leveraging this from the REPL. Hint by @mfikes: it works in REPL launched directly from Clojure jar, but for some reason it doesn't in REPLs spawned by neither Leiningen nor Boot. Yet, most people use REPL from those tools, so we're still screwed.

On the other hand, Common Lisp has feature expressions as a first-class feature. Developers are free to define their own features and use them anywhere they like. And while this may create chaos and requires strict agreements between colleague, the feature itself is quite useful. Features like :dev, :test and :prod are quite prevalent in Common Lisp projects, and often they substitute other means of configuration and build type separation.

So, for the above reasons, and mainly for fun, I decided to hijack the new reader conditionals functionality to make it extensible and omnipresent.

Disclaimer: do not use this in your projects and do not think it is acceptable to do such things in real life. In fact, forget everything you're going to see here.

Read more ->>

Yesterday I needed to make a cheatsheet for my coworkers, but I didn't want to use online services or other proprietary tools. I turned to LaTeX, but there weren't any enticing eye-candy templates that I would be proud to give out. This template was the closest I could get, it looks neat by doesn't have a cherry on the top.

So I spent an evening to pimp that template and turn it into something that you can see below. Just edit the cheatsheet.tex file and compile it with xelatex.

TeX source

Resulting PDF

Read more ->>

A couple of years ago I have discovered this silly definition of the word Yegge on Urban Dictionary. For those who don't know Steve Yegge is a software developer, a former Google employee, and an author of his blog Stevey's Blog Rants. So the UD definition of "Yegge" goes as following:

A measurement of length of a piece of writing, particularly when indicating a length excessive for the genre. A Yegge is approximately 4000 words or 25 kilobytes.

Named for well known programmer and technical blogger Steve Yegge, whose blog up to about 2009 was notorious for entries of approximately 1 or 2 Yegges in length, vastly exceeding the typical length of blog entries in the genre.

Usage example: "I knew breaking up with him was a good idea after I got an email two Yegges long listing all the reasons why I should take him back."

Read more ->>

For more posts see the Archives page.