August 3rd, 2009
gen-struct: a Clojure macro for generating classes with mutable state
Sometimes the only way to get the desired performance is to shun
immutability.
In case of Clojure, that means using arrays or importing mutable
classes from an existing Java library - assuming the library already
has classes with properties/fields that fit our needs. Otherwise, we
have to write some Java code.
Dropping to another language for performance is pretty
disappointing. But sometimes it’s the only sane choice.
I’ve created gen-struct library to avoid some of those
situations. This simple macro, which in reality is a modified version
of the gen-class macro created by Rich Hickey, allows you to create
simple, mutable and immutable structures. You can customize only one
aspect of those classes: their fields. Here’s an example:
(gen-struct
:name my.test.struct
:mutable-fields [[float x]
[float y]]
:final-fields [[int timeout]
[static int MAX_TIMEOUT :is 1000]
[java.io.File input]])
gen-struct automatically generates a constructor which lets you
initialize all the final, non-static fields. In the above example,
single constructor accepting an int value and a File object would
be generated (you pass the arguments in order in which they were
declared in the macro).
gen-struct classes need to be compiled, just like with gen-class.
This is an ugly duckling, since it doesn’t allow for inheritance,
probably not everyone will be happy with no possibility of overriding equals,
and static final fields can only be of primitive type. At least it doesn’t let you mix state and behavior in one entity.
My main motivation for creating it was that some of my experiments in
clj-processing needed a lot of mutation.
§
February 15th, 2009
Only one paragraph about Denmark
I’ve been in Denmark for over a month and haven’t really seen much of it. I’m waiting for warmer weather. But the people are cool. Lots of different nationalities in the place I work in makes things even more interesting.
I’m doing mostly .NET related stuff right now, I only have time for Clojure on weekends. I’m trying to get a feel for getting better performance out of Clojure code; yesterday I’ve dug up an old code sample, but now I see I was doing a bunch of subtle things wrong. Rewrite ahead!
Back in December I’ve begun to prototype a Swing app in Java (I needed auto-completion to get used to the giantic API). Right now I’m in the process of building it from scratch in Clojure. I want to see how far I can go without dropping down to Java, and how to combine Java and Clojure in one project effectively (mostly from the design perspective).
§
November 25th, 2008
Clojure goodies
Processing + Clojure
Processing is a java library for doing visualizations and various
media related stuff. A while ago I did a Clojure wrapper for it. You
can get it from github: clj-processing.
Cloak
A couple of months ago I saw examples of config files of ruby’s
rake. Rake is a build tool, like ant or msbuild, but unlike
those, it doesn’t involve editing XML files. And thanks to ruby’s
quite flexible syntax, the resulting configuration files don’t hurt
your eyes.
I don’t know ruby and didn’t really feel like learning it just for one
tool. Googling for something similar to rake in the python universe didn’t
yield any results.
Since I’m investing much time in Clojure lately, I decided that I
might as well write something useful in it. Hence Cloak, a
simplistic automation tool written in Clojure. It’s heavily inspired by
rake; I had rake’s docs opened most of the time when writing the app.
Here’s how to use it. You put a file named CLOAK in your project’s
directory, and in it you define tasks, like this:
(task :task-name [:other-task :another]
(when (exists? "some.file")
(rm "some.file"))
(sh "command arg1 arg2 arg3" :dofail))
Task name should be a keyword. To run it from the command line, type
cloak task-name, without the semicolon (assuming cloak is the name
of the shell script that launches cloak). Second argument to task is an
optional list of dependencies, which can be other tasks or files. For
example [:compile "classes/my.lib"]. To refer to a file, use it’s
file name. Apart from regular tasks, you can specify file tasks:
(file "index.html" ["template.xml" "content/main.txt"]
(sh "genhtml template.xml content/main.txt index.html"))
file tasks differ from regular tasks in one detail: they compare
modification time of the target and all its dependencies. Task is
executed only if mtime of target < mtime of source.
Cloak is not a replacement for maven or ant. It would take me ages
to reach the level of functionality of those tools. I just wanted
something simple, to automate the generation of my website (among
other things). So far, it’s still a work in progress but it’s usable enough for me to use it with my own projects.
Utility Libs
I’ve also put my utility libs on github. Cloak requires them (but has
them in in a jar, so no need to download them separately). There’s
some IO and math related stuff in there.
§
November 20th, 2008
Autumn Update
Since the end of the year is near, and because at the beginning of January
I’ll be pretty busy with other things (see below), I decided I’ll post
something while I still have spare time on my hands.
On a personal note, that was a good year (I finished school, among
other things). On the professional level, well, I didn’t work
anywhere, was too busy with my thesis. But in September I started
sending out my CV and found something really nice. In Denmark.
I’m starting in January, that’s why I won’t have much time at the
beginning of next year for fancy retrospectives. I’ll spend 1+ year in
Denmark. I always wanted to live there, at least for a while. I mean,
they invented Lego, best toy ever.
But till then, I have lots of free time and so far I’m spending it
mostly on reading and programming. I’m gradually replacing Python with
Clojure as my weapon of choice and I’ll post something on that
topic shortly.
§
August 31st, 2008
MathTalker Went Live
On friday I uploaded the 1.0 version of MathTalker to
Google’s servers. It’s a simple chat application which allows you to write
mathematical formulas (using syntax similar to TeX). It was written in
Python and runs on App Engine.
MathTalker has pretty steep requirements for a web app: Firefox
browser and special math fonts (download links on MathTalker
page). Displaying math formulas is possible thanks to ASCIIMathML
library, which converts ASCII to MathML. I know about the plug-in that
lets you render MathML in IE, but I decided to drop support for that
browser after spending a couple of hours trying to make the UI work.
App Engine
App Engine SDK comes with a little web framework and that’s what I
used. You can also use Django, but I wanted to keep things
simple. The built-in framework is nothing special, but it doesn’t get
in your way. What requires more attention is Google’s Datastore -
their distributed database. Honestly, I used only relational databases
so far (oh, and flat files…), so I had to watch one or two talks
from Google IO conference to get the idea.
What pissed me off the most was lack of support for nested
transactions and some bugs in existing transaction code. To run some
piece of code, you have to pass a function to
db.run_in_transaction(), but whenever I tried to make the code more
generic (as in: not to write two almost identical functions) stuff
exploded. It’s pretty bad, because creating an entity and updating a
counter should be a single atomic action. But they aren’t, so you end
up hoping for the best.
JavaScript
Little bit of history: At first I hated it, then I really liked
it. Now I’m just using it and ignoring its deficiencies. And regarding
the period that I liked JS: it was the time that JS libraries were
becoming really, really good, and I was just impressed (shocked, even)
that it’s possible to build anything with it without cursing like mad.
But even JS 1.7, which has generators and list comprehensions, is
pretty verbose, and you can only take it so far as
jQuery - the best attempt for creating domain
specific language in JavaScript. Great for traversing/manipulating
DOM.
Another thing: I used Emacs with js2-mode. The style of formating
code encouraged (somewhat) by jQuery drives Emacs insane and beaks the
indentation. At the beginning it bothered me, but then I stopped
nesting function definitions and js2-mode let me do my work, and my
code looked more readable. I don’t know if that was how js2-mode
supposed to work or if it was just a bug, but it’s done more good than
harm.
Blueprint
I’ve also tried out Blueprint CSS framework. I’ve used
Yahoo’s CSS reset library before (and I don’t want to work without CSS
reset ever again), but never Blueprint. It’s pretty good, but
somehow feels not clean enough. I guess it provides to much defaults
for my taste. But I’ll probably use it again someday.
§