Can’t dynamically bind non-dynamic var in Clojure 1.3 and on

I’ve already described the issue of Can’t dynamically bind non-dynamic var in Can’t dynamically bind non-dynamic var in Clojure 1.3. While learning about defs, symbols and vars, I again ran into this issue. I can see now that I made a mistake using Clojure 1.3 not 1.3.0-alpha6 in the title of the past blog entry as it seems broken in the final version 1.3.0.

user=> (clojure-version)
"1.3.0"
user=> (def b 3)
#'user/b
user=> (binding [b 4])
IllegalStateException Can't dynamically bind non-dynamic var: user/b  clojure.lang.Var.pushThreadBindings (Var.java:339)
user=> (def *c* 5)
#'user/*c*Warning: *c* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *c* or change the name.
user=> (def ^:dynamic *d* 5)
#'user/*d*Warning: *d* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *d* or change the name.

It turns out that it was however fixed in the recent version of Clojure 1.4.0-beta3 and on.

You can download Clojure 1.4.0-beta3 and check it out yourself (I strongly recommend using leiningen to do the test).

$ wget -O clojure-1.4.0-beta3.jar http://search.maven.org/remotecontent?filepath=org/clojure/clojure/1.4.0-beta3/clojure-1.4.0-beta3.jar
$ java -jar clojure-1.4.0-beta3.jar
Clojure 1.4.0-beta3
user=> (def ^:dynamic *d* 5)
#'user/*d*
user=> (binding [*d* 10] *d*)
10

I also tested it out with the recent build off the sources of Clojure.

$ ant
Buildfile: /Users/jacek/oss/clojure/build.xml
...
jar:
      [jar] Building jar: /Users/jacek/oss/clojure/clojure-1.4.0-master-SNAPSHOT.jar
     [copy] Copying 1 file to /Users/jacek/oss/clojure

all:

BUILD SUCCESSFUL
Total time: 1 minute 34 seconds

$ java -jar clojure-1.4.0-master-SNAPSHOT.jar
Clojure 1.4.0-master-SNAPSHOT
user=> (def ^:dynamic *d* 5)
#'user/*d*
user=> (meta (var *d*))
{:ns #<Namespace user>, :name *d*, :dynamic true, :line 1, :file "NO_SOURCE_PATH"}
user=> (binding [*d* 10] *d*)
10

I’ll have to stick with the version clojure-1.4.0-beta3 for the time being.

However, it looks like I’ll also have to use (def ^{:dynamic true} *server*) as lein2 compile finished with the following error:

Caused by: java.lang.IllegalArgumentException: Unable to resolve classname: :dynamic
	at clojure.lang.Compiler$HostExpr.tagToClass(Compiler.java:916)
	at clojure.lang.Compiler$VarExpr.getJavaClass(Compiler.java:512)
	at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:807)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:5369)
	... 47 more
Compilation failed.
Languages 2 Comments

Block-Scanner from Let Over Lambda in Clojure

Remember Getting my head around let-over-lambda, functions in let, and let with bindings in Clojure in which I mentioned the chapter Closures in Let Over Lambda by Doug Hoyte? I spent an entire day having imagined I could write the parser in Clojure and, guess what, I ultimately did it!

How would you feel about the following implementation? Would you accept it as a preliminary version of a final solution or would that be the final one?

user=> (defn block-scanner [trigger-string]
         (let [curr (atom trigger-string)]
           (fn
             ([] @curr)
             ([data-string]
               (doseq [c data-string]
                 (if @curr
                   (swap! curr (fn [_]
                                 (if (= (first @curr) c)
                                   (rest @curr)
                                   trigger-string)))))
               (= @curr trigger-string)))))
#'user/block-scanner
user=> (def clj-scan (block-scanner "clojure"))
#'user/clj-scan
user=> (clj-scan ">> cloj")
false
user=> (clj-scan)
(\u \r \e)
user=> (clj-scan "ure.")
true

Notice how the returned function (a closure) closes over the atom (in the let form) and trigger-string (the input argument). I hope my Clojure self-learning is going into the right direction.

Languages 3 Comments

Java EE web apps with Clojure (Maven and Leiningen are there, too!)

Sorry for party rocking! That’s really a crazy song, isn’t it? I do hope, the demo won’t be far from it :)

How could I never come up with the idea?! I’m just a day before I again showcase Clojure for Warszawa Java User Group (WJUG) and since there’ll be lots of people with Java EE background I came up with it – show how to use Clojure in Java EE applications. Well, they’re not any different from other Java applications, but guess it will surely help me introduce the language provided it brings a value. They will know it better, don’t they?

