måndag 19 mars 2012

[] and {} revealed!

These are good explanations of PersistentVector and PersistentHashmap. Read them now, if you are the least unsure on how the [] and {} works!

fredag 17 februari 2012

Scary Macros and Nice Gates

I was finally forced into the realms of macros. What I wanted was this:

(defn logic-tree [gate1 gate2 gate3]
(fn [a b c d] (gate1 (gate2 a b) (gate3 c d))))

My idea was to be able to write a function that generated a function which took four args and combined them in a logic gate, like this:

(gate1 (gate2 A B) (gate3 C D))

ie

(AND (OR A B) (NAND C D))

This is not possible to solve with a function, since a function cannot easily distinguish between the functional arguments and the arguments to feed in later on. This meant I had to go for macros, which have always scared me.

Learning clojure has a good tutorial.

(defmacro logic4 [f]
(list 'fn ['a 'b]
(list f 'a 'b)))

(macroexpand '(logic4 and))
;;=> (fn* ([a b] (and a b)))

((logic4 and) true true) => true

which would easily be expanded to the final form.

Macros does seem less scary after this.

onsdag 15 februari 2012

Javadoc and browse features

There are some really good features in the clojure.java.* libs

one is in javadoc:
user=> (use 'clojure.java.javadoc)
nil

user=> (javadoc String)
"http://java.sun.com/javase/6/docs/api/java/lang/String.html"

user=> (javadoc (java.util.Date.))
"http://java.sun.com/javase/6/docs/api/java/util/Date.html"
the other is browse
user=> (use 'clojure.java.browse)
user=> (browse-url "http://clojuredocs.org")
Booth are shamelessly stolen from awesome ClojureDocs.org

söndag 12 februari 2012

A simple graph-walker

I had a bit of inspiration yesterday, so I made a little graphwalker, where you can move around with a (move :room) in the repl:


Note: This is not very high-performant code - there is a special graph-library where the look-up time is O(log n) or something because it pre-caches all the neighbors to a node.

måndag 6 februari 2012

Announcements of interest

There was some intresting ANNouncements in the list:

Ann: clj-aws-s3 0.2.0 (Weavejester, 4th feb)
This library gives access to the more advanced features of Amazon S3. I've used S3-functionality in Noir previously, but this was a quite simple solution simply covering a very common use case (send a file to S3 and make it readable for all).

Clj-aws-s3 seems to be different, supporting creation of buckets. ACL functionality to come.

CongoMongo is a wrapper for the Java driver for MongoDB. The nice part is a very good match between clojures map data structure and MongoDBs way of storing things. You can use both maps {:a "b"} and vectors [] (but not #{} sets) out of the box.

side note:
I made a gist on how to create mongoIds in Clojure, if you would need it. Most probably not, since the ordinary use case is to put a map in and then recall it somehow based on other things than id.

[ANN] Marshal 1.0.0 (github, clojars, Russell Christopher)

The idea is to be able to use Clojure to read binary data formats/streams in a structured way.

The release note gives the following example:

//C header file definition
struct packet {
unsigned long type;
unsigned long size;
long data[1];
};

translated to Clojure:

(require '[marshal.core :as m])
(def packet (m/struct :type m/uint32 :size m/uint32 :data (m/array m/
sint32 :size)))
(m/write output-stream packet {:type 1 :size 2 :data [1 -1]})
(m/read input-stream packet)
=> {:type 1 :size 2 :data [1 -1]}
An enlighting discussion followed, promoting the library Gloss as a library with similar and even more functionality.

Ann: Clojure 1.4.0-beta1
Clojure 1.4.0 is going beta! The good parts would be better support for clojure-in-clojure, making it easier to port clojure to new platforms (projects regarding Python, PHP and LLVM is discussed).

My impression is that there are a lot of speed achievements to be made (especially with protocols, records and other nice abstractions over OO-engines).

fredag 3 februari 2012

Generate XML

I need to generate a lot of quite boring XML. I was thinking and trying out zip-maps, but this seems to be quite tedious in this specific application. I'll head for hiccup and see where that rabbit hole ends.

söndag 29 januari 2012

Zip-filter.xml

I've added som examples of the zip-filter.xml/xml-> at the great site ClojureDocs.org.

I'm not sure it's always the best tool to use to generate xml, I'm still looking for a good way to represent complicated (or, should I say, complected) xml structures.

Search and replace of tokens in an XML-template should also works in many pure generate some xml-file cases.

lördag 28 januari 2012

Using Leiningens java-source-path

There's a functionality :java-source-path in Leiningen.

I wanted to know whether this compiled the java-sources in sub-folders as well, and could handle packages-notation, a good functionality when already having a code base in java . Leiningen did not put me down, it did take good care of all this.

I added a

:java-source-path "java"

to Leiningen's project.clj. And then

mkdir java/se/linusericsson/www

where I created a small TestPackage.java:

package www.linusericsson.se;
public class TestPackage {
int i = 100;
public int geti() {return i}
public void seti(int j) {i = j;}}

I ran lein javac (says something like one file compiled)

in lein repl

(import 'www.linusericsson.se.TestPackage)
(def tp (TestPackage.))
(.geti tp)
=> 100
(.seti 145 tp)
(.geti tp)
=>145 ;;OK!

note:
(Xxx.) means new Xxx in java.
(.geti ) is part of the standard java interop for clojure.