Why would I prefer Liberty Profile over TomEE?! No easy answer

That’s the question which keeps bothering me lately: “Why would I prefer IBM WebSphere Application Server V8.5 Liberty Profile over Apache TomEE?”

I’m pretty sure I’m not alone who struggles with the question and there’ll be more people soon. Since they’re new product offerings such questions will pop up quite often.

TomEE has just passed the vote for public consumption as the version 1.0. At almost the same time “IBM officially announced a new developer friendly light-weight web app server called WAS V8.5 – Liberty Profile”. And there’re other application servers around that keep your head busy over choosing the best offer for your next project (in random order): Apache Geronimo, JBoss AS, GlassFish, Jetty, Tomcat, Oracle WebLogic Server, et al.

“Why am I concerned?”, you may ask. It’s not very often when you’re in charge of deciding what application server to pick for a project, but when you are in charge of proving a guidance, things get tough and complicated. What’s a big deal?! Well, I’m an IBMer and a member of the Apache TomEE project.

I’ve been always wishing that IBM would release an application server like the Liberty Profile. It’s been my dream for ages. I remember the days when IBM WebSphere AS V6.1 was released and I left BEA WebLogic Server aside when I changed the employer. It wasn’t easy, but OSGi made the difference and I believed it would eventually turn the product to become the leader. I’m not going to say it happened (neither would I refuse it!), but the versions were better over time (even though many people I met could hardly notice it as they often just didn’t care).

I was really happy when IBM unveiled IBM WebSphere Application Server V8 as “the third application to be certified with full Java EE 6 Profile, following on from Oracle’s GlassFish Open Source Edition 3.x and upwards, and JEUS 7 from TmaxSoft.” Since GlassFish is the reference implementation for Java EE 6 and is indeed supposed to be the first application server to test against and I’ve never seen JEUS 7 as the platform, it’s been said that IBM WebSphere Application Server V8 was the first commercial product offering with the full Java EE 6 support. That made the difference for me!

IBM didn’t stop it, but neither did the competition. Apache TomEE has a great potential to catch people’s attention for its simplicity as “The result is Tomcat with added EE features, TomEE.”

I can hardly point the winner in the race for a leaner, smoother and more feature-rich and lightweight application server, but am sure we, Java EE developers, have just received a very interesting question to tackle. TomEE “is an all-Apache Java EE 6 Web Profile certified stack where Tomcat is top dog” which Liberty Profile would not likely soon achieve. On the other hand, Liberty profile supports Enterprise OSGi (OSGi Blueprint and WABs) with Mac OS and Java 7, but more importantly for many software shops and customers, “any application that runs on the Liberty profile will also run on the full product server” – IBM WebSphere Application Server 8.5. Although TomEE runs atop Mac OS with any Java available and Enterprise OSGi may be supported, it is not at the moment which makes Liberty profile a viable candidate for some developers.

Surprisingly, I’m tempted to disregard JBoss AS’s existence. Leaving TomEE and Liberty profile aside, there’s GlassFish out there so if I need a refresher GlassFish does fit well. There’s always the question about the products built atop and supported by application servers (which many consider a commodity like operating systems), but happily IBM keeps me busy on that front, too, after closing Acquisition of Lombardi Software with their Business Process Management (BPM) software and offering the product IBM Business Process Manager (there’s also the announcement about IBM Business Process Manager V8.0 publicly available). There’re plenty of business-oriented products atop IBM WebSphere AS and wish I’d more time to learn them better.

Having said that, I’m certainly concerned with the question “What makes Liberty Profile better than TomEE for a project?” Do you? Please leave your comment so with your help I may draw some conclusions earlier. I’m not going to favor one over the other and technical features do only matter!

p.s. There’s yet another question that takes my attention away – I simply can’t believe why they released the versions now while my brain’s currently overwhelmed to mentally digest the goodness of functional programming (with Clojure). It looks like IT’s not going to be easy any time soon :)

Java EE, WebSphere , 2 Comments

OpenJDK 1.8.0-jdk8-b35 seems to break Leiningen 2