I believe it was during a walk with my youngest son (5 months and 2 days old) when he was sleeping and there’s nothing I could do, but to think about what I should be presenting during a WJUG meeting. I was wondering about an idea that would ultimately catch their attention for Clojure, and I’d need to show what they’re doing from another angle – have a Clojure script used in a JSP or a servlet. I believe it can do the trick and some will certainly appreciate the marriage.

These days, Apache Maven seems losing attention as the most comprehensive project management tool as the other alternative languages are catching up, and gradle, sbt or some kind of thereof leads the race. I don’t mean to learn or ask the audience to learn the other packaging tools, and since I’m the most comfortable with Maven (amongst the other tools I’ve just mentioned), I’ll stick with it.

As described on Maven’s Guide to Webapps, run the following command to generate a web application for our learning purposes:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp

It generates a web application called my-webapp in the current directory.

Clojure’s side of the webapp will be managed by Leiningen. Run lein new my-webapp-clj to generate a new Clojure project.

Edit src/my_webapp_clj/core.clj so it contains the following:

(ns my-webapp-clj.core
  (:gen-class
   :methods [[hello [String] String]]))

(defn -hello
  [this s]
  (str "Hello, " s))

Note the :gen-class and :methods directives in ns macro. They’re very important for the Java interop, and hence our demo. They basically say that during the project’s AOT compilation, a Java class called my_webapp_clj.core is to be generated (:gen-class) with the method hello(String) which returns a String object (:methods array).

Edit project.clj so it contains :aot :all in defproject as follows:

(defproject my-webapp-clj "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.3.0"]]
  :aot :all)

Note the line with :aot :all that will trigger AOT compilation for the entire project. No other changes are necessary.

Run lein install to AOT compile the namespace, package and install the project in a Maven repository.

jacek:~/sandbox/my-webapp-clj
$ lein install
Compiling my-webapp-clj.core
Compilation succeeded.
Created /Users/jacek/sandbox/my-webapp-clj/my-webapp-clj-1.0.0-SNAPSHOT.jar
Wrote pom.xml
[INFO] Installing /Users/jacek/sandbox/my-webapp-clj/my-webapp-clj-1.0.0-SNAPSHOT.jar to
/Users/jacek/.m2/repository/my-webapp-clj/my-webapp-clj/1.0.0-SNAPSHOT/my-webapp-clj-1.0.0-SNAPSHOT.jar

Back to the my-webapp project.

In pom.xml add the following dependency:

<dependency>
  <groupId>my-webapp-clj</groupId>
  <artifactId>my-webapp-clj</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</dependency>

It says that the my-webapp project depends on our Clojure project’s artifact.

Edit src/main/webapp/index.jsp so it looks as follows:

<html>
<body>
<h2>Hello World!</h2>
</body>
<p><%= new my_webapp_clj.core().hello("Jacek") %></p>
</html>

You may have noticed the scriptlet with new my_webapp_clj.core().hello("Jacek"). Although it’s not recommended to use scriptlets in JSP, it’s fine for the example. You’re strongly advised to create a servlet and call the my_webapp_clj.core class off it.

Run mvn package to package the webapp.

[INFO] Building war: /Users/jacek/sandbox/my-webapp/target/my-webapp.war

The webapp’s ready for deployment. Copy it to webapps directory of your Tomcat, and fire it up.

Open up http://localhost:8080/my-webapp/ and enjoy the Clojure and Java EE combo.

I can’t wait till I show it during tomorrow’s WJUG meeting. Nobody’s gonna apologize for some fun!

Java EE, Languages 4 Comments

Getting my head around let-over-lambda, functions in let, and let with bindings in Clojure

While I was working on a solution in Clojure for the block-scanner from the chapter Closures in Let Over Lambda by Doug Hoyte that I imagined would help me to understand the let-over-lambda concept, I hit on the idea of a function as a way to create an environment, like let form. A couple of examples should ease getting the point across.

;; assume you want to have a global-like value or how they call it - a var
;; Clojure provides def special form
user=> (def bound-var 5)

;; You could also declare a var without a root binding
user=> (def unbound-var)

;; unbound-var can't be used without first initializing it
user=> unbound-var
java.lang.IllegalStateException: Var user/unbound-var is unbound. (NO_SOURCE_FILE:0)

;; let form helps
user=> (let [unbound-var 10]
             unbound-var)
10

;; you could also use binding form
user=> (binding [unbound-var 10]
             unbound-var)
10

;; there's a difference between let and binding, but don't get distracted too much

;; let special form and binding macro are kind of a function
;; they even look the same, don't they? Well, in Clojure everything looks the same.

;; let's create a function
user=> (defn f [v] v)
#'user/f

;; the function f returns the value it was executed with - a "no-op" function
user=> (f 3)
3

;; notice that anything inside the function f sees the value of the input parameter v
;; in other words, v is bound var like it happens for def or within let and binding forms

;; a function creates a lexical scope for input parameters
;; let form creates a lexical scope, too
;; and finally a function is a first-class object like a number (5) or any other structure (list, map, array)

;; assume you want to set a bound var to another value inside a function
user=> (def bound-v 7)
#'user/bound-v

user=> (defn g []
         (let [bound-v 3]
           bound-v))
#'user/g
user=> (g)
3

;; it effectively shadowed bound-v with a new value

;; what if we wanted to shadow a var (or reassign the value of it)
user=> (defn h []
         (let [f (fn [bound-v g] (g bound-v))]
           (println bound-v)     ;; use top-level bound-v
           (f 9 println)))       ;; use bound-v reassigned to 9
#'user/h
user=> (h)
7
9
nil

Now I wonder where I would need it, though?! The concept of let-over-lambda I met in Clojure in Action first bothers me badly. It’s simply a technique to bind values to free variables for their use in a closure (not Clojure the language, but the executable block of code that closes over free variables), but knowing how to use it is far from knowing when/where to apply the knowledge. However, I believe good things come to those who wait.

BTW, I’m speaking about Clojure at 33rd degree in Krakow on 19-21.03.2012, DevCrowd in Szczecin on 14.04.2012, 4Developers in Poznan on 18.04.2012, GeeCON in Poznan on 17-18.05.2012 and have been thinking about proposing a talk for the other European conferences like EuroClojure in London, Jazoon in Zurich, but guess there’ll be other Clojurians who do the job of presenting Clojure better. Help me decide if you believe I could help you jump on the Clojure bandwagon.

Languages 5 Comments

Practical encounter with defprotocol in Clojure for JSONising MongoDB’s ObjectId

I’ve seen examples that make use of defprotocol in Clojure, but have never tried it out myself. Until now.

I’m working on the librarian-clojure project which aims at offering a book manager in Clojure. It’s more for learning Clojure while developing something potentially useful. I managed to encourage Konrad Garus to join the project and I believe we’re doing great together. My dream came true – I’ve got a Clojure project with a teammate.

The project uses many solutions that I’ve been only theoretically aware of. Quite recently jQuery joined the club as we needed to send JSON data between a browser and a server.

After a couple of days reading the book jQuery Recipes from Apress I felt ready to give jQuery a try. I knew that MongoDB, which we use in the project, can return JSON data, so I thought it’s a matter of passing it along to the browser. I couldn’t have been more wrong.

It turned out that the following simple query

(with-mongo db
  (fetch :books :where query))

returns a JSON-like structure, e.g. a list of JSON items:

