Daniel Janus’s blog
Posts in category: Lisp
Making of “Clojure as a dependency”
In my previous post, “Clojure as a dependency”, I’ve presented the results of some toy research on Clojure version numbers seen in the wild. I’m a big believer in reproducible research, so I’m making available a Git repo that contains code you can run yourself to reproduce these results. This post is an experience report from writing that code.
Clojure as a dependency
I have a shameful confession to make: I have long neglected an open-source library that I maintain, clj-tagsoup.
This would have been less of an issue, but this is my second-most-starred project on GitHub. Granted, I don’t feel a need for it anymore, but apparently people do. I wish I had spent some time reviewing and merging the incoming PRs.
Indenting cond forms
Indentation matters when reading Clojure code. It is the primary visual cue that helps the reader discern the code structure. Most Clojure code seen in the wild conforms to either the community style guide or the proposed simplified rules; the existing editors make it easy to reformat code to match them.
You already use Lisp syntax
Unix Developer: I’m not going to touch Lisp. It’s horrible!
Me: Why so?
UD: The syntax! This illegible prefix-RPN syntax that nobody else uses. And just look at all these parens!
Me: Well, many people find it perfectly legible, although most agree that it takes some time to get accustomed to. But I think you’re mistaken. Lots of people are using Lisp syntax on a daily basis…
Combining virtual sequences
or, Sequential Fun with Macros
or, How to Implement Clojure-Like Pseudo-Sequences with Poor Man’s Laziness in a Predominantly Imperative Language
Sequences and iteration
There are a number of motivations for this post. One stems from my extensive exposure to Clojure over the past few years: this was, and still is, my primary programming language for everyday work. Soon, I realized that much of the power of Clojure comes from a sequence abstraction being one of its central concepts, and a standard library that contains many sequence-manipulating functions. It turns out that by combining them it is possible to solve a wide range of problems in a concise, high-level way. In contrast, it pays to think in terms of whole sequences, rather than individual elements.
Keyword arguments
Who said Common Lisp programs cannot be small?
So, how much disk space does your average CL image eat up? A hundred megs? Fifty? Twenty? Five, perhaps, if you’re using LispWorks with a tree-shaker? Well then, how about this?
[nathell@chamsin salza2-2.0.4]$ ./cl-gzip closures.lisp test.gz
[nathell@chamsin salza2-2.0.4]$ gunzip test
[nathell@chamsin salza2-2.0.4]$ diff closures.lisp test
[nathell@chamsin salza2-2.0.4]$ ls -l cl-gzip
-rwxr-xr-x 1 nathell nathell 386356 2008-08-09 11:08 cl-gzip
cl-morfeusz: A ninety minutes’ hack
Here’s what I came up with today, after no more than 90 minutes of coding (complete with comments and all):
MORFEUSZ> (morfeusz-analyse "zażółć gęślą jaźń")
((0 1 "zażółć" "zażółcić" "impt:sg:sec:perf")
(1 2 "gęślą" "gęśl" "subst:sg:inst:f")
(2 3 "jaźń" "jaźń" "subst:sg:nom.acc:f"))
cl-netstrings
I’ve just packaged up the Common Lisp netstring handling code that I wrote a week ago into a neat library. Unsurprisingly enough, it is called cl-netstrings and has its own home on the Web. It’s even asdf-installable! I wonder whether this one turns out to be useful for anybody besides me…
Hacking away with JSON-RPC
Let’s try:
(let ((s (socket-stream
(socket-connect "localhost" 10081
:element-type '(unsigned-byte 8)))))
(write-netstring "{\"method\":\"ping\",\"params\":[],\"id\":1}" s)
(finish-output s)
(princ (read-netstring s))
(close s))
; { "result": "pong" }
; --> T