Is it only me experiencing an issue with running the most recent build of Leiningen 2 with the recent OpenJDK 8 x64-lambda JDK with Lambda from jdk8 branch (b35) (OpenJDK-OSX-8-x64-lambda-jdk-b35-20120507) on Mac OS X?

With the version of OpenJDK selected in the Java Preferences, lein2 finishes with a stacktrace.

Here’s the full log of the steps to reproduce the issue. Is it Clojure 1.4 or lein2?

jacek:~/oss/leiningen
$ git pull -u
Already up-to-date.

jacek:~
$ java -version
openjdk version "1.8.0-jdk8-b35"
OpenJDK Runtime Environment (build 1.8.0-jdk8-b35-20120507)
OpenJDK 64-Bit Server VM (build 24.0-b07, mixed mode)

jacek:~/oss/leiningen/leiningen-core
$ lein install
Copying 33 files to /Users/jacek/oss/leiningen/leiningen-core/lib
No namespaces to :aot compile listed in project.clj.
Created /Users/jacek/oss/leiningen/leiningen-core/leiningen-core-2.0.0-SNAPSHOT.jar
Wrote pom.xml
[INFO] Installing /Users/jacek/oss/leiningen/leiningen-core/leiningen-core-2.0.0-SNAPSHOT.jar to
/Users/jacek/.m2/repository/leiningen-core/leiningen-core/2.0.0-SNAPSHOT/leiningen-core-2.0.0-SNAPSHOT.jar

jacek:~
$ lein2 version
Exception in thread "main" java.lang.VerifyError: (class: ordered/map/OrderedMap, method: count signature: ()J) Expecting to find long on stack, compiling:(ordered/map.clj:26)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6462)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.analyze(Compiler.java:6223)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.access$100(Compiler.java:37)
    at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:518)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.analyze(Compiler.java:6223)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5919)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.analyze(Compiler.java:6223)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)
    at clojure.lang.Compiler.analyze(Compiler.java:6262)
    at clojure.lang.Compiler.eval(Compiler.java:6508)
    at clojure.lang.Compiler.load(Compiler.java:6952)
    at clojure.lang.RT.loadResourceScript(RT.java:359)
    at clojure.lang.RT.loadResourceScript(RT.java:350)
    at clojure.lang.RT.load(RT.java:429)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$load_lib.doInvoke(core.clj:5264)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$load_libs.doInvoke(core.clj:5298)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$require.doInvoke(core.clj:5381)
    at clojure.lang.RestFn.invoke(RestFn.java:551)
    at leiningen.core.project$eval22$loading__4784__auto____23.invoke(project.clj:1)
    at leiningen.core.project$eval22.invoke(project.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    at clojure.lang.Compiler.eval(Compiler.java:6501)
    at clojure.lang.Compiler.load(Compiler.java:6952)
    at clojure.lang.RT.loadResourceScript(RT.java:359)
    at clojure.lang.RT.loadResourceScript(RT.java:350)
    at clojure.lang.RT.load(RT.java:429)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$load_lib.doInvoke(core.clj:5264)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$load_libs.doInvoke(core.clj:5298)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$require.doInvoke(core.clj:5381)
    at clojure.lang.RestFn.invoke(RestFn.java:482)
    at leiningen.core.main$eval3$loading__4784__auto____4.invoke(main.clj:1)
    at leiningen.core.main$eval3.invoke(main.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    at clojure.lang.Compiler.eval(Compiler.java:6501)
    at clojure.lang.Compiler.load(Compiler.java:6952)
    at clojure.lang.RT.loadResourceScript(RT.java:359)
    at clojure.lang.RT.loadResourceScript(RT.java:350)
    at clojure.lang.RT.load(RT.java:429)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$load_lib.doInvoke(core.clj:5264)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$load_libs.doInvoke(core.clj:5298)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$require.doInvoke(core.clj:5381)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.main$main_opt.invoke(main.clj:324)
    at clojure.main$main.doInvoke(main.clj:427)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at clojure.lang.Var.invoke(Var.java:423)
    at clojure.lang.AFn.applyToHelper(AFn.java:167)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)
Caused by: java.lang.VerifyError: (class: ordered/map/OrderedMap, method: count signature: ()J) Expecting to find long on stack
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:259)
    at clojure.lang.RT.classForName(RT.java:2039)
    at clojure.lang.Compiler$HostExpr.maybeClass(Compiler.java:957)
    at clojure.lang.Compiler$HostExpr.access$400(Compiler.java:736)
    at clojure.lang.Compiler$NewExpr$Parser.parse(Compiler.java:2473)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)
    ... 93 more

With the version of OpenJDK changed to 1.7.0-jdk7u4-b21, it works fine.

jacek:~
$ java -version
openjdk version "1.7.0-jdk7u4-b21"
OpenJDK Runtime Environment (build 1.7.0-jdk7u4-b21-20120427)
OpenJDK 64-Bit Server VM (build 23.0-b21, mixed mode)

jacek:~
$ lein2 version
Leiningen 2.0.0-SNAPSHOT on Java 1.7.0-jdk7u4-b21 OpenJDK 64-Bit Server VM

jacek:~
$ lein2 repl
nREPL server started on port 60220
Welcome to REPL-y!
Clojure 1.4.0
    Exit: Control+D or (exit) or (quit)
Commands: (user/help)
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
          (user/sourcery function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org: [clojuredocs or cdoc]
          (user/clojuredocs name-here)
          (user/clojuredocs "ns-here" "name-here")
nil
user=> (clojure-version)
"1.4.0"
user=> (leiningen.core.main/leiningen-version)
"2.0.0-SNAPSHOT"
Languages 1 Comment

How F# helped me to appreciate Clojure’s reduce to traverse data structures (XMLs)

I’ve no doubt that the book Real-World Functional Programming – With examples in F# and C# by Tomas Petricek and Jon Skeet will make me a better functional programmer and have often found it very enlightening. I haven’t done with its reading, but my meetup with it won’t finish once read. It’s too valuable to put on a bookshelf and let it get forgotten. Functional programming is so much easier with the book!

It’s about F# yet I’m reading it to understand functional programming better. F# is just another language. What matters is that it’s a functional language and its syntax doesn’t bother me. Moreover, I found the language highly intuitive and similar to Scala (they say it’s because they borrowed a lot from OCaml). I simply don’t mind learning yet another functional language provided it makes my foray into functional paradigm easier and faster. Even if it’s a non-JVM functional language.

On page 367, there’s a sample with Seq.fold to traverse a XPath-like path in a XML. I burnt a few brain cycles before I figured out how it works. It’s simple, but it wasn’t almost half a day before. That’s that sort of examples I enjoy the most. They’re usually short yet powerful and their understanding doesn’t come for free – you need to spend some time and think. Think a lot!

Here’s a session with Clojure REPL to have a version in Clojure.

;; Let's have a data structure - a map with other, nested maps
;; One could see it as an XML-like data structure.
;; I did.

user=> (def req (update-in {} [:a :b :c :d] (fn [v] "value")))
#'user/req
user=> req
{:a {:b {:c {:d "value"}}}}

;; Let's define a function xelem that accepts a key (a tag) and a map (a node).

user=> (defn xelem [s el] (s el))
#'user/xelem

;; Let's have some fun and play with the function.

user=> (xelem :a req)
{:b {:c {:d "value"}}}
user=> (xelem :b (xelem :a req))
{:c {:d "value"}}
user=> (->> (xelem :a req) (xelem :b))
{:c {:d "value"}}

;; I played until I found out the following:

user=> (->> req (xelem :a) (xelem :b) (xelem :c) (xelem :d))
"value"

;; It's that calling a key with a map in sequence gives you the value.

;; Let's define a XPath-like path to the value.

user=> (def path [:a :b :c :d])
#'user/path

;; With reduce life became so easy.
;; Or was it because of the book?!
;; I think both.

user=> (reduce (fn [v1 v2] (println "DEBUG v1:" v1 "v2:" v2) (xelem v2 v1)) req path)
DEBUG v1: {:a {:b {:c {:d value}}}} v2: :a
DEBUG v1: {:b {:c {:d value}}} v2: :b
DEBUG v1: {:c {:d value}} v2: :c
DEBUG v1: {:d value} v2: :d
"value"

;; The book "Real-World Functional Programming" uses the pipelining operator |>,
;; and Clojure provides the threading macros: -> or ->>

user=> (->> path
            (reduce (fn [xn s]
                      (xelem s xn)) req))
"value"

;; I like the book, F#, Clojure and learning!
Languages , 4 Comments

Reversi in Clojure…functional

Reversi in Clojure w/ Three Alternative User Interfaces is the type of blog entries I enjoy the most – it inspired me to think about functional programming in Clojure and found it a great “platform” to work on my understanding of Clojure’s way to functional programming. I hope I didn’t mess it up and am on my way to functional programming nirvana.

The idea was to find all the places where mutation happens or may be incurred (due to a type/data structure used) and find their functional counterparts.

The very first finding was the if statement in the function opposite-piece. As I wrote in the blog entry Protocols more functional than if in Clojure?, I tend to believe that the if function resembles the imperative if statement so much that whenever I find it in a code, it encourages me to think about another approach.

What about this version of the opposite-piece function?

(defn opposite-piece-with-map [piece]
  "Change white to black and vice versa"
  (let [conversion-map {:w :b :b :w}]
    (conversion-map piece)))

To me it looks more functional.

The other piece of the code I found intriguing was the function initialize-board which uses a less functional data structure – a vector – not an immutable list – the truly functional data structure (which was the foundation for Lisp and later Clojure). I think a list (or a sequence in general) invites to a thinking in a functional way, with no way to mutate its content since it’s immutable by design (so is a vector in Clojure, but it may easily mislead an untrained reader coming from Java or another OOP language).

I consider a vector an imperative data structure and a sort of mutable list or vice versa – a list as an immutable vector (even though the distinction doesn’t exist in Clojure). I’ve seen lists used instead and whenever it happened it was a mental challenge for me. I enjoyed it and was keen on introducing it in the game.

So, from that moment on, I was using a list not a vector in initialize-board. And the fun began!

As a starter, let’s consider the following 3×3 board with 0′s.

(def board (repeat 9 0))

I wish I could have a picture of a board to accompany the snippets.

You may also use the function partition.

How could you change, say increase, the 0′s in the position you’d call (2,2) – the central 0? Let’s assume we start counting the rows and the columns from 1 onwards.

The pure function could look as follows:

(defn inc-at-v1 [board row col]
  (let [split-pos  (+ (* 3 (dec row)) col)
        f inc]
    (concat (take (dec split-pos) board)
            (list (f (nth board (dec split-pos))))
            (drop split-pos board))))

Let’s see how it works.

user=> (inc-at-v1 board 2 2)
(0 0 0 0 1 0 0 0 0)

It works! My very first take on refactoring of the game to a more functional version works well.

There’s a serious issue, though. We iterate over the sequence board three times – once when we calculate the elements for the left side of the output sequence, another to get at the value to increment and yet another for the right side. It’s certainly not very efficient.

The other solution was a recursion with a counter – a sort of functional for (not to be confused with the for function for list comprehension).

(defn inc-at-v2
  ([board row col]
    (let [split-pos  (dec (+ (* 3 (dec row)) col))
          split-fn (fn [idx e]
                     (cond (< idx split-pos) e
                           (= idx split-pos) (inc e)
                           (> idx split-pos) e))]
      (map-indexed split-fn board))))

Let’s give it a shot!

user=> (inc-at-v2 board 2 2)
(0 0 0 0 1 0 0 0 0)
user=> (inc-at-v2 board 2 3)
(0 0 0 0 0 1 0 0 0)
user=> (inc-at-v2 board 3 3)
(0 0 0 0 0 0 0 0 1)

It works fine again. Is it better? I’m still unconvinced, esp. the split-fn looks terribly. I need a version without any mutation, even with atoms, refs or agents. Would you mind lending me a helping hand? How would you change the function inc-at-v2 to be more effective and look prettier?

Languages 7 Comments

Java 7 New Features Cookbook give-away contest

I’ve been a technical reviewer for the book Java 7 New Features Cookbook from Packt and it’s now available in the bookstores near you (Amazon.com comes to my mind, but guess it should be nearer, too).

Packt runs a couple of promotional activities around the book and they asked me if I could run a giveaway contest on my blog. I’ve happily accepted the offer as I believe the book should in most cases be worth your time. Be warned, though. I did review the book, albeit many of my comments did not make it to the final version of the book, so I’m not going to say it’s an excellent book – it’s useful enough to take your chance in a drawing to have your own free copy.

Here are the rules:

Book Give-away: Hold a chance to win a free copy of the Java 7 New Features Cookbook just by commenting!

For the contest Packt have two copies of Java 7 New Features Cookbook, to be given away to two lucky winners.

How you can win:

To win your copy of this book, all you need to do is come up with a comment below highlighting the reason “why you would like to win this book”.

Duration of the contest & selection of winners:

The contest is valid for the upcoming 7 (seven) days, and is open to everyone. The contest starts now and winners will be selected on the basis of their comment posted in random order. I’ll do the selection in Clojure so it should be fair enough.

About the book:

Java 7 New Features Cookbook is a Step-by-step instructions to utilize improved access to mouse buttons and the mouse wheel along with additional event handling support, master the new row set interfaces and control of the database schema and other such new exciting features are also designed in the book.

Java 7 New Features Cookbook covers the details of using the numerous Graphical User Interface improvements including window methods, the new JLayer class and various dialog box-related methods to perform asynchronous IO in Java 7. It enables developers to manage threads using the join/fork paradigm and use new data structures.

Languages 11 Comments

Java EE and Clojure on Allegro RoadShow in Torun

Clojure makes my life so much fun!

I’ve recently been invited for a talk about my current interests in functional programming during Allegro RoadShow in Torun and chose Clojure with Java EE 6 as the topic to present. It has been an event where an employee of Allegro – *the* e-commerce company in Poland – talked about his job and what tools they use. I was there too to shed some light on alternative language – Clojure. And that brought so much fun!

My session was supposed to take 35 minutes only, so I jumped right into the Clojure REPL after a 5-minute introduction (of mine and Clojure itself). I made a quick decision to showcase how to develop a servlet with a helper function in Clojure – a module for the front-end in Java EE and another for the back-end in Clojure. I used Leiningen to build the Clojure project, Maven to build the webapp project and finally deployed it onto Apache Tomcat. The other part was about developing web applications with Ring. I knew Vars could do the magic very easy – no server restarts to introduce a new functionality. HTTP requests and responses as maps in Ring helped enormously, too. I’m not sure they had enough time to appreciate the simplicity.

The event was held at University of Torun, the Computer Science department.

  • There were ca 60 attendees
  • When I asked about their familiarity of Java EE, 2 people raised their hand.
  • When I asked about Java, 20 people raised their hand.
  • Some exposure to functional languages? 10 people nodded.

It was a very varied audience and wonder whether I could whet their appetite for more better. I seem to have noticed some interest, so I do hope more people would accept a functional programming language as the language of choice for a project. At last, they know it’s possible to do some web development.

Java EE, Languages 2 Comments

Protocols more functional than if in Clojure?

While reading Ring Handlers – Functional Decorator Pattern

How often do you perform conditional branching with if? The answer may likely rely upon the available features offered by the language of choice – the if statement/expression (Java, Clojure), pattern matching (F#) and dynamic dispatch (Java, Clojure).

When I read Conditional (programming) in Wikipedia I stumbled upon the following sentence:

“Although dynamic dispatch is not usually classified as a conditional construct, it is another way to select between alternatives at runtime.”

It made me think about its implementation in Clojure. I could definitely tackle it with method overloading in Java (that was dumb easy to figure out), but what about Clojure?

At the moment I’d come up with a possible implementation in Java, Clojure’s Protocols sprung to my mind. I’ve been reading about them, mainly in books and very rarely in articles, and have never used the concept before. It looked like it’d change.

Protocols are like interfaces in Java and beg no special treatment of nil (counterpart of Java’s null which begs a casting to appropriate type).

Below you can find a simple Protocol implementation in Clojure and its use. Fire up lein2 repl and follow along.

;; I'm aiming at simplifying the following function from the article Ring Handlers – Functional Decorator Pattern
;; It's actually Ring's function
user=> #_
(defn wrap-params
  [handler & [opts]]
  (fn [request]
    (let [request  (if (:query-params request)
                           request
                           (assoc-query-params request))]
      (handler request))))

;; I'm mostly interested in the if expression in let
user=> #_
(if (:query-params request)
    request
    (assoc-query-params request))

;; the very first version to demonstrate protocols
user=> (defprotocol IfProtocol
         "A better if - an if or cond alternative - ver.1"
         (if++ [this] "A single protocol method"))
IfProtocol
user=> (extend-protocol IfProtocol
         nil
         (if++ [_] "Nil")
         Object
         (if++ [_] "Object"))
nil
user=> (if++ nil)
"Nil"
user=> (if++ "a string")
"Object"

;; a two-argument version
user=> (defprotocol IfProtocol
         "A better if - an if or cond alternative"
         (if++ [this rq] "A single protocol method with a request"))
IfProtocol
user=> (extend-protocol IfProtocol
         nil
         (if++ [_ rq] (str "Nil with " rq))
         Object
         (if++ [_ rq] (str "Object with " rq)))
nil
user=> (if++ nil 1)
"Nil with 1"
user=> (if++ "A string" 1)
"Object with 1"

;; the final version - extending the protocol one type at a time
user=> (extend-protocol IfProtocol Object (if++ [_ rq] rq))
nil
user=> (defn assoc-query-params [rq]
         (str "Processing " rq))
#'user/assoc-query-params
user=> (extend-protocol IfProtocol nil (if++ [_ request] (assoc-query-params request)))
nil

;; Testing...

user=> (defn f [request]
         (let [request  (if++ (:query-params request) request)]
           request))
#'user/f
user=> (f {})
"Processing {}"
user=> (f {:query-params 1})
{:query-params 1}

;; the function from the article with if++
user=> (defn wrap-params
         [handler & [opts]]
         (fn [request]
           (let [request  (if++ (:query-params request) request)]
             (handler request))))
#'user/wrap-params

;; more testing
user=> (def wp (wrap-params identity))
#'user/wp
user=> (wp {})
"Processing {}"
user=> (wp {:query-params 1})
{:query-params 1}

It works, but I’m still uncertain about its applicability for a simple if-then expression, meaning as an alternative for a flat, single if-then expression as in the use case above. It appears to bring no value in simple cases and may result in more work for not much benefit. Does it?

You may also find OCaml: Pattern matching vs If/else statements or if-else branching in clojure useful to tackle the issue. The last reference made me thinking about nested if statements with their own else branches. Doh, I thought I was done with it.

There’s also Clojure’s multimethods concept which seem as much applicable to the use case as protocols. Doh doubled.

I’ve also added org.clojure/core.match to a S.I.L (= Seemingly Inevitable to Learn) bucket.

Languages 7 Comments

Clojure and me at devCrowd.pl

Clojure

The past Saturday I was on devCrowd.pl in Szczecin, Poland where I ran two sessions about Clojure as a functional programming language to develop web applications. I don’t have slides to share as they were (supposed to have been) live coding sessions about what Clojure can offer for web development. The first session was after a talk about functional programming in a day-job development by Sebastian Pietrowski (@pedrowaty) and I wished I’d skipped the introductory part in my talk to spare more time for the demo instead.

It was a made-in-heaven, always-dreamt-of conference where not only could I demo Clojure in a 1-hour session with around 40 people (off 120 registered for the conference at that time and with a workshop about node.js and a talk about IT project management in parallel), but also ran another 1-hour live coding session organized in a hurry yet attracted ca. 10 people (some even left the Scala workshop!) when a speaker didn’t make it to the conference. I’m so glad the organizators ultimately convinced me to have run it for the price of me skipping a Scala workshop. It was definitely worth it!

“Always choose wisely” – they say. When faced with a choice of attending a session or leading one, I’d pick the later. It’s a no-brainer now.

After having spent 2 hours with the audience I could experience an addictive feel of empowerment, esp. when I was convinced to have done things in Clojure I really shouldn’t have in public with no prior preparation. It was very risky, but once done, it turned out easy and worth the effort. I felt as if I had grasped the most of Clojure. No macros were presented, though, as I had not studied and practiced them much.

I was afraid that finding a good balance between introducing Clojure with slides and later the live coding sessions might’ve been a huge undertaking, but the comments on twitter (#devcrowdpl + @jaceklaskowski) about my sessions seem to prove that people might’ve enjoyed the sessions. I also managed to speak to a few people who spent some time with functional languages – Clojure and F#.

I had a cheatsheet on my Android mobile device to cover my back in case of troubles which was very helpful at times.

The live coding session started with a lein2 project – lein2 new, lein2 run -m to have it run standalone with lein2 uberjar after :gen-class and :main true (in the Clojure namespace) and :aot (in the project.clj) were added and explained a bit. With a minor hitch, it went very smoothly. With the standalone jar I managed to demo a standalone Java application to call the Clojure namespace. No problems along the way (I was so much surprised to have done it with no issues!) Then I switched to lein2 repl and played with integrated pomegrade and ring-jetty-adapter. I used a var of a handler right away to handle HTTP requests and showed how to change the handler dynamically. As the last step in the demo, I had a var with a function that was used by a Thread and used telnet to access the REPL to change the function at runtime with no interruption to the running thread. A bit of Eclipse with Counterclockwise, more introduction to functional programming with Clojure with map, reduce and filter amongst the other features (immutable data structures) concluded the sessions.

I’m going to described the parts of my sessions which have not yet found their place in my blog. Stay tuned.

Should you want to join a live coding session with Clojure and me, I wholeheartedly recommend to attend the presentations of mine on 4Developers in Poznan on 18. April, GeeCON in Poznan on 18. May and hopefully Confitura in Warsaw on 30. June.

p.s. I felt in love with functional programming with Clojure and F# so much that I could very likely consider a job as a team leader or a lead developer, too.

Languages , 4 Comments

Mocking out in Clojure with with-redefs-fn (no Midje this time)

I made some changes in a Clojure project – librarian-clojure. The changes revolved around security in a Compojure web application. What I needed was to check whether they’re correct and hence I needed some tests with mocking involved because the functions the changes were introduced to used external sources – MongoDB and an encryption library. I didn’t mean to set up the environment, but just enough to get the task done. And it should be fast and quick.

The functions are used in a web application, but neither a web container nor a Request object was necessary since Ring turns HTTP requests into…maps. Moreover, I knew Clojure could replace function definition (a var) on the fly for a single thread with binding, but Clojure 1.3 comes with the with-redefs-fn function that “Temporarily redefines Vars during a call to func. (…) Useful for mocking out functions during testing.” I didn’t have to define a dependency and have a framework to work with. Life couldn’t have been easier!

I’ve been doing Java programming for years, but only recently have I been exposed to the aspects of Test-Driven Development (TDD). I think I know the benefits and the rules, but applying TDD was more a belief in its added value not a way to think. I simply didn’t care (perhaps because I wasn’t paid for programming and was only doing it in my spare time, often sidetracked by other activities).

I’ve also been leaning quite recently towards believing that despite repeated assurances of TDD applicability to and increased quality of applications developed in Java or any object-oriented languages, TDD was simply too laborious.

I think that TDD in Clojure (or any functional language) is so much easier and…fun!

Firstly, there’s a REPL where you can do it interactively. Secondly, Clojure’s dynamic. Thirdly, there’s no “overhead” with object-oriented hierarchy since “weakly” structures like maps suffice. All these seem to suggest that Clojure may easily be the language of choice for TDD.

Have a look at the following session in Clojure’s REPL to experience it yourself. Even thought it’s far from TDD, it led to using the fake functions with no pain (and eventually I found out that Midje might’ve done it better. Next time.)

user=> (use 'librarian-clojure.security)
nil
user=> (def request {:params {:login "jacek" :password "secr3t"}})
#'user/request
user=> (log-in request)
AssertionError Assert failed: (somnium.congomongo/connection? c__793__auto__)  librarian-clojure.db/db-get-user (db.clj:63)
user=> ;; no CongoDB up and running - mock its availability
user=> (def ^:dynamic db-get-user)
#'user/db-get-user
user=> (binding [db-get-user (fn [v] (println "user: " v) v)]
         (log-in request))
AssertionError Assert failed: (somnium.congomongo/connection? c__793__auto__)  librarian-clojure.db/db-get-user (db.clj:63)
user=> ;; it doesn't seem to work for another namespace's vars - a bit of Google'ing and with-redefs-fn shows up
user=> (with-redefs-fn {#'librarian-clojure.db/db-get-user (fn [v] (println "user: " v) {:password "secr3t" :roles #{:admin}})
                        #'librarian-clojure.security/check-password (fn [cd cr] (println "candidate: " cd " crypt: " cr) true)}
              #(librarian-clojure.security/log-in request))
user:  jacek
candidate:  secr3t  crypt:  secr3t
{:name "jacek", :roles #{:admin}}
Languages Leave a comment

Clojure easier? s/lein/lein2 – pomegranate is there already

After I published the blog entry Clojure’s REPL, lein, pomegranate and classpath, Sun Ning commented that lein2 uses pomegranate internally as the dependency resolution management tool. Well, it was a bit convoluted in a sense, but meant exactly this. It later turned out that a single sentence “Leiningen 2 has move its dependency management core to a new library, called pomegranate.” made my day as developing Clojure applications in Clojure’s REPL became even easier. I guess also that presenting Clojure development live should change, too.

From now on, I become a proponent of using lein2 as a mandatory management tool for people who start their journey into Clojure. Consult the Installation section in Leiningen’s README.

Give yourself a couple of minutes to have a better exposure for the changes.

  1. Run lein2 repl.
  2. Execute (use ‘[cemerick.pomegranate :only (add-dependencies)]).
  3. Use (add-dependencies).
jacek:~/sandbox
$ lein2 version
Leiningen 2.0.0-SNAPSHOT on Java 1.7.0-jdk7u4-b19 OpenJDK 64-Bit Server VM
jacek:~/sandbox
$ lein2 repl
nREPL server started on port 56376
Welcome to REPL-y!
Clojure 1.3.0
    Exit: Control+D or (exit) or (quit)
Commands: (help)
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
          (sourcery function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org:
          (clojuredocs name-here)
          (clojuredocs "ns-here" "name-here")
nil
user=> (clojure-[TAB]
user=> (clojure-version)
"1.3.0"
user=> (use '[cemerick.pomegranate :only (add-dependencies)])
nil
user=> (add-dependencies :coordinates '
[[compojure "1.0.1"]])
{[javax.servlet/servlet-api "2.5"] nil, [clout "1.0.1"] nil, [org.clojure/core.incubator "0.1.0"] nil, [ring/ring-core "1.0.1"] #{[javax.servlet/servlet-api "2.5"] [commons-io "1.4"] [commons-codec "1.4"] [commons-fileupload "1.2.1"]}, [org.clojure/tools.macro "0.1.0"] nil, [commons-io "1.4"] nil, [compojure "1.0.1"] #{[clout "1.0.1"] [org.clojure/core.incubator "0.1.0"] [ring/ring-core "1.0.1"] [org.clojure/tools.macro "0.1.0"] [org.clojure/clojure "1.2.1"]}, [org.clojure/clojure "1.2.1"] nil, [commons-codec "1.4"] nil, [commons-fileupload "1.2.1"] nil}
user=> (use '[compojure.core :only (defroutes)])
nil
user=> (defroutes app)
#'
user/app

You may also want to read in which we coin a term which is the opposite of deprecate about the other reasons to switch to lein2. Don’t forget to read the comment for the blog entry:

“Somehow I forgot to mention that the repl task has been totally rewritten in Leiningen 2; it features readline-ish input without rlwrap and has great completion.”

I must admit I hadn’t noticed it before having read the comment, but had been using it already (!) I tend to get used to useful features very easily without noticing it.

Lots of great stuff in lein2. See Leiningen’s Upgrading for more.

Thanks Chas, Phil and Sun Ning! I’m deeply indebted to you for your help. Gonna use it during the upcoming conferences in Poland where I’m presenting Clojure: DevCrowd, 4Developers, GeeCON and hopefully Confitura.

Languages 1 Comment