<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Japila :: verba docent, exempla trahunt</title>
	
	<link>http://blog.japila.pl</link>
	<description>Functional programming with Clojure, Java EE, and IBM WebSphere</description>
	<lastBuildDate>Mon, 14 May 2012 12:12:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/blog-japila-pl" /><feedburner:info uri="blog-japila-pl" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>blog-japila-pl</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Why would I prefer Liberty Profile over TomEE?! No easy answer</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/ITkMlL1XZG0/</link>
		<comments>http://blog.japila.pl/2012/05/why-would-i-prefer-liberty-profile-over-tomee-no-easy-answer/#comments</comments>
		<pubDate>Mon, 14 May 2012 12:12:32 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Java EE]]></category>
		<category><![CDATA[WebSphere]]></category>
		<category><![CDATA[IBM WebSphere AS]]></category>
		<category><![CDATA[TomEE]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=988</guid>
		<description><![CDATA[That&#8217;s the question which keeps bothering me lately: &#8220;Why would I prefer IBM WebSphere Application Server V8.5 Liberty Profile over Apache TomEE?&#8221; I&#8217;m pretty sure I&#8217;m not alone who struggles with the question and there&#8217;ll be more people soon. Since they&#8217;re new product offerings such questions will pop up quite often. TomEE has just passed [...]]]></description>
			<content:encoded><![CDATA[<p>That&#8217;s the question which keeps bothering me lately: &#8220;Why would I prefer <a href="http://wasdev.net">IBM WebSphere Application Server V8.5 Liberty Profile</a> over <a href="http://openejb.apache.org/apache-tomee.html">Apache TomEE</a>?&#8221;</p>
<p>I&#8217;m pretty sure I&#8217;m not alone who struggles with the question and there&#8217;ll be more people soon. Since they&#8217;re new product offerings such questions will pop up quite often.</p>
<p><a href="https://blogs.apache.org/openejb/entry/apache_tomee_1_0_final">TomEE has just passed the vote for public consumption as the version 1.0</a>. At almost the same time <a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/wasdev/entry/websphere_application_server_v8_5_announced_april_24th12">&#8220;IBM officially announced a new developer friendly light-weight web app server called WAS V8.5 &#8211; Liberty Profile&#8221;</a>. And there&#8217;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.</p>
<p><em>&#8220;Why am I concerned?&#8221;</em>, you may ask. It&#8217;s not very often when you&#8217;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&#8217;s a big deal?! Well, I&#8217;m an IBMer <strong>and</strong> a member of the Apache TomEE project.</p>
<p>I&#8217;ve been always wishing that IBM would release an application server like the Liberty Profile. It&#8217;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&#8217;t easy, but OSGi made the difference and I believed it would eventually turn the product to become the leader. I&#8217;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&#8217;t care).</p>
<p>I was really happy when IBM unveiled IBM WebSphere Application Server V8 as <a href="http://www.infoq.com/news/2011/06/was8-released">&#8220;the third application to be certified with full Java EE 6 Profile, following on from Oracle&#8217;s GlassFish Open Source Edition 3.x and upwards, and JEUS 7 from TmaxSoft.&#8221;</a> 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&#8217;ve never seen JEUS 7 as the platform, it&#8217;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!</p>
<p>IBM didn&#8217;t stop it, but neither did the competition. Apache TomEE has a great potential to catch people&#8217;s attention for its simplicity as <a href="http://openejb.apache.org/apache-tomee.html">&#8220;The result is Tomcat with added EE features, TomEE.&#8221;</a></p>
<p>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 <a href="http://openejb.apache.org/index.html">&#8220;is an all-Apache Java EE 6 Web Profile certified stack where Tomcat is top dog&#8221;</a> which Liberty Profile would not likely soon achieve. On the other hand, <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/beta/topic/com.ibm.websphere.wlp.nd.doc/topics/cwlp_about.html">Liberty profile supports Enterprise OSGi (OSGi Blueprint and WABs) with Mac OS and Java 7</a>, but more importantly for many software shops and customers, <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/beta/topic/com.ibm.websphere.wlp.doc/topics/thread_twlp_devenv.html">&#8220;any application that runs on the Liberty profile will also run on the full product server&#8221;</a> &#8211; 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.</p>
<p>Surprisingly, I&#8217;m tempted to disregard JBoss AS&#8217;s existence. Leaving TomEE and Liberty profile aside, there&#8217;s GlassFish out there so if I need a refresher GlassFish does fit well. There&#8217;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 <a href="http://www.ibm.com/press/us/en/pressrelease/29238.wss">closing Acquisition of Lombardi Software</a> with their Business Process Management (BPM) software and offering the product <a href="http://www.ibm.com/software/integration/business-process-manager/">IBM Business Process Manager</a> (there&#8217;s also <a href="http://www-01.ibm.com/support/docview.wss?uid=swg21590559">the announcement about IBM Business Process Manager V8.0</a> publicly available). There&#8217;re plenty of business-oriented products atop IBM WebSphere AS and wish I&#8217;d more time to learn them better.</p>
<p>Having said that, I&#8217;m certainly concerned with the question &#8220;What makes Liberty Profile better than TomEE for a project?&#8221; Do you? Please leave your comment so with your help I may draw some conclusions earlier. I&#8217;m not going to favor one over the other and technical features do only matter!</p>
<p>p.s. There&#8217;s yet another question that takes my attention away &#8211; I simply can&#8217;t believe why they released the versions now while my brain&#8217;s currently overwhelmed to mentally digest the goodness of functional programming (with Clojure). It looks like IT&#8217;s not going to be easy any time soon :)</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/ITkMlL1XZG0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/05/why-would-i-prefer-liberty-profile-over-tomee-no-easy-answer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/05/why-would-i-prefer-liberty-profile-over-tomee-no-easy-answer/</feedburner:origLink></item>
		<item>
		<title>OpenJDK 1.8.0-jdk8-b35 seems to break Leiningen 2</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/H_DGleV0xh0/</link>
		<comments>http://blog.japila.pl/2012/05/openjdk-1-8-0-jdk8-b35-seems-to-break-leiningen-2/#comments</comments>
		<pubDate>Thu, 10 May 2012 21:47:04 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=982</guid>
		<description><![CDATA[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&#8217;s the full log of the [...]]]></description>
			<content:encoded><![CDATA[<p>Is it only me experiencing an issue with running the most recent build of <a href="https://github.com/technomancy/leiningen">Leiningen 2</a> with the recent <a href="http://code.google.com/p/openjdk-osx-build/downloads/detail?name=OpenJDK-OSX-8-x64-lambda-jdk-b35-20120507.dmg">OpenJDK 8 x64-lambda JDK with Lambda from jdk8 branch (b35) (OpenJDK-OSX-8-x64-lambda-jdk-b35-20120507)</a> on Mac OS X?</p>
<p>With the version of OpenJDK selected in the Java Preferences, lein2 finishes with a stacktrace.</p>
<p><a href="http://blog.japila.pl/wp-content/uploads/2012/05/java-preferences-java8-lambda-breaks-lein2.png"><img src="http://blog.japila.pl/wp-content/uploads/2012/05/java-preferences-java8-lambda-breaks-lein2-300x227.png" alt="" title="java-preferences-java8-lambda-breaks-lein2" width="300" height="227" class="aligncenter size-medium wp-image-983" /></a></p>
<p>Here&#8217;s the full log of the steps to reproduce the issue. Is it Clojure 1.4 or lein2?</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jacek:~/oss/leiningen<br />
$ git pull -u<br />
Already up-to-date.<br />
<br />
jacek:~<br />
$ java -version<br />
openjdk version &quot;1.8.0-jdk8-b35&quot;<br />
OpenJDK Runtime Environment (build 1.8.0-jdk8-b35-20120507)<br />
OpenJDK 64-Bit Server VM (build 24.0-b07, mixed mode)<br />
<br />
jacek:~/oss/leiningen/leiningen-core<br />
$ lein install<br />
Copying 33 files to /Users/jacek/oss/leiningen/leiningen-core/lib<br />
No namespaces to :aot compile listed in project.clj.<br />
Created /Users/jacek/oss/leiningen/leiningen-core/leiningen-core-2.0.0-SNAPSHOT.jar<br />
Wrote pom.xml<br />
[INFO] Installing /Users/jacek/oss/leiningen/leiningen-core/leiningen-core-2.0.0-SNAPSHOT.jar to<br />
/Users/jacek/.m2/repository/leiningen-core/leiningen-core/2.0.0-SNAPSHOT/leiningen-core-2.0.0-SNAPSHOT.jar<br />
<br />
jacek:~<br />
$ lein2 version<br />
Exception in thread &quot;main&quot; java.lang.VerifyError: (class: ordered/map/OrderedMap, method: count signature: ()J) Expecting to find long on stack, compiling:(ordered/map.clj:26)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6462)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6223)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.access$100(Compiler.java:37)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:518)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6443)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6223)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5919)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6223)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5618)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5054)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3674)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6453)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyze(Compiler.java:6262)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.eval(Compiler.java:6508)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.load(Compiler.java:6952)<br />
&nbsp; &nbsp; at clojure.lang.RT.loadResourceScript(RT.java:359)<br />
&nbsp; &nbsp; at clojure.lang.RT.loadResourceScript(RT.java:350)<br />
&nbsp; &nbsp; at clojure.lang.RT.load(RT.java:429)<br />
&nbsp; &nbsp; at clojure.lang.RT.load(RT.java:400)<br />
&nbsp; &nbsp; at clojure.core$load$fn__4890.invoke(core.clj:5415)<br />
&nbsp; &nbsp; at clojure.core$load.doInvoke(core.clj:5414)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:408)<br />
&nbsp; &nbsp; at clojure.core$load_one.invoke(core.clj:5227)<br />
&nbsp; &nbsp; at clojure.core$load_lib.doInvoke(core.clj:5264)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:142)<br />
&nbsp; &nbsp; at clojure.core$apply.invoke(core.clj:603)<br />
&nbsp; &nbsp; at clojure.core$load_libs.doInvoke(core.clj:5298)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:137)<br />
&nbsp; &nbsp; at clojure.core$apply.invoke(core.clj:603)<br />
&nbsp; &nbsp; at clojure.core$require.doInvoke(core.clj:5381)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:551)<br />
&nbsp; &nbsp; at leiningen.core.project$eval22$loading__4784__auto____23.invoke(project.clj:1)<br />
&nbsp; &nbsp; at leiningen.core.project$eval22.invoke(project.clj:1)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.eval(Compiler.java:6511)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.eval(Compiler.java:6501)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.load(Compiler.java:6952)<br />
&nbsp; &nbsp; at clojure.lang.RT.loadResourceScript(RT.java:359)<br />
&nbsp; &nbsp; at clojure.lang.RT.loadResourceScript(RT.java:350)<br />
&nbsp; &nbsp; at clojure.lang.RT.load(RT.java:429)<br />
&nbsp; &nbsp; at clojure.lang.RT.load(RT.java:400)<br />
&nbsp; &nbsp; at clojure.core$load$fn__4890.invoke(core.clj:5415)<br />
&nbsp; &nbsp; at clojure.core$load.doInvoke(core.clj:5414)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:408)<br />
&nbsp; &nbsp; at clojure.core$load_one.invoke(core.clj:5227)<br />
&nbsp; &nbsp; at clojure.core$load_lib.doInvoke(core.clj:5264)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:142)<br />
&nbsp; &nbsp; at clojure.core$apply.invoke(core.clj:603)<br />
&nbsp; &nbsp; at clojure.core$load_libs.doInvoke(core.clj:5298)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:137)<br />
&nbsp; &nbsp; at clojure.core$apply.invoke(core.clj:603)<br />
&nbsp; &nbsp; at clojure.core$require.doInvoke(core.clj:5381)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:482)<br />
&nbsp; &nbsp; at leiningen.core.main$eval3$loading__4784__auto____4.invoke(main.clj:1)<br />
&nbsp; &nbsp; at leiningen.core.main$eval3.invoke(main.clj:1)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.eval(Compiler.java:6511)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.eval(Compiler.java:6501)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.load(Compiler.java:6952)<br />
&nbsp; &nbsp; at clojure.lang.RT.loadResourceScript(RT.java:359)<br />
&nbsp; &nbsp; at clojure.lang.RT.loadResourceScript(RT.java:350)<br />
&nbsp; &nbsp; at clojure.lang.RT.load(RT.java:429)<br />
&nbsp; &nbsp; at clojure.lang.RT.load(RT.java:400)<br />
&nbsp; &nbsp; at clojure.core$load$fn__4890.invoke(core.clj:5415)<br />
&nbsp; &nbsp; at clojure.core$load.doInvoke(core.clj:5414)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:408)<br />
&nbsp; &nbsp; at clojure.core$load_one.invoke(core.clj:5227)<br />
&nbsp; &nbsp; at clojure.core$load_lib.doInvoke(core.clj:5264)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:142)<br />
&nbsp; &nbsp; at clojure.core$apply.invoke(core.clj:603)<br />
&nbsp; &nbsp; at clojure.core$load_libs.doInvoke(core.clj:5298)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:137)<br />
&nbsp; &nbsp; at clojure.core$apply.invoke(core.clj:603)<br />
&nbsp; &nbsp; at clojure.core$require.doInvoke(core.clj:5381)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:408)<br />
&nbsp; &nbsp; at clojure.main$main_opt.invoke(main.clj:324)<br />
&nbsp; &nbsp; at clojure.main$main.doInvoke(main.clj:427)<br />
&nbsp; &nbsp; at clojure.lang.RestFn.invoke(RestFn.java:436)<br />
&nbsp; &nbsp; at clojure.lang.Var.invoke(Var.java:423)<br />
&nbsp; &nbsp; at clojure.lang.AFn.applyToHelper(AFn.java:167)<br />
&nbsp; &nbsp; at clojure.lang.Var.applyTo(Var.java:532)<br />
&nbsp; &nbsp; at clojure.main.main(main.java:37)<br />
Caused by: java.lang.VerifyError: (class: ordered/map/OrderedMap, method: count signature: ()J) Expecting to find long on stack<br />
&nbsp; &nbsp; at java.lang.Class.forName0(Native Method)<br />
&nbsp; &nbsp; at java.lang.Class.forName(Class.java:259)<br />
&nbsp; &nbsp; at clojure.lang.RT.classForName(RT.java:2039)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$HostExpr.maybeClass(Compiler.java:957)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$HostExpr.access$400(Compiler.java:736)<br />
&nbsp; &nbsp; at clojure.lang.Compiler$NewExpr$Parser.parse(Compiler.java:2473)<br />
&nbsp; &nbsp; at clojure.lang.Compiler.analyzeSeq(Compiler.java:6455)<br />
&nbsp; &nbsp; ... 93 more</div></div>
<p>With the version of OpenJDK changed to 1.7.0-jdk7u4-b21, it works fine.</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jacek:~<br />
$ java -version<br />
openjdk version &quot;1.7.0-jdk7u4-b21&quot;<br />
OpenJDK Runtime Environment (build 1.7.0-jdk7u4-b21-20120427)<br />
OpenJDK 64-Bit Server VM (build 23.0-b21, mixed mode)<br />
<br />
jacek:~<br />
$ lein2 version<br />
Leiningen 2.0.0-SNAPSHOT on Java 1.7.0-jdk7u4-b21 OpenJDK 64-Bit Server VM<br />
<br />
jacek:~<br />
$ lein2 repl<br />
nREPL server started on port 60220<br />
Welcome to REPL-y!<br />
Clojure 1.4.0<br />
&nbsp; &nbsp; Exit: Control+D or (exit) or (quit)<br />
Commands: (user/help)<br />
&nbsp; &nbsp; Docs: (doc function-name-here)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (find-doc &quot;part-of-name-here&quot;)<br />
&nbsp; Source: (source function-name-here)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (user/sourcery function-name-here)<br />
&nbsp;Javadoc: (javadoc java-object-or-class-here)<br />
Examples from clojuredocs.org: [clojuredocs or cdoc]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (user/clojuredocs name-here)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (user/clojuredocs &quot;ns-here&quot; &quot;name-here&quot;)<br />
nil<br />
user=&gt; (clojure-version)<br />
&quot;1.4.0&quot;<br />
user=&gt; (leiningen.core.main/leiningen-version)<br />
&quot;2.0.0-SNAPSHOT&quot;</div></div>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/H_DGleV0xh0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/05/openjdk-1-8-0-jdk8-b35-seems-to-break-leiningen-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/05/openjdk-1-8-0-jdk8-b35-seems-to-break-leiningen-2/</feedburner:origLink></item>
		<item>
		<title>How F# helped me to appreciate Clojure’s reduce to traverse data structures (XMLs)</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/_vIrrzB9qtw/</link>
		<comments>http://blog.japila.pl/2012/05/how-f-helped-me-to-appreciate-clojures-reduce-to-traverse-data-structures-xmls/#comments</comments>
		<pubDate>Sat, 05 May 2012 21:20:56 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=974</guid>
		<description><![CDATA[I&#8217;ve no doubt that the book Real-World Functional Programming &#8211; 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&#8217;t done with its reading, but my meetup with it won&#8217;t finish once read. It&#8217;s too valuable to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve no doubt that the book <a href="http://manning.com/petricek/">Real-World Functional Programming &#8211; With examples in F# and C#</a> by Tomas Petricek and Jon Skeet will make me a better functional programmer and have often found it very enlightening. I haven&#8217;t done with its reading, but my meetup with it won&#8217;t finish once read. It&#8217;s too valuable to put on a bookshelf and let it get forgotten. Functional programming is so much easier with the book!</p>
<p>It&#8217;s about <a href="http://fsharp.net">F#</a> yet I&#8217;m reading it to understand functional programming better. F# is just another language. What matters is that it&#8217;s a functional language and its syntax doesn&#8217;t bother me. Moreover, I found the language highly intuitive and similar to <a href="http://scala-lang.org">Scala</a> (they say it&#8217;s because they borrowed a lot from <a href="http://caml.inria.fr/">OCaml</a>). I simply don&#8217;t mind learning yet another functional language provided it makes my foray into functional paradigm easier and faster. Even if it&#8217;s a non-JVM functional language.</p>
<p>On page 367, there&#8217;s a sample with <code class="codecolorer text default"><span class="text">Seq.fold</span></code> to traverse a XPath-like path in a XML. I burnt a few brain cycles before I figured out how it works. It&#8217;s simple, but it wasn&#8217;t almost half a day before. That&#8217;s that sort of examples I enjoy the most. They&#8217;re usually short yet powerful and their understanding doesn&#8217;t come for free &#8211; you need to spend some time and think. Think a lot!</p>
<p>Here&#8217;s a session with Clojure REPL to have a version in <a href="http://clojure.org">Clojure</a>.</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">;; Let's have a data structure - a map with other, nested maps<br />
;; One could see it as an XML-like data structure.<br />
;; I did.<br />
<br />
user=&gt; (def req (update-in {} [:a :b :c :d] (fn [v] &quot;value&quot;)))<br />
#'user/req<br />
user=&gt; req<br />
{:a {:b {:c {:d &quot;value&quot;}}}}<br />
<br />
;; Let's define a function xelem that accepts a key (a tag) and a map (a node).<br />
<br />
user=&gt; (defn xelem [s el] (s el))<br />
#'user/xelem<br />
<br />
;; Let's have some fun and play with the function.<br />
<br />
user=&gt; (xelem :a req)<br />
{:b {:c {:d &quot;value&quot;}}}<br />
user=&gt; (xelem :b (xelem :a req))<br />
{:c {:d &quot;value&quot;}}<br />
user=&gt; (-&gt;&gt; (xelem :a req) (xelem :b))<br />
{:c {:d &quot;value&quot;}}<br />
<br />
;; I played until I found out the following:<br />
<br />
user=&gt; (-&gt;&gt; req (xelem :a) (xelem :b) (xelem :c) (xelem :d))<br />
&quot;value&quot;<br />
<br />
;; It's that calling a key with a map in sequence gives you the value.<br />
<br />
;; Let's define a XPath-like path to the value.<br />
<br />
user=&gt; (def path [:a :b :c :d])<br />
#'user/path<br />
<br />
;; With reduce life became so easy.<br />
;; Or was it because of the book?!<br />
;; I think both.<br />
<br />
user=&gt; (reduce (fn [v1 v2] (println &quot;DEBUG v1:&quot; v1 &quot;v2:&quot; v2) (xelem v2 v1)) req path)<br />
DEBUG v1: {:a {:b {:c {:d value}}}} v2: :a<br />
DEBUG v1: {:b {:c {:d value}}} v2: :b<br />
DEBUG v1: {:c {:d value}} v2: :c<br />
DEBUG v1: {:d value} v2: :d<br />
&quot;value&quot;<br />
<br />
;; The book &quot;Real-World Functional Programming&quot; uses the pipelining operator |&gt;,<br />
;; and Clojure provides the threading macros: -&gt; or -&gt;&gt;<br />
<br />
user=&gt; (-&gt;&gt; path<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (reduce (fn [xn s] <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (xelem s xn)) req))<br />
&quot;value&quot;<br />
<br />
;; I like the book, F#, Clojure and learning!</div></div>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/_vIrrzB9qtw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/05/how-f-helped-me-to-appreciate-clojures-reduce-to-traverse-data-structures-xmls/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/05/how-f-helped-me-to-appreciate-clojures-reduce-to-traverse-data-structures-xmls/</feedburner:origLink></item>
		<item>
		<title>Reversi in Clojure…functional</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/bMDU3G13h_0/</link>
		<comments>http://blog.japila.pl/2012/05/reversi-in-clojure-functional/#comments</comments>
		<pubDate>Thu, 03 May 2012 20:18:25 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=968</guid>
		<description><![CDATA[Reversi in Clojure w/ Three Alternative User Interfaces is the type of blog entries I enjoy the most &#8211; it inspired me to think about functional programming in Clojure and found it a great &#8220;platform&#8221; to work on my understanding of Clojure&#8217;s way to functional programming. I hope I didn&#8217;t mess it up and am [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.seekingclojure.com/post/22144855523/reversi">Reversi in Clojure w/ Three Alternative User Interfaces</a> is the type of blog entries I enjoy the most &#8211; it inspired me to think about functional programming in <a href="http://clojure.org">Clojure</a> and found it a great &#8220;platform&#8221; to work on my understanding of Clojure&#8217;s way to functional programming. I hope I didn&#8217;t mess it up and am on my way to functional programming nirvana.</p>
<p>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.</p>
<p>The very first finding was the if statement in the function <code class="codecolorer text default"><span class="text">opposite-piece</span></code>. As I wrote in the blog entry <a href="http://blog.japila.pl/2012/04/protocols-more-functional-than-if-in-clojure/">Protocols more functional than if in Clojure?</a>, 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.</p>
<p>What about this version of the <code class="codecolorer text default"><span class="text">opposite-piece</span></code> function?</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(defn opposite-piece-with-map [piece]<br />
&nbsp; &quot;Change white to black and vice versa&quot;<br />
&nbsp; (let [conversion-map {:w :b :b :w}]<br />
&nbsp; &nbsp; (conversion-map piece)))</div></div>
<p>To me it looks more functional.</p>
<p>The other piece of the code I found intriguing was the function <code class="codecolorer text default"><span class="text">initialize-board</span></code> which uses a less functional data structure &#8211; a vector &#8211; not an immutable list &#8211; 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&#8217;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).</p>
<p>I consider a vector an imperative data structure and a sort of mutable list or vice versa &#8211; a list as an immutable vector (even though the distinction doesn&#8217;t exist in Clojure). I&#8217;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.</p>
<p>So, from that moment on, I was using a list not a vector in initialize-board. And the fun began!</p>
<p>As a starter, let&#8217;s consider the following 3&#215;3 board with 0&#8242;s.</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(def board (repeat 9 0))</div></div>
<p>I wish I could have a picture of a board to accompany the snippets.</p>
<p>You may also use the function <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/partition">partition</a>.</p>
<p>How could you change, say increase, the 0&#8242;s in the position you&#8217;d call (2,2) &#8211; the central 0? Let&#8217;s assume we start counting the rows and the columns from 1 onwards.</p>
<p>The pure function could look as follows:</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(defn inc-at-v1 [board row col]<br />
&nbsp; (let [split-pos &nbsp;(+ (* 3 (dec row)) col)<br />
&nbsp; &nbsp; &nbsp; &nbsp; f inc]<br />
&nbsp; &nbsp; (concat (take (dec split-pos) board)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (list (f (nth board (dec split-pos))))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (drop split-pos board))))</div></div>
<p>Let&#8217;s see how it works.</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">user=&gt; (inc-at-v1 board 2 2)<br />
(0 0 0 0 1 0 0 0 0)</div></div>
<p>It works! My very first take on refactoring of the game to a more functional version works well.</p>
<p>There&#8217;s a serious issue, though. We iterate over the sequence <code class="codecolorer text default"><span class="text">board</span></code> three times &#8211; 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&#8217;s certainly not very efficient.</p>
<p>The other solution was a recursion with a counter &#8211; a sort of functional for (not to be confused with <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/for">the for function for list comprehension</a>).</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">(defn inc-at-v2<br />
&nbsp; ([board row col]<br />
&nbsp; &nbsp; (let [split-pos &nbsp;(dec (+ (* 3 (dec row)) col))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; split-fn (fn [idx e]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(cond (&lt; idx split-pos) e<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(= idx split-pos) (inc e)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(&gt; idx split-pos) e))]<br />
&nbsp; &nbsp; &nbsp; (map-indexed split-fn board))))</div></div>
<p>Let&#8217;s give it a shot!</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">user=&gt; (inc-at-v2 board 2 2)<br />
(0 0 0 0 1 0 0 0 0)<br />
user=&gt; (inc-at-v2 board 2 3)<br />
(0 0 0 0 0 1 0 0 0)<br />
user=&gt; (inc-at-v2 board 3 3)<br />
(0 0 0 0 0 0 0 0 1)</div></div>
<p>It works fine again. Is it better? I&#8217;m still unconvinced, esp. the <code class="codecolorer text default"><span class="text">split-fn</span></code> looks terribly. I need a version without any mutation, even with <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/atom">atoms</a>, <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/ref">refs</a> or <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/agent">agents</a>. Would you mind lending me a helping hand? How would you change the function <code class="codecolorer text default"><span class="text">inc-at-v2</span></code> to be more effective and look prettier?</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/bMDU3G13h_0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/05/reversi-in-clojure-functional/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/05/reversi-in-clojure-functional/</feedburner:origLink></item>
		<item>
		<title>Java 7 New Features Cookbook give-away contest</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/0CGzZ4Toyuo/</link>
		<comments>http://blog.japila.pl/2012/04/java-7-new-features-cookbook-give-away-contest/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 10:06:58 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[java7]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=962</guid>
		<description><![CDATA[I&#8217;ve been a technical reviewer for the book Java 7 New Features Cookbook from Packt and it&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.packtpub.com/java-7-new-features-cookbook/book"><img src="http://blog.japila.pl/wp-content/uploads/2012/04/5627EN_Java-SE-7-New-Features-Cookbook_cov.jpg" alt="" title="Java SE 7 New Features Cookbook" width="400" height="494" class="alignleft size-full wp-image-963" /></a>I&#8217;ve been a technical reviewer for the book <a href="http://www.packtpub.com/java-7-new-features-cookbook/book">Java 7 New Features Cookbook</a> from Packt and it&#8217;s now available in the bookstores near you (Amazon.com comes to my mind, but guess it should be nearer, too).</p>
<p>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&#8217;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&#8217;m not going to say it&#8217;s an excellent book &#8211; it&#8217;s useful enough to take your chance in a drawing to have your own free copy.</p>
<p>Here are the rules:</p>
<p><strong>Book Give-away:</strong> Hold a chance to win a free copy of the <a href="http://www.packtpub.com/java-7-new-features-cookbook/book">Java 7 New Features Cookbook</a> just by commenting!</p>
<p>For the contest Packt have two copies of <a href="http://www.packtpub.com/java-7-new-features-cookbook/book">Java 7 New Features Cookbook</a>, to be given away to two lucky winners.</p>
<p><strong>How you can win:</strong></p>
<p>To win your copy of this book, all you need to do is come up with a comment below highlighting the reason &#8220;why you would like to win this book”.</p>
<p><strong>Duration of the contest &#038; selection of winners:</strong></p>
<p>The contest is valid for the upcoming <strong>7</strong> (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&#8217;ll do the selection in Clojure so it should be fair enough.</p>
<p><strong>About the book:</strong></p>
<p><a href="http://www.packtpub.com/java-7-new-features-cookbook/book">Java 7 New Features Cookbook</a> 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.</p>
<p><a href="http://www.packtpub.com/java-7-new-features-cookbook/book">Java 7 New Features Cookbook</a> 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.</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/0CGzZ4Toyuo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/04/java-7-new-features-cookbook-give-away-contest/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/04/java-7-new-features-cookbook-give-away-contest/</feedburner:origLink></item>
		<item>
		<title>Java EE and Clojure on Allegro RoadShow in Torun</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/MKnJqZDQLz8/</link>
		<comments>http://blog.japila.pl/2012/04/java-ee-and-clojure-on-allegro-roadshow-in-torun/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 21:05:30 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Java EE]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=954</guid>
		<description><![CDATA[Clojure makes my life so much fun! I&#8217;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 &#8211; *the* e-commerce company in Poland &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://allegroroadshow.pl/"><img src="http://blog.japila.pl/wp-content/uploads/2012/04/allegro-roadshow-torun.png" alt="" title="allegro-roadshow-torun" width="200" height="94" class="alignleft size-full wp-image-955" /></a>Clojure makes my life so much fun!</p>
<p>I&#8217;ve recently been invited for a talk about my current interests in functional programming during <a href="http://allegroroadshow.pl/">Allegro RoadShow</a> in Torun and chose Clojure with Java EE 6 as the topic to present. It has been an event where an employee of Allegro &#8211; *the* e-commerce company in Poland &#8211; talked about his job and what tools they use. I was there too to shed some light on alternative language &#8211; Clojure. And that brought so much fun!</p>
<p>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 &#8211; 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 &#8211; no server restarts to introduce a new functionality. HTTP requests and responses as maps in Ring helped enormously, too. I&#8217;m not sure they had enough time to appreciate the simplicity.</p>
<p>The event was held at University of Torun, the Computer Science department.</p>
<ul>
<li>There were ca 60 attendees</li>
<li>When I asked about their familiarity of Java EE, 2 people raised their hand.</li>
<li>When I asked about Java, 20 people raised their hand.</li>
<li>Some exposure to functional languages? 10 people nodded.</li>
</ul>
<p>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&#8217;s possible to do some web development.</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/MKnJqZDQLz8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/04/java-ee-and-clojure-on-allegro-roadshow-in-torun/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/04/java-ee-and-clojure-on-allegro-roadshow-in-torun/</feedburner:origLink></item>
		<item>
		<title>Protocols more functional than if in Clojure?</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/dCjzV9UVZ2Y/</link>
		<comments>http://blog.japila.pl/2012/04/protocols-more-functional-than-if-in-clojure/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 17:32:31 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=947</guid>
		<description><![CDATA[While reading Ring Handlers – Functional Decorator Pattern&#8230; How often do you perform conditional branching with if? The answer may likely rely upon the available features offered by the language of choice &#8211; the if statement/expression (Java, Clojure), pattern matching (F#) and dynamic dispatch (Java, Clojure). When I read Conditional (programming) in Wikipedia I stumbled [...]]]></description>
			<content:encoded><![CDATA[<p>While reading <a href="http://squirrel.pl/blog/2012/04/10/ring-handlers-functional-decorator-pattern/">Ring Handlers – Functional Decorator Pattern</a>&#8230;</p>
<p>How often do you perform conditional branching with if? The answer may likely rely upon the available features offered by the language of choice &#8211; the if <a href="http://en.wikipedia.org/wiki/Statement_%28programming%29">statement</a>/<a href="http://en.wikipedia.org/wiki/Expression_%28programming%29">expression</a> (Java, Clojure), pattern matching (F#) and dynamic dispatch (Java, Clojure).</p>
<p>When I read <a href="http://en.wikipedia.org/wiki/Conditional_%28programming%29">Conditional (programming)</a> in Wikipedia I stumbled upon the following sentence:</p>
<p><em>&#8220;Although dynamic dispatch is not usually classified as a conditional construct, it is another way to select between alternatives at runtime.&#8221;</em></p>
<p>It made me think about its implementation in <strong>Clojure</strong>. I could definitely tackle it with method overloading in Java (that was dumb easy to figure out), but what about Clojure?</p>
<p>At the moment I&#8217;d come up with a possible implementation in Java, <a href="http://clojure.org/protocols">Clojure&#8217;s Protocols</a> sprung to my mind. I&#8217;ve been reading about them, mainly in books and very rarely in articles, and have never used the concept before. It looked like it&#8217;d change.</p>
<p>Protocols are like interfaces in Java and beg no special treatment of nil (counterpart of Java&#8217;s null which <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.10">begs a casting to appropriate type</a>).</p>
<p>Below you can find a simple Protocol implementation in Clojure and its use. Fire up <code class="codecolorer text default"><span class="text">lein2 repl</span></code> and follow along.</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">;; I'm aiming at simplifying the following function from the article Ring Handlers – Functional Decorator Pattern<br />
;; It's actually Ring's function<br />
user=&gt; #_<br />
(defn wrap-params<br />
&nbsp; [handler &amp; [opts]]<br />
&nbsp; (fn [request]<br />
&nbsp; &nbsp; (let [request &nbsp;(if (:query-params request)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;request<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(assoc-query-params request))]<br />
&nbsp; &nbsp; &nbsp; (handler request))))<br />
<br />
;; I'm mostly interested in the if expression in let<br />
user=&gt; #_<br />
(if (:query-params request)<br />
&nbsp; &nbsp; request<br />
&nbsp; &nbsp; (assoc-query-params request))<br />
<br />
;; the very first version to demonstrate protocols<br />
user=&gt; (defprotocol IfProtocol<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;A better if - an if or cond alternative - ver.1&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if++ [this] &quot;A single protocol method&quot;))<br />
IfProtocol<br />
user=&gt; (extend-protocol IfProtocol<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if++ [_] &quot;Nil&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if++ [_] &quot;Object&quot;))<br />
nil<br />
user=&gt; (if++ nil)<br />
&quot;Nil&quot;<br />
user=&gt; (if++ &quot;a string&quot;)<br />
&quot;Object&quot;<br />
<br />
;; a two-argument version<br />
user=&gt; (defprotocol IfProtocol<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;A better if - an if or cond alternative&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if++ [this rq] &quot;A single protocol method with a request&quot;))<br />
IfProtocol<br />
user=&gt; (extend-protocol IfProtocol<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nil<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if++ [_ rq] (str &quot;Nil with &quot; rq))<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Object<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(if++ [_ rq] (str &quot;Object with &quot; rq)))<br />
nil<br />
user=&gt; (if++ nil 1)<br />
&quot;Nil with 1&quot;<br />
user=&gt; (if++ &quot;A string&quot; 1)<br />
&quot;Object with 1&quot;<br />
<br />
;; the final version - extending the protocol one type at a time<br />
user=&gt; (extend-protocol IfProtocol Object (if++ [_ rq] rq))<br />
nil<br />
user=&gt; (defn assoc-query-params [rq]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(str &quot;Processing &quot; rq))<br />
#'user/assoc-query-params<br />
user=&gt; (extend-protocol IfProtocol nil (if++ [_ request] (assoc-query-params request)))<br />
nil<br />
<br />
;; Testing...<br />
<br />
user=&gt; (defn f [request]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(let [request &nbsp;(if++ (:query-params request) request)]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;request))<br />
#'user/f<br />
user=&gt; (f {})<br />
&quot;Processing {}&quot;<br />
user=&gt; (f {:query-params 1})<br />
{:query-params 1}<br />
<br />
;; the function from the article with if++<br />
user=&gt; (defn wrap-params<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[handler &amp; [opts]]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(fn [request]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(let [request &nbsp;(if++ (:query-params request) request)]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(handler request))))<br />
#'user/wrap-params<br />
<br />
;; more testing<br />
user=&gt; (def wp (wrap-params identity))<br />
#'user/wp<br />
user=&gt; (wp {})<br />
&quot;Processing {}&quot;<br />
user=&gt; (wp {:query-params 1})<br />
{:query-params 1}</div></div>
<p>It works, but I&#8217;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?</p>
<p>You may also find <a href="http://stackoverflow.com/questions/7536633/ocaml-pattern-matching-vs-if-else-statements">OCaml: Pattern matching vs If/else statements</a> or <a href="http://stackoverflow.com/questions/4943628/if-else-branching-in-clojure">if-else branching in clojure</a> 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.</p>
<p>There&#8217;s also <a href="http://clojure.org/multimethods">Clojure&#8217;s multimethods</a> concept which seem as much applicable to the use case as protocols. Doh doubled.</p>
<p>I&#8217;ve also added <a href="https://github.com/clojure/core.match">org.clojure/core.match</a> to a <em>S.I.L</em> (= Seemingly Inevitable to Learn) bucket.</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/dCjzV9UVZ2Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/04/protocols-more-functional-than-if-in-clojure/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/04/protocols-more-functional-than-if-in-clojure/</feedburner:origLink></item>
		<item>
		<title>Clojure and me at devCrowd.pl</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/OFV_mNqg8js/</link>
		<comments>http://blog.japila.pl/2012/04/clojure-and-me-at-devcrowd-pl/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 06:26:15 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=943</guid>
		<description><![CDATA[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&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>The past Saturday I was on <a href="http://devcrowd.pl/">devCrowd.pl</a> in Szczecin, Poland where I ran two sessions about <strong>Clojure</strong> as a functional programming language to develop web applications. I don&#8217;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 <a href="http://devcrowd.pl/index.php/funkcjonalne-programowanie-a-codzienny-dewelopment/">functional programming in a day-job development by Sebastian Pietrowski</a> (<a href="https://twitter.com/#!/pedrowaty">@pedrowaty</a>) and I wished I&#8217;d skipped the introductory part in my talk to spare more time for the demo instead.</p>
<p>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 href="http://devcrowd.pl/index.php/wlasna-skalowana-aplikacja-webowa-na-platformie-node-js/">a workshop about node.js</a> and <a href="http://devcrowd.pl/index.php/zdroworozsadkowe-praktyki-w-projektach-it/">a talk about IT project management</a> 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&#8217;t make it to the conference. I&#8217;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!</p>
<p>&#8220;Always choose wisely&#8221; &#8211; they say. When faced with a choice of attending a session or leading one, I&#8217;d pick the later. It&#8217;s a no-brainer now.</p>
<p>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&#8217;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.</p>
<p>I was afraid that finding a good balance between introducing Clojure with slides and later the live coding sessions might&#8217;ve been a huge undertaking, but <a href="https://twitter.com/#!/search/%23devcrowdpl%2B%40jaceklaskowski">the comments on twitter (#devcrowdpl + @jaceklaskowski) about my sessions seem to prove that people might&#8217;ve enjoyed the sessions</a>. I also managed to speak to a few people who spent some time with functional languages &#8211; Clojure and F#.</p>
<p>I had a cheatsheet on my Android mobile device to cover my back in case of troubles which was very helpful at times.</p>
<p>The live coding session started with a <strong>lein2</strong> project &#8211; 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 <strong>pomegrade</strong> and <strong>ring-jetty-adapter</strong>. 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 <strong>Eclipse</strong> with <strong>Counterclockwise</strong>, more introduction to functional programming with Clojure with <strong>map</strong>, <strong>reduce</strong> and <strong>filter</strong> amongst the other features (immutable data structures) concluded the sessions.</p>
<p>I&#8217;m going to described the parts of my sessions which have not yet found their place in my blog. Stay tuned.</p>
<p>Should you want to join a live coding session with Clojure and me, I wholeheartedly recommend to attend the presentations of mine on <a href="http://4developers.org.pl/">4Developers in Poznan</a> on 18. April, <a href="http://2012.geecon.org/">GeeCON in Poznan</a> on 18. May and hopefully <a href="http://2012.confitura.pl/">Confitura in Warsaw</a> on 30. June.</p>
<p>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.</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/OFV_mNqg8js" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/04/clojure-and-me-at-devcrowd-pl/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/04/clojure-and-me-at-devcrowd-pl/</feedburner:origLink></item>
		<item>
		<title>Mocking out in Clojure with with-redefs-fn (no Midje this time)</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/uX3ooUa_lWg/</link>
		<comments>http://blog.japila.pl/2012/04/mocking-out-in-clojure-with-with-redefs-fn-no-midje-this-time/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 20:24:49 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=930</guid>
		<description><![CDATA[I made some changes in a Clojure project &#8211; librarian-clojure. The changes revolved around security in a Compojure web application. What I needed was to check whether they&#8217;re correct and hence I needed some tests with mocking involved because the functions the changes were introduced to used external sources &#8211; MongoDB and an encryption library. [...]]]></description>
			<content:encoded><![CDATA[<p>I made some changes in a <a href="http://clojure.org">Clojure</a> project &#8211; <a href="https://github.com/jaceklaskowski/librarian-clojure">librarian-clojure</a>. The changes revolved around security in a Compojure web application. What I needed was to check whether they&#8217;re correct and hence I needed some tests with mocking involved because the functions the changes were introduced to used external sources &#8211; MongoDB and an encryption library. I didn&#8217;t mean to set up the environment, but just enough to get the task done. And it should be fast and quick.</p>
<p>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&#8230;maps. Moreover, I knew Clojure could replace function definition (a var) on the fly for a single thread with <code class="codecolorer text default"><span class="text">binding</span></code>, but <strong>Clojure 1.3</strong> comes with the <strong>with-redefs-fn</strong> function that <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/with-redefs-fn">&#8220;Temporarily redefines Vars during a call to func. (&#8230;) Useful for mocking out functions during testing.&#8221;</a> I didn&#8217;t have to define a dependency and have a framework to work with. Life couldn&#8217;t have been easier!</p>
<p>I&#8217;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&#8217;t care (perhaps because I wasn&#8217;t paid for programming and was only doing it in my spare time, often sidetracked by other activities).</p>
<p>I&#8217;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.</p>
<p>I think that TDD in Clojure (or any functional language) is so much easier and&#8230;fun!</p>
<p>Firstly, there&#8217;s a REPL where you can do it interactively. Secondly, Clojure&#8217;s dynamic. Thirdly, there&#8217;s no &#8220;overhead&#8221; with object-oriented hierarchy since &#8220;weakly&#8221; structures like maps suffice. All these seem to suggest that Clojure may easily be the language of choice for TDD.</p>
<p>Have a look at the following session in Clojure&#8217;s REPL to experience it yourself. Even thought it&#8217;s far from TDD, it led to using the fake functions with no pain (and eventually I found out that <a href="https://github.com/marick/Midje">Midje might&#8217;ve done it better</a>. Next time.)</p>
<div class="codecolorer-container text blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">user=&gt; (use 'librarian-clojure.security)<br />
nil<br />
user=&gt; (def request {:params {:login &quot;jacek&quot; :password &quot;secr3t&quot;}})<br />
#'user/request<br />
user=&gt; (log-in request)<br />
AssertionError Assert failed: (somnium.congomongo/connection? c__793__auto__) &nbsp;librarian-clojure.db/db-get-user (db.clj:63)<br />
user=&gt; ;; no CongoDB up and running - mock its availability<br />
user=&gt; (def ^:dynamic db-get-user)<br />
#'user/db-get-user<br />
user=&gt; (binding [db-get-user (fn [v] (println &quot;user: &quot; v) v)]<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(log-in request))<br />
AssertionError Assert failed: (somnium.congomongo/connection? c__793__auto__) &nbsp;librarian-clojure.db/db-get-user (db.clj:63)<br />
user=&gt; ;; it doesn't seem to work for another namespace's vars - a bit of Google'ing and with-redefs-fn shows up<br />
user=&gt; (with-redefs-fn {#'librarian-clojure.db/db-get-user (fn [v] (println &quot;user: &quot; v) {:password &quot;secr3t&quot; :roles #{:admin}})<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #'librarian-clojure.security/check-password (fn [cd cr] (println &quot;candidate: &quot; cd &quot; crypt: &quot; cr) true)}<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #(librarian-clojure.security/log-in request))<br />
user: &nbsp;jacek<br />
candidate: &nbsp;secr3t &nbsp;crypt: &nbsp;secr3t<br />
{:name &quot;jacek&quot;, :roles #{:admin}}</div></div>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/uX3ooUa_lWg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/04/mocking-out-in-clojure-with-with-redefs-fn-no-midje-this-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/04/mocking-out-in-clojure-with-with-redefs-fn-no-midje-this-time/</feedburner:origLink></item>
		<item>
		<title>Clojure easier? s/lein/lein2 – pomegranate is there already</title>
		<link>http://feedproxy.google.com/~r/blog-japila-pl/~3/FPauyw3lwOU/</link>
		<comments>http://blog.japila.pl/2012/04/clojure-easier-sleinlein2-pomegranate-is-there-already/#comments</comments>
		<pubDate>Sat, 07 Apr 2012 13:23:35 +0000</pubDate>
		<dc:creator>Jacek Laskowski</dc:creator>
				<category><![CDATA[Languages]]></category>
		<category><![CDATA[Clojure]]></category>

		<guid isPermaLink="false">http://blog.japila.pl/?p=902</guid>
		<description><![CDATA[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 &#8220;Leiningen 2 has move its dependency management core [...]]]></description>
			<content:encoded><![CDATA[<p>After I published the blog entry <a href="http://blog.japila.pl/2012/04/clojures-repl-lein-pomegranate-and-classpath/">Clojure’s REPL, lein, pomegranate and classpath</a>, Sun Ning commented that <a href="http://blog.japila.pl/2012/04/clojures-repl-lein-pomegranate-and-classpath/#comment-1327">lein2 uses pomegranate internally as the dependency resolution management tool</a>. Well, it was a bit convoluted in a sense, but meant exactly this. It later turned out that a single sentence <a href="http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/"><em>&#8220;Leiningen 2 has move its dependency management core to a new library, called pomegranate.&#8221;</em></a> made my day as developing Clojure applications in Clojure&#8217;s REPL became even easier. I guess also that presenting Clojure development live should change, too.</p>
<p>From now on, I become a proponent of using <strong>lein2</strong> as a mandatory management tool for people who start their journey into Clojure. Consult the Installation section in <a href="https://github.com/technomancy/leiningen#readme">Leiningen&#8217;s README</a>.</p>
<p>Give yourself a couple of minutes to have a better exposure for the changes.</p>
<ol>
<li>Run <strong>lein2 repl</strong>.</li>
<li>Execute <strong>(use ‘[cemerick.pomegranate :only (add-dependencies)])</strong>.</li>
<li>Use <strong>(add-dependencies)</strong>.</li>
</ol>
<div class="codecolorer-container bash blackboard" style="border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jacek:~<span style="color: #000000; font-weight: bold;">/</span>sandbox<br />
$ lein2 version<br />
Leiningen 2.0.0-SNAPSHOT on Java 1.7.0-jdk7u4-b19 OpenJDK <span style="color: #000000;">64</span>-Bit Server VM<br />
jacek:~<span style="color: #000000; font-weight: bold;">/</span>sandbox<br />
$ lein2 repl<br />
nREPL server started on port <span style="color: #000000;">56376</span><br />
Welcome to REPL-y<span style="color: #000000; font-weight: bold;">!</span><br />
Clojure 1.3.0<br />
&nbsp; &nbsp; Exit: Control+D or <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">exit</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> or <span style="color: #7a0874; font-weight: bold;">&#40;</span>quit<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
Commands: <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">help</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; Docs: <span style="color: #7a0874; font-weight: bold;">&#40;</span>doc function-name-here<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">&#40;</span>find-doc <span style="color: #ff0000;">&quot;part-of-name-here&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; Source: <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">source</span> function-name-here<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">&#40;</span>sourcery function-name-here<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp;Javadoc: <span style="color: #7a0874; font-weight: bold;">&#40;</span>javadoc java-object-or-class-here<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
Examples from clojuredocs.org:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">&#40;</span>clojuredocs name-here<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">&#40;</span>clojuredocs <span style="color: #ff0000;">&quot;ns-here&quot;</span> <span style="color: #ff0000;">&quot;name-here&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
nil<br />
<span style="color: #007800;">user</span>=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>clojure-<span style="color: #7a0874; font-weight: bold;">&#91;</span>TAB<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #007800;">user</span>=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>clojure-version<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #ff0000;">&quot;1.3.0&quot;</span><br />
<span style="color: #007800;">user</span>=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">'[cemerick.pomegranate :only (add-dependencies)])<br />
nil<br />
user=&gt; (add-dependencies :coordinates '</span><span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>compojure <span style="color: #ff0000;">&quot;1.0.1&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>javax.servlet<span style="color: #000000; font-weight: bold;">/</span>servlet-api <span style="color: #ff0000;">&quot;2.5&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> nil, <span style="color: #7a0874; font-weight: bold;">&#91;</span>clout <span style="color: #ff0000;">&quot;1.0.1&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> nil, <span style="color: #7a0874; font-weight: bold;">&#91;</span>org.clojure<span style="color: #000000; font-weight: bold;">/</span>core.incubator <span style="color: #ff0000;">&quot;0.1.0&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> nil, <span style="color: #7a0874; font-weight: bold;">&#91;</span>ring<span style="color: #000000; font-weight: bold;">/</span>ring-core <span style="color: #ff0000;">&quot;1.0.1&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#{[javax.servlet/servlet-api &quot;2.5&quot;] [commons-io &quot;1.4&quot;] [commons-codec &quot;1.4&quot;] [commons-fileupload &quot;1.2.1&quot;]}, [org.clojure/tools.macro &quot;0.1.0&quot;] nil, [commons-io &quot;1.4&quot;] nil, [compojure &quot;1.0.1&quot;] #{[clout &quot;1.0.1&quot;] [org.clojure/core.incubator &quot;0.1.0&quot;] [ring/ring-core &quot;1.0.1&quot;] [org.clojure/tools.macro &quot;0.1.0&quot;] [org.clojure/clojure &quot;1.2.1&quot;]}, [org.clojure/clojure &quot;1.2.1&quot;] nil, [commons-codec &quot;1.4&quot;] nil, [commons-fileupload &quot;1.2.1&quot;] nil}</span><br />
<span style="color: #007800;">user</span>=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>use <span style="color: #ff0000;">'[compojure.core :only (defroutes)])<br />
nil<br />
user=&gt; (defroutes app)<br />
#'</span>user<span style="color: #000000; font-weight: bold;">/</span>app</div></div>
<p>You may also want to read <a href="http://technomancy.us/158">in which we coin a term which is the opposite of deprecate</a> about the other reasons to switch to lein2. Don&#8217;t forget to read the comment for the blog entry:</p>
<p><em>&#8220;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.&#8221;</em></p>
<p>I must admit I hadn&#8217;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.</p>
<p>Lots of great stuff in lein2. See <a href="https://github.com/technomancy/leiningen/wiki/Upgrading">Leiningen&#8217;s Upgrading</a> for more.</p>
<p>Thanks <a href="http://cemerick.com/">Chas</a>, <a href="http://technomancy.us/">Phil</a> and <a href="http://sunng.info">Sun Ning</a>! I&#8217;m deeply indebted to you for your help. Gonna use it during the upcoming conferences in Poland where I&#8217;m presenting Clojure: <a href="http://devcrowd.pl/">DevCrowd</a>, <a href="http://4developers.org.pl/">4Developers</a>, <a href="http://2012.geecon.org/">GeeCON</a> and hopefully <a href="http://2012.confitura.pl/">Confitura</a>.</p>
<img src="http://feeds.feedburner.com/~r/blog-japila-pl/~4/FPauyw3lwOU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.japila.pl/2012/04/clojure-easier-sleinlein2-pomegranate-is-there-already/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.japila.pl/2012/04/clojure-easier-sleinlein2-pomegranate-is-there-already/</feedburner:origLink></item>
	</channel>
</rss>