({:_id #<ObjectId 4f4e5a7726b228abdf05cf93>, :author Jacek, :title Tytul} {:_id 0, :author Mickiewicz, :title Konrad Wallenrod})

As you might’ve noticed, it’s not an array, but a list so clojure.data.json/json-str spat the following exception:

java.lang.Exception: Don't know how to write JSON of class org.bson.types.ObjectId
     at clojure.data.json$write_json_generic.invoke(json.clj:276)
     at clojure.data.json$fn__447$G__442__456.invoke(json.clj:197)
     at clojure.data.json$write_json_object.invoke(json.clj:242)
     at clojure.data.json$fn__447$G__442__456.invoke(json.clj:197)
     at clojure.data.json$write_json_array.invoke(json.clj:255)
     at clojure.data.json$fn__447$G__442__456.invoke(json.clj:197)
     at clojure.data.json$json_str.doInvoke(json.clj:316)
     at clojure.lang.RestFn.invoke(RestFn.java:410)
     at librarian_clojure.books$get_books_json.invoke(books.clj:58)
     ...

Having looked at the source code of clojure.data.json/json-str I noticed that it uses write-json that’s part of the Write-JSON protocol. When I looked at the series of extend’s I knew I’d have to extend the protocol to handle MongoDB’s org.bson.types.ObjectId.

With the following functions I’m now able to use json-str without a problem.

(defn- write-json-mongodb-objectid [x out escape-unicode?]
  (json/write-json (str x) out escape-unicode?))

(extend org.bson.types.ObjectId json/Write-JSON
  {:write-json write-json-mongodb-objectid})

The output is now as follows:

[{"_id":"4f4e5a7726b228abdf05cf93","author":"Jacek","title":"Tytul"},{"_id":0,"author":"Mickiewicz","title":"Konrad Wallenrod"}]

http://jsonlint.com/ says it’s a valid JSON so I’m glad I could sort it out at one sit.

I’ve always been said that to truly master a language one needs to stay with it for entire days. It’s much easier when you’ve got a project and you’re paid for doing it, but without a paid project, you’re not doomed at all. You simply have to start your own. And I did and thanks to Konrad I’m having so much fun as I’m learning Clojure and the auxiliary solutions. Life couldn’t have been better!

Frameworks, Languages , 1 Comment

Today’s a palindrome redux – a slimmer version of palindrome? function with reduce

After some tinkering with the palindrome? function I presented in the previous blog post I received a bunch of very educative responses that ultimately guided me to the following slimmer version of the palindrome? function.

(defn palindrome? [s]
  (= s (reduce #(str %2 %) s)))

(is (palindrome? "21022012"))

There’s no map function, but the point was to have it if it could improve the function.

I could also find traces to java.lang.StringBuffer.reverse() which “causes this character sequence to be replaced by the reverse of the sequence”, but the variation of the palindrome? function is certainly not shorter and moreover I don’t think it’s even prettier.

UPDATE on 02/24: The function changed after the comment of Denis where he pointed out the excessive parens around .reverse and str functions. The palindrome? function is now slightly improved.

UPDATE on 02/24: The function changed after the comment of Nander where he pointed out to use java.lang.StringBuilder as “This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations”.

(defn palindrome? [s]
  (= s (-> (StringBuilder. s)
           .reverse
           str)))

Note the space between the dot and “reverse” in (. reverse) (the line 2). You could have the s-expression with and without the space (!)

Looking at clojure.string/reverse doesn’t reveal anything better, either.

(defn ^String reverse
  "Returns s with its characters reversed."
  {:added "1.2"}
  [^CharSequence s]
  (.toString (.reverse (StringBuilder. s))))

I’d say it’s even uglier with the (.toString) call, at least length-wise. Could it be that using Java methods is faster than their Clojure counterparts?

I’d like to thank Mark, Andrew, Craig, Norman, Si Yu and Manuel for their inspirational comments, and tweets from Sean and Neale. You guys helped me a lot to get closer to functional programming zen in Clojure :) It matters a lot to me! As I’m presenting Clojure during Java conferences in Poland, the more I feel comfortable with the language the better presentation I’m to run. Thanks!

Languages 6 Comments

Today’s a palindrome – how to check palindromes in Clojure

There’re countries like Poland that use dates in the format ‘dd.mm.YYYY’, so today’s 21.02.2012. As pointed by @KevlinHenney on twitter it’s a palindrome and I was pleasantly surprised to find it out.

I came up with the idea of writing a Clojure function to check if a given string is a palindrome.

I remember the moment very well when I stumbled upon the (conj) function and learnt that it behaves slightly different when executed with a list or an array.

user=> ;; use conj with a list (mind the quote mark)
user=> (conj '(1 2 3) 0)
(0 1 2 3)
user=> ;; use conj with an array
user=> (conj [1 2 3] 0)
[1 2 3 0]

I think that in order to fully embrace the concept of functional programming is to use the three functions: map, reduce and filter extensively, and so I insisted on using them to tackle the problem.

Here’s the function I developed to check whether a given string is a palindrome or not.

user=> (defn my-reverse [s]
         (let [lst (list)]
           (reduce #(str %2 %1)
                   (mapcat #(conj lst %1) s))))
#'user/my-reverse

user=> (defn palindrome? [s]
         (= s (my-reverse s)))

user=> (is (palindrome? "21022012"))
true

I solved the problem, but with mapcat not map. Is there a way to use just the three functions – map, reduce and filter?

Languages 7 Comments

AOT-compile all namespaces in a Clojure project – :aot :all in project.clj (leiningen)

It’s been a couple of times when I ran across a compilation issue while starting up the librarian-clojure project. I guess refactoring in Clojure or any dynamic programming language is not as easy to achieve as in static languages, and perhaps Ahead-of-time (AOT) Compilation could be a solution. I’m yet to join a project with Clojure (or JRuby) as the language so I may find it out one day.

I use lein to manage Clojure projects and learnt to use lein compile.

There’s an issue with lein compile – it doesn’t compile all the available sources which was the feature I was looking for.

To use lein compile you’ll have to define :main [namespace] which will only compile the main namespace pointed out by the namespace option.

(defproject librarian-clojure "0.0.1-SNAPSHOT"
  :description "Book manager in Clojure"
  :url "http://github.com/jaceklaskowski/librarian-clojure"
  ;; removed to ease reading
  :main librarian-clojure.run)

Run lein compile and you’ll see your main namespace compiled.

jacek:~/oss/librarian-clojure
$ lein compile
Compiling librarian-clojure.run
Compilation succeeded.

I often consult a source code to find answers if it’s available. The sources of the compile task are available, and it’s just a matter of time how much you’ll gain studying the sources. I don’t think you need much to learn a lot.

At line 30 of the compile task I found the value :all of the :aot option. That was it!

(defproject librarian-clojure "0.0.1-SNAPSHOT"
  :description "Book manager in Clojure"
  :url "http://github.com/jaceklaskowski/librarian-clojure"
  ;; removed to ease reading
  :main librarian-clojure.run
  :aot :all)

With the change in project.clj, lein compile now processes all the namespaces in the project. Huurray!

jacek:~/oss/librarian-clojure
$ lein compile
Compiling librarian-clojure.run
Compiling librarian-clojure.books
Warning: *server* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *server* or change the name.
Compiling librarian-clojure.core
Compiling librarian-clojure.repl

Type (go) to launch the server and run a browser.
Type (stop) to stop the server.

Compiling librarian-clojure.run
Compilation succeeded.
Languages 1 Comment

clj-time and Joda Time to pretty-print my son’s age in Clojure

In Clojure’s lein and clj-time to calculate my son’s age I wrote about clj-time to help me calculate my son’s age. What I missed was how to display weeks, days and hours and such in a format like: 4 months and 4 days and 5 hours and 10 minutes.

Konrad Garus pointed out at org.joda.time.format.PeriodFormatterBuilder that would do this.

The following is a possible answer to my question of formatting the age of my youngest son up to minutes. Note how I almost directly copied the Java version to create the Clojure one. Ideas and comments welcome.

(import 'org.joda.time.format.PeriodFormatterBuilder)

(defn format-age [interval]
  (let [builder (doto (PeriodFormatterBuilder.)
                      (.printZeroAlways)
                      (.printZeroRarelyLast)
                      (.appendMonths)
                      (.appendSuffix " month" " months")
                      (.appendSeparator " and ")
                      (.appendDays)
                      (.appendSuffix " day" " days")
                      (.appendSeparator " and ")
                      (.appendHours)
                      (.appendSuffix " hour" " hours")
                      (.appendSeparator " and ")
                      (.appendMinutes)
                      (.appendSuffix " minute" " minutes"))
        formatter (.toFormatter builder)]
    (.print formatter interval)))

(use 'clj-time.core)

(def maksym-birth-date-time (date-time 2011 10 03 17 23))

(def maksym-interval (interval maksym-birth-date-time (now)))

(format-age (.toPeriod maksym-interval))

(in-weeks maksym-interval)

When you run it, it should print out the following output:

user=> (format-age (.toPeriod maksym-interval))
"4 months and 6 days and 4 hours and 25 minutes"
user=> (in-weeks maksym-interval)
19
Languages Leave a comment

(clojure.java.browse/browse-url “http://clojure.org”)

While reviewing the sources of RESTful Clojure webapp skeleton w/Compojure, Ring, Enlive, and ClojureQL I found the clojure.java.browse namespace with the browse-url function I was looking for for some time.

By a complete chance I stumbled upon this function which I happily incorporated in the librarian-clojure project. The function requires a URL to be open, e.g.

$ lein repl
REPL started; server listening on localhost port 44510
user=> (clojure-version)
"1.2.1"
user=> (clojure.java.browse/browse-url "http://clojure.org")
"http://clojure.org"

Once you call this function the default browser will open with the page. Quite handy, isn’t it? And the sources of the function are easy to read through as well. It takes a mere minute.

It turned out that the function was already in my project (when I copied the part off the other project), but I had no time to read about and ultimately learn it. Now I did.

By the way, I don’t recommend reviewing the application as it appears quite old, and perhaps often misleading in its use of the web libraries. Stay away of it.

Languages Leave a comment