<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0EASH87cSp7ImA9WhRaF0s.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185</id><updated>2012-02-20T20:20:49.109+01:00</updated><category term="Node.J" /><category term="Performance" /><category term="Freedom Languages" /><category term="Prime Numbers" /><category term="C" /><category term="Sieve" /><category term="Clojure" /><category term="Pointless" /><category term="Geometry" /><category term="Windows" /><category term="Prolog" /><category term="Web" /><category term="Testing" /><category term="System Programming" /><category term="Productivity" /><category term="Perforce" /><category term="git" /><category term="AI" /><category term="itertools" /><category term="TextMate" /><category term="Mac" /><category term="Mac OS X" /><category term="Laziness" /><category term="vim" /><category term="Mac Dev" /><category term="SCM" /><category term="Computer Science" /><category term="CSS" /><category term="Java Epic Failure" /><category term="Javascript" /><category term="Pointless programming" /><category term="Closures" /><category term="Land of Lisp" /><category term="Social Networks" /><category term="Latex" /><category term="Metaprogramming" /><category term="misc" /><category term="Computability" /><category term="Haskell" /><category term="Atkin Sieve" /><category term="xUnit" /><category term="leiningen" /><category term="editor" /><category term="Programming Languages" /><category term="PostgreSQL" /><category term="string concatenation" /><category term="Django" /><category term="Game Of Life" /><category term="DB" /><category term="Build Systems" /><category term="Fixtures" /><category term="Emacs" /><category term="Bash" /><category term="Object Oriented Programming" /><category term="Templates/Generics" /><category term="Io" /><category term="call/cc" /><category term="Optimization" /><category term="Python" /><category term="Zsh" /><category term="Gambit" /><category term="Logic" /><category term="Real Basic" /><category term="Security" /><category term="Lisp" /><category term="IDE" /><category term="Unfold" /><category term="Programming" /><category term="C++" /><category term="LLVM" /><category term="Shell" /><category term="Artificial Intelligence" /><category term="Node.js" /><category term="Scala" /><category term="Function Composition" /><category term="Conti" /><category term="Software" /><category term="Common Lisp" /><category term="Anamorphism" /><category term="Design Patterns" /><category term="Scheme" /><category term="Unit Testing" /><category term="Social Network Analysis" /><category term="Pointfree" /><category term="Book Review" /><category term="quicksort" /><category term="Declarative Programming" /><category term="Y Combinator" /><category term="Office" /><category term="PyCharm" /><category term="sorting" /><category term="Applescript" /><category term="Java" /><category term="Fun" /><category term="Algorithms" /><category term="jedit" /><category term="Racket" /><category term="nosetests" /><category term="ePublishing" /><category term="Maths" /><category term="IntelliJ" /><category term="Functional Programming" /><category term="Ruby" /><category term="PageRank" /><category term="Maven" /><category term="unix" /><category term="Linux" /><category term="Continuations" /><category term="Cocoa" /><category term="Hardware" /><category term="Rant" /><category term="Ubuntu" /><category term="Game Programming" /><category term="Pointfree programming" /><category term="Macros" /><category term="Complex Networks" /><category term="mercurial" /><category term="Erlang" /><title>RiK0 Tech Temple</title><subtitle type="html">Computing, Maths, Science
[from Enrico Franchi]</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.enrico-franchi.org/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>285</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Rik0TechTemple" /><feedburner:info uri="rik0techtemple" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0EASH8-eyp7ImA9WhRaF0s.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-3944370961037348548</id><published>2012-02-20T20:20:00.001+01:00</published><updated>2012-02-20T20:20:49.153+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-20T20:20:49.153+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Mac OS X" /><title>Lion, brew and gcc</title><content type="html">&lt;p&gt;For me, the transition to lion was relatively painless. Painless here basically means that I patched up the couple of things that gave me problems . In the specific situation, the issue is that Apple's new developer's tools do not include regular gcc anymore. Instead there is a version working with llvm backend which is great but has some issues with some packages that have not been updated yet.&lt;/p&gt;
&lt;p&gt;Another problem is that is closely related is that I had a Python 2.7 installed with Python main website package. I did this because older OS Xs did not have Python 2.7. That Python was built with the older gcc-4.0 apple shipped with SL. Thus, new libraries I install with pip still want that compiler, which apple moved in /Developers-3.2.x/... Thus, I lived so far adding that directory to the PATH and happily compiling.&lt;/p&gt;
&lt;p&gt;What I should have done was getting rid of my beloved python and either use EPD or Apple built-in 2.7 (shipping with Lion) or use a brew-ed python or see if Python.org distributes a Python compiled with the new compiler (which, as far as I know, is perfectly capable of building Python). The question is: are there any python extension I need that need the older gcc? But this is not something I'm going to discuss here: not yet ready to make the transition.&lt;/p&gt;
&lt;p&gt;I just want to point out that I installed the old gcc from homebrew-alt, and now I can just brew install --use-gcc for packages that need the old gcc compiler. This is easy to use and nice. I also removed the old Developers and hope everything's fine.&lt;/p&gt;
&lt;pre&gt;
% git clone https://github.com/adamv/homebrew-alt.git /usr/local/LibraryAlt
% brew install /usr/local/LibraryAlt/duplicates/apple-gcc42.rb
&lt;/pre&gt;
&lt;p&gt;An older version of gfortran I installed conflicted, but the commands above worked like a charm after removing it.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-3944370961037348548?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xWMR3zcYnJYg0Fu0u2cej0MBKuM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xWMR3zcYnJYg0Fu0u2cej0MBKuM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xWMR3zcYnJYg0Fu0u2cej0MBKuM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xWMR3zcYnJYg0Fu0u2cej0MBKuM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/E0qxL-hM0Y0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/3944370961037348548/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=3944370961037348548" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/3944370961037348548?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/3944370961037348548?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/E0qxL-hM0Y0/lion-brew-and-gcc.html" title="Lion, brew and gcc" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2012/02/lion-brew-and-gcc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08CQX4-cCp7ImA9WhRbFUQ.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-2338684135142784227</id><published>2012-02-07T08:31:00.000+01:00</published><updated>2012-02-07T08:31:00.058+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-07T08:31:00.058+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java Epic Failure" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Continuations" /><title>Clojure: writing tail recursive functions without using recur</title><content type="html">&lt;p&gt;Once upon a time, in the land of the Clojure, there was a brilliant student who enquired the nature of things and he for that he was greatly loved and appreciated by his teachers, for he was brilliant and asked about the nature of things and they could explain him the world. He learned about macros and first order functions and actors and software transactional memory and he was happy. But then he began to focus on the nature of recur and he felt that something was amiss and the way trampolines and functions interact made him wonder.&lt;/p&gt;
&lt;p&gt;During a short holiday he was in Schemeland, and he saw that they did not use recur. They named the functions and called them with their name in tail position and that was the way they did. And he felt it was good. So he asked his Master:&lt;/p&gt;
&lt;p&gt;"Why can the schemers call the functions in tail position and their stacks never end?"&lt;/p&gt;
&lt;p&gt;And the Master told him that it was because their soil is fertile, while the land of the Clojure is just an oasis in the wastes of Javaland.&lt;/p&gt;
&lt;p&gt;"We are lucky," he added, "for our land still gives us food spontaneously and the air does not drives us mad. And our spring is natural and not a framework. And if you do not like recur, you can always map, for or loop. Higher order functions and macros can help you to hide what you do not like, for you are the master of your own language."&lt;/p&gt;
&lt;p&gt;For a while the student was content, still he had a recurring thought: functions can do everything and in Church he did not find recur but only functions. And so he learned Y. But Y is a demanding beast, for it requires functions to be defined awkwardly. And the student wanted to simply write:&lt;/p&gt;
&lt;pre&gt;
(defn factorial [n acc]
  (if (= n 0)
    acc
    (factorial (- n 1) (* n acc))))
&lt;/pre&gt;
&lt;p&gt;His Master saw him troubled and in pain, and one day a big application they were creating exploded with a StackOverflowError and he knew that unless the student was cured he could not be writing code with the others. So one evening, he told his student that if he really wanted to learn the secrets to make tail-call recursive functions run with constant stack usage, he shall go to the Land of Snakes, where they eat only Spam and Eggs, to look for some &lt;a href="http://code.activestate.com/recipes/496691/"&gt;wise men&lt;/a&gt; and have them teach the secrets of creating tail recursion at language level. And he warned the student that the travel was dangerous.&lt;/p&gt;
&lt;p&gt;The young student was frightened, because the Land of Snake is far away and he was barely aware of the perils that lurked in the shadow. However, his resolve was strong and he packed his things, an editor and few jars to survive the wastes of Javaland, and ventured forth. He travelled through the dull wastes where everything is private or protected and he has to ask things to do things for him. But as most people grew up in the land of Clojure, he knew that objects are but closure in disguise and he new how to bind them to his will with the power of the dot form.&lt;/p&gt;
&lt;p&gt;After three days and three nights he eventually reached the Mines of Ruby and where massive gates blocked his way. He spoke the words as his master instructed (password: mellon), but the gate remained closed, for someone monkey-patched it and the door now spoke english, but the student did not know it and with failure in his heart he left the place, because he was trained in the ways of Lambda and could not cope with such a stateful abomination.&lt;/p&gt;
&lt;p&gt;After months of wandering, he eventually reached Schemeland, where he at least could tail recur without recur. He spent another month drowning his pain into first class continuations and losing hope to ever come back to the land of Clojure, until one day he overhead the men telling tales at the tavern about a pythonista adventuring to Schemeland. The student sought the pythonista and eventually he found him and he asked him about the secrets of recursion and the pythonista &lt;a href="http://micheles.googlecode.com/hg/decorator/documentation.html"&gt;showed him code&lt;/a&gt; and the student was happy because he knew classes are another word for closures and he was a master of closures. But he also understood that state was the missing element and he was saddened, because he also knew that state is treacherous.&lt;/p&gt;
&lt;p&gt;Nonetheless, he felt he had come to far to be stopped by the formal purity of stateless programming and he eventually wrote the code. Little is known of what happened afterwards. Some claim he finally found his way to the lend of the Snake, after having extendedly monkey-wrenched the monkey patcher, other say that he went back to the Land of the Clojure.&lt;/p&gt;
&lt;p&gt;I, your humble narrator, do not know the truth. I tried nonetheless to follow the student's step and implement myself the function that makes tail recursive calls without using recur. Ugly it is, and is indeed but an illusion, for recur lies inside the implementation. Still, it does the trick:&lt;/p&gt;
&lt;pre&gt;
&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;defrec factorial &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;n acc&lt;/span&gt;&lt;span class="s0"&gt;] 
&lt;a name="l28"&gt;  (&lt;/span&gt;&lt;span class="s1"&gt;if &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;= n &lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="s0"&gt;) 
&lt;a name="l29"&gt;    &lt;/span&gt;&lt;span class="s1"&gt;acc&lt;/span&gt;&lt;span class="s0"&gt; 
&lt;a name="l30"&gt;    (&lt;/span&gt;&lt;span class="s1"&gt;factorial &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;- n &lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="s0"&gt;) (&lt;/span&gt;&lt;span class="s1"&gt;* n acc&lt;/span&gt;&lt;span class="s0"&gt;))))&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;And here the code:&lt;/p&gt;
&lt;pre&gt;
&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;defn uuid &lt;/span&gt;&lt;span class="s0"&gt;[] (&lt;/span&gt;&lt;span class="s1"&gt;str &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;java.util.UUID/randomUUID&lt;/span&gt;&lt;span class="s0"&gt;))) 
&lt;a name="l3"&gt; 
&lt;a name="l4"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;defn tail-recursive &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;f&lt;/span&gt;&lt;span class="s0"&gt;] 
&lt;a name="l5"&gt;  (&lt;/span&gt;&lt;span class="s1"&gt;let &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;state &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;ref &lt;/span&gt;&lt;span class="s0"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;:func &lt;/span&gt;&lt;span class="s1"&gt;f &lt;/span&gt;&lt;span class="s2"&gt;:first-call &lt;/span&gt;&lt;span class="s3"&gt;true &lt;/span&gt;&lt;span class="s2"&gt;:continue &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;uuid&lt;/span&gt;&lt;span class="s0"&gt;)})] 
&lt;a name="l6"&gt;    (&lt;/span&gt;&lt;span class="s1"&gt;fn &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;amp; args&lt;/span&gt;&lt;span class="s0"&gt;] 
&lt;a name="l7"&gt;      (&lt;/span&gt;&lt;span class="s1"&gt;let &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;cont &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;:continue &lt;/span&gt;&lt;span class="s0"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;state&lt;/span&gt;&lt;span class="s0"&gt;)] 
&lt;a name="l8"&gt;        (&lt;/span&gt;&lt;span class="s1"&gt;if &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;:first-call &lt;/span&gt;&lt;span class="s0"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;state&lt;/span&gt;&lt;span class="s0"&gt;) 
&lt;a name="l9"&gt;          (&lt;/span&gt;&lt;span class="s1"&gt;let &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;fnc &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;:func &lt;/span&gt;&lt;span class="s0"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;state&lt;/span&gt;&lt;span class="s0"&gt;)] 
&lt;a name="l10"&gt;            (&lt;/span&gt;&lt;span class="s1"&gt;dosync&lt;/span&gt;&lt;span class="s0"&gt; 
&lt;a name="l11"&gt;              (&lt;/span&gt;&lt;span class="s1"&gt;alter state assoc &lt;/span&gt;&lt;span class="s2"&gt;:first-call &lt;/span&gt;&lt;span class="s3"&gt;false&lt;/span&gt;&lt;span class="s0"&gt;)) 
&lt;a name="l12"&gt;            (&lt;/span&gt;&lt;span class="s1"&gt;try&lt;/span&gt;&lt;span class="s0"&gt; 
&lt;a name="l13"&gt;              (&lt;/span&gt;&lt;span class="s1"&gt;loop &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;targs args&lt;/span&gt;&lt;span class="s0"&gt;] 
&lt;a name="l14"&gt;                (&lt;/span&gt;&lt;span class="s1"&gt;let &lt;/span&gt;&lt;span class="s0"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;result &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;apply fnc targs&lt;/span&gt;&lt;span class="s0"&gt;)] 
&lt;a name="l15"&gt;                  (&lt;/span&gt;&lt;span class="s1"&gt;if &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;= result cont&lt;/span&gt;&lt;span class="s0"&gt;) 
&lt;a name="l16"&gt;                    (&lt;/span&gt;&lt;span class="s1"&gt;recur &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;:args &lt;/span&gt;&lt;span class="s0"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;state&lt;/span&gt;&lt;span class="s0"&gt;)) 
&lt;a name="l17"&gt;                    &lt;/span&gt;&lt;span class="s1"&gt;result&lt;/span&gt;&lt;span class="s0"&gt;))) 
&lt;a name="l18"&gt;              (&lt;/span&gt;&lt;span class="s1"&gt;finally&lt;/span&gt;&lt;span class="s0"&gt; 
&lt;a name="l19"&gt;                (&lt;/span&gt;&lt;span class="s1"&gt;dosync &lt;/span&gt;&lt;span class="s0"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;alter state assoc &lt;/span&gt;&lt;span class="s2"&gt;:first-call &lt;/span&gt;&lt;span class="s3"&gt;true&lt;/span&gt;&lt;span class="s0"&gt;))))) 
&lt;a name="l20"&gt;          (&lt;/span&gt;&lt;span class="s1"&gt;dosync&lt;/span&gt;&lt;span class="s0"&gt; 
&lt;a name="l21"&gt;            (&lt;/span&gt;&lt;span class="s1"&gt;alter state assoc &lt;/span&gt;&lt;span class="s2"&gt;:args &lt;/span&gt;&lt;span class="s1"&gt;args&lt;/span&gt;&lt;span class="s0"&gt;) 
&lt;a name="l22"&gt;            &lt;/span&gt;&lt;span class="s1"&gt;cont&lt;/span&gt;&lt;span class="s0"&gt;))))))&lt;/span&gt;&lt;/pre&gt;
&lt;script src="https://gist.github.com/1753119.js"&gt; &lt;/script&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-2338684135142784227?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TNKDdUYD18opkm6X1QaFirCFOzE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TNKDdUYD18opkm6X1QaFirCFOzE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TNKDdUYD18opkm6X1QaFirCFOzE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TNKDdUYD18opkm6X1QaFirCFOzE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/5RoEJ2g1DD0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/2338684135142784227/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=2338684135142784227" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2338684135142784227?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2338684135142784227?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/5RoEJ2g1DD0/clojure-writing-tail-recursive.html" title="Clojure: writing tail recursive functions without using recur" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2012/02/clojure-writing-tail-recursive.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMMSXY6fip7ImA9WhRbEk0.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-9057276020219972555</id><published>2012-02-02T18:08:00.001+01:00</published><updated>2012-02-02T18:08:08.816+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-02T18:08:08.816+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="IntelliJ" /><category scheme="http://www.blogger.com/atom/ns#" term="leiningen" /><category scheme="http://www.blogger.com/atom/ns#" term="Maven" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Geek automation: Maven, Ant and other things</title><content type="html">&lt;p&gt;About automation, I'm definitely a geek. And I totally agree with the famous graph:&lt;/p&gt;&lt;img src="http://jonudell.net/images/geeks-win-eventually.png" /&gt;
&lt;p&gt;And I was working to a Java project with an unusual deployment. Part of the problem is that the actual application for which I was writing the plugin wasn't available as a maven repository. Moreover, running the whole thing needed some fiddling with long command line options, plus a non-trivial class-path.&lt;/p&gt;
&lt;p&gt;I started appreciating maven with leiningen, and then by itself. Moreover, it solves one of the worse problems I have with IDEs. I hate to version IDE files (after all, people may use a different environment, something many eclipse users do not even consider). And I hate to recreate them every time (especially when they are not trivial). Eventually, I hate to depend from a GUI program to actually build a project (where a command line should suffice).&lt;/p&gt;
&lt;p&gt;Then there is another problem related to libraries, i.e., I find it annoying all the solution regarding jars:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;place the jars in a system wide directory akin to /usr/local/lib&lt;/li&gt;

  &lt;li&gt;download the jars every time and manually add them to the project&lt;/li&gt;

  &lt;li&gt;create a script that downloads the jars (and curse the first time you develop on windows)&lt;/li&gt;

  &lt;li&gt;do not use external dependencies&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Maven solves all these problems together. I just name the jars in the pom and everything is taken care of. I loved the thing so much with Clojure and Leiningen that even with the despicable xml syntax things work smoothly.&lt;/p&gt;
&lt;p&gt;But I had this very important jar that ain't versioned nowhere. So maven was out of question, I thought: moreover. The idea of manually downloading the jar and then adding it to maven's repository (and doing it on the 2-3-4 computer I use) really looked unacceptable.&lt;/p&gt;
&lt;p&gt;So I dig into ant most advanced stuff and built an ant script that actually downloaded the jar for me and put it in a lib directory inside the project (packaging jars with the project is not acceptable). But I still wanted to use maven… so I learned the terribly documented ant plugin to get the dependencies from maven… and since that was not installed by default, I also wrote the code to go and get the jar.&lt;/p&gt;
&lt;p&gt;So I basically had this ant script that did everything for me… and was some hundred lines long. Eventually, I also wrote some targets to generate scripts to execute the project (I told about complex command lines).&lt;/p&gt;
&lt;p&gt;Of course, this also meant that maven was under-used. But then I realized… I have maven. I have a plugin that creates the scripts for me (not part of maven, but maven can easily get it). I only need ant to get the ant-maven bridge (which I wouldn't need anymore) and to get the missing jar. So I'm maintaining a very complex system for basically nothing: it is so much simpler to wget the jar, install it in the local maven repository and go on.&lt;/p&gt;
&lt;p&gt;Fun that in order not to write to lines a couple of times I wrote a one hundred lines script.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-9057276020219972555?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NJpHLOW83qim7CJICc_KsQSjHpQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NJpHLOW83qim7CJICc_KsQSjHpQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NJpHLOW83qim7CJICc_KsQSjHpQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NJpHLOW83qim7CJICc_KsQSjHpQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/SSbL6yvn5tY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/9057276020219972555/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=9057276020219972555" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/9057276020219972555?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/9057276020219972555?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/SSbL6yvn5tY/geek-automation-maven-ant-and-other.html" title="Geek automation: Maven, Ant and other things" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2012/02/geek-automation-maven-ant-and-other.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QFQ3g-eCp7ImA9WhRUFUo.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-5144449796774766103</id><published>2012-01-26T10:48:00.001+01:00</published><updated>2012-01-26T10:48:32.650+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-26T10:48:32.650+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Declarative Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Handle this! (views, const, state in Clojure, Java, C++ and Python)</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;The original vision Alan Key had on object oriented programming was about separate entities communicating through message passing. A logical consequence is that the global programming state is the sum of the individual states of these entities (called &lt;i&gt;objects&lt;/i&gt;). State of such objects is naturally hidden from the outside and state modifications occur only as a consequence of the exchanged messages.&lt;/p&gt;
&lt;p&gt;I would like to mention that in this model the "privacy" of internal variables is not exactly simply a matter of a keyword, but a consequence of a programming philosophy. This is not the kind of limitation you get in Java classes or C++, where the field is there, you just cannot access it. It somewhat more similar to calling a black-box with a state that is its own business; there are &lt;i&gt;no fields&lt;/i&gt;and if there are, they are just an implementation detail. Or even more so, private variables are not accessed in the same sense that the physical address of an object in Java is not part of the programming model.&lt;/p&gt;
&lt;p&gt;Such objects do not necessarily have their own thread of execution (in the sense that they are concurrently in control). However, if they had, the logical model would not be overly different. But back to the objects…&lt;/p&gt;
&lt;p&gt;I somewhat believe that objects are an overloaded metaphor. In fact, there are at least two &lt;a href="http://www.enrico-franchi.org/2012/01/java-and-clojure-how-data-structures.html"&gt;types of objects&lt;/a&gt;. And while the object oriented message only metaphor well applies for domain specific objects, I somewhat feel that it is not appropriate for some data structures. Sometimes, it is a nice property that "similar structures" have a common interface so that, for example, switching from an array to a linked-list is a painless transition, because it eases experimentation with different trade-offs regarding computational efficiency (although such problems are better solved with pen and paper).&lt;/p&gt;
&lt;p&gt;However, in other situations, accessing the internals of some complex structure is plainly the "right thing to do". It is a walking-horror from the object oriented point of view, but it plainly makes sense for computational reasons. I often have to deal with graphs with billions of nodes, and more often than not I feel that usual OO laws are too restrictive.&lt;/p&gt;
&lt;h4&gt;Graph example&lt;/h4&gt;
&lt;p&gt;A clear example here is the design of networkx.Graph: I have nothing against the design, by the way. I believe they do the right thing. Here the idea is that they have implemented their Graph internals in some way (does not matter how, right now). However, you may want to get a list of all the nodes in the graph. Now, how to do this? The first issue, is that the nodes may not be memorized in a way which is easier to return. This is actually the case: nodes are a dictionary keys, under the hood. So essentially there is no easy way to return them without calling some dict member which returns a &lt;b&gt;new&lt;/b&gt;structure holding the nodes.&lt;/p&gt;
&lt;h3&gt;State and "Static" OOP&lt;/h3&gt;
&lt;p&gt;OOP is all about state change. Perhaps just local state change, if done correctly. And hopefully the state's effect do not propagate too far from where the state is hidden. About C++, I found no other very mainstream OO language that makes it clear what you shall change and what you shall not.&lt;/p&gt;
&lt;p&gt;The C++ pragmatics is really precise on consting whatever you can const. And to solve issues where it is not practical to have a logically const object which actually mutates something inside, you can use the mutable modifier to support the idea that the object &lt;i&gt;real&lt;/i&gt;state did not change while some irrelevant parts of it indeed changed. Examples are forms of caching, counting stuff, logging to a logger we hold a reference to.&lt;/p&gt;
&lt;p&gt;Another important aspect of C++ is that it quite distinguishes between a const pointer (a pointer that cannot change) and a pointer to a const object (the pointed object cannot change). As always all this leads to additional complexity. However, declaring stuff const is good: first it is a rather strong safety guarantee, second it really leads to optimizations otherwise impossible. Still, it is tragically inadequate wrt. plainly immutable objects.&lt;/p&gt;
&lt;p&gt;Moreover, although many other languages do not have pointer arithmetics, they do have references. In Java it is possible, for example, to mark such a reference final, which essentially means it will always refer to a given object. However, there is no way to state that the actual object could not be mutated by accesses through that specific reference.&lt;/p&gt;
&lt;p&gt;In Java, the only way to achieve that goal is not providing methods that mutate the state. In fact this approach makes sense. Somewhat you make the language simpler without really losing much. And C++ newbies really do not get the whole constness thing very well.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;img src="http://farm8.staticflickr.com/7151/6764758181_45a496e761.jpg" width="480" height="476" alt="mutable-immutable.png" /&gt;&lt;/p&gt;
&lt;p&gt;Essentially, in Java you do not have the possibility to have a mutable object that some clients cannot mutate. There are options, however. For example, in Figure 1) we have two interfaces, one mutable and one immutable. We have the mutable interface extend the immutable one and the appropriate base classes.&lt;/p&gt;
&lt;p&gt;Immutability at class level can be obtained both (a) with a true immutable implementation implementing the immutable interface and a mutable implementation implementing the mutable one; or (b) with just a mutable implementation: clients that should not mutate the object will use the immutable interface. This is quite similar to the const in C++ in the sense that a const_cast is usually possible (and in this case we could just cast to the mutable interface). Such things somewhat break the whole immutability thing, but sometimes have their uses.&lt;/p&gt;
&lt;p&gt;And what is the big deal with immutability? Basically, in this context immutable stuff can be shared with no fear. And copying huge datasets is too inefficient to be considered.&lt;/p&gt;
&lt;h3&gt;Dynamic OOP&lt;/h3&gt;
&lt;p&gt;The essential problem here is that the OO language we have discussed so far are built around the idea that your co-workers will screw the project if they can do stuff. So the objective is not letting them do it. Constness shall be &lt;i&gt;enforced&lt;/i&gt;by the language (you had the opinion that I was happy about C++ const, did you?) because otherwise someone will foobar the project.&lt;/p&gt;
&lt;p&gt;On the other hand in languages such as Python you may well do everything to every object and consequently the const-enforcement does not fare very well. A bit more could be done (formally) in Ruby. Still, even then you could always hack the objects to let you do whatever you want. And believe me, you could do that also in C++ and Java, provided you have sufficient control of the environment where the program is going to be run. It is just way harder.&lt;/p&gt;
&lt;p&gt;In fact, I believe approaches where good policies about code isolation can be also (easily) implemented in Python. Good API design is of paramount importance. A C++ wise advise (from Meyers) was "Avoid returning Handles to object internals" (Item 28, Effective C++, 3rd ed, Scott Meyers, Addison-Wesley).&lt;/p&gt;
&lt;p&gt;Essentially the idea is never to let your object guts exposed and never ever let someone mess with it. This is not about trust. This is about such handles are just a sure way to break your object constraints (why I'm talking like a static programmer anyway?). The point is that such handles change state independently by the core object and this is probably going to be bad, because the corruption of the state will be revealed in a place and time extremely distant from when and where it actually happen.&lt;/p&gt;
&lt;p&gt;So, we have to carefully design our APIs, even (shall I say, especially?) if we are dynamic programmers. For example, we can return views on our object internals. Since our languages are very dynamic, such views can be easily constructed: they just have to quack like the original objects. When it makes sense, it is probably just better place the functionality in the "large" object and to delegate to the attribute (delegation is so trivial to implement in dynamic languages!). Notice that strongly interface based languages such as Java could make this approach even more natural, provided that formally specified interfaces make sense for the specific case.&lt;/p&gt;
&lt;p&gt;Sometimes it makes also sense to return object which can mutate and where their mutation influences the state of the object from which they come from. However, in this situations such objects shall be built in a way that they do not break the behavior of the object from which they were gotten. Essentially here we are just obeying principle like SRP (single responsibility principle) and design things to work together. In fact, they are not handles to the object internals at all. We are not exposing the implementation of the object: we are just exposing an interface to a part of the object state (perhaps even state that cannot be changed through the main object interface).&lt;/p&gt;
&lt;p&gt;What are the problems with this approach? As long as things are not modified, copying is fine. A view is a good thing, because it may be as efficient as possible for reading, while being completely safe. The problem essentially arises when we want to mutate the objects state: internals handles are bad, so we have to:&lt;/p&gt;
&lt;p&gt;1. carefully craft the object interface to allow modifications efficiently and that make sense to the problem at hand, without making it excessively general (because it clashes with efficiency) or excessively big (because it clashes with almost every good property OOP tries to give to programs)&lt;/p&gt;
&lt;p&gt;2. Perhaps create special objects that are able to perform controlled modifications on the original object. This may give lot of generality, in a sense, but also complicates the class hierarchy significantly.&lt;/p&gt;
&lt;h4&gt;Graph example&lt;/h4&gt;
&lt;p&gt;Back to our example… we may have many solutions. Suppose that this "get the list of nodes" operation is frequent enough. It may make sense to memorize such list separately from the dictionary. If node removal and addition is not too frequent, the additional memory may well be worth it (well, perhaps not, if we really have lots of nodes). Even if such operations are frequent, we double the cost of the addition and make deletion O(N)… but if instead of a list we use a set, we have both operation O(1) simply with an increased multiplicative constant. Of course a language could offer a dict implementation which essentially offers an efficient view over the set of keys, so that separate memorization is not needed.&lt;/p&gt;
&lt;p&gt;We could use a mutable datatype to hold the list, but then we should make a copy before returning it (this what actually happens with networkx). Not making a copy has the same problems of returning an internal handle. If we make a copy, then we could return something immutable or mutable. Essentially returning something immutable has not a lot of sense, as modifications would not affect the graph &lt;i&gt;and&lt;/i&gt;modifications to the graph are not reflected in the node-list. The simplest thing to do is plainly return a list of nodes.&lt;/p&gt;
&lt;p&gt;The true solution would be that dictionary supported a "true" view object which is able to modify the original dictionary. And actually Python 2.7 and Python 3 have it. At this point we could just return such thing and have both efficiency and functionality… were it not for a simple issue: a networkx graph has more than one internal structure holding the nodes. Thus a higher level view would need to be created which could work across the different point were the same information is memorized inside a Graph. And we are back to the "complicating the class hierarchy thing".&lt;/p&gt;
&lt;h3&gt;Immutable by default&lt;/h3&gt;
&lt;p&gt;The thing is that actually having to specify things to be const, is a bit a pain. And perhaps it is just me... but consider the Java solutions (this apply to things which roughly work like Java): we are talking about having two class and two interfaces (or just one class and two interfaces) for lots of objects. In my opinion, this is not practical. And if we want to create "well-behaved handles" things become even more complex.&lt;/p&gt;
&lt;p&gt;In fact, this is probably why it is not done (most of the times). Probably it should be sufficient to limit such strategies for things where it really matters. Think about the collections framework.&lt;/p&gt;
&lt;p&gt;On the other hand... think about a world where most things are just immutable. I think it is just a safer mind model of programming. It is not about limiting your colleagues (or yourself) on not doing things which are licit in the model and that we want to restrict.&lt;/p&gt;
&lt;p&gt;If we &lt;i&gt;think&lt;/i&gt;immutable, things are just easier. But then we are definitely moving towards the functional side of things. I'm not claiming that functional languages have &lt;i&gt;only&lt;/i&gt;immutable stuff. Even though many functional languages (Clojure, Haskell) have mostly immutable stuff. However, reasoning in terms of flows of functions and immutable objects is just easier than thinking about immutable immutable objects. At least, it should be, if we were trained to think functionally from the beginning.&lt;/p&gt;
&lt;p&gt;Here we are used to deal with const objects. Sometimes we &lt;i&gt;need&lt;/i&gt;to change the state. Two typical scenarios spring to mind. We aren't doing "Object Oriented Programming": we are just writing an algorithm and the algorithm was conceived for imperative languages. Sometimes there is no clear conversion into the functional world. Not an efficient one, at least. In this case we may want to use some special mutable object (arrays?) to perform our computation efficiently. And this may even generally work.&lt;/p&gt;
&lt;p&gt;In the second case, it is simply not practical to structure the state of the world as some function parameters. In fact most of the times the global state is to big to be wisely represented as a huge set of parameters. In this case we probably want to express the computation as a set of transformations (functions, basically) that shall be executed one after the other on the world. Here I am mostly thinking about Haskell's monads. Though, even different from a syntactical and semantical point of view, we are not far from the realm of refs/agents.&lt;/p&gt;
&lt;p&gt;The issue of efficiency, however, remains. We should still keep in mind that well buried under layers of object orientations there may be lots of hidden costs. Interfaces often get in the way of really efficient implementations, because costs are not part of the interface. The collections framework is beautiful… but sort is still implemented copying everything to an array and sorting the array.&lt;/p&gt;
&lt;h3&gt;Welcome under the sign of the Lambda&lt;/h3&gt;
&lt;p&gt;Not only it is better to have const object by default, that is to say object mutability shall be an opt-in rather than an opt-out. In fact, a part from the &lt;a href="http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html"&gt;famous koan&lt;/a&gt;about objects and closures, we have to avoid returning handles to our objects guts… but I do not see often closures that open up the enclosed state to the world.&lt;/p&gt;
&lt;p&gt;The point is that avoiding all the copy costs may be simply &lt;i&gt;the&lt;/i&gt;thing to do when we have to deal with huge datasets. Restrict mutability where needed (e.g., implementing the algorithms) but mostly use mutable input and outputs from functions. Moreover, functional code is generally flatter, which can also, in the long run, improve efficiency.&lt;/p&gt;
&lt;p&gt;Eventually, with languages such as clojure, even the perceived drawbacks of lists can be avoided using vectors, which support efficiently a different sets of primitives. Lazyness is also extremely helpful: actions that are not performed do not cost.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-5144449796774766103?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Xu_HB4xzIFB4Y8wknO9PFygboME/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xu_HB4xzIFB4Y8wknO9PFygboME/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Xu_HB4xzIFB4Y8wknO9PFygboME/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xu_HB4xzIFB4Y8wknO9PFygboME/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/LEoJfznaeVI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/5144449796774766103/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=5144449796774766103" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/5144449796774766103?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/5144449796774766103?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/LEoJfznaeVI/handle-this-views-const-state-in.html" title="Handle this! (views, const, state in Clojure, Java, C++ and Python)" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2012/01/handle-this-views-const-state-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcDSXw8fyp7ImA9WhRUFU0.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-8112653699607242544</id><published>2012-01-25T16:57:00.000+01:00</published><updated>2012-01-25T16:57:58.277+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-25T16:57:58.277+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Social Networks" /><category scheme="http://www.blogger.com/atom/ns#" term="Social Network Analysis" /><category scheme="http://www.blogger.com/atom/ns#" term="Complex Networks" /><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms" /><title>Social Network Analysis</title><content type="html">This is a presentation I gave some days ago.&lt;br /&gt;
It is rather maths heavy and the point of view is more maths than computer science.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder='0' style='width:460px;height:375px;' src='http://public.iwork.com/embed/?d=sna.key&amp;a=p1001694596&amp;h=768&amp;w=1024&amp;sw=458'&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="width:425px" id="__ss_11254350"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/rik0/social-network-analysis-11254350" title="Social Network Analysis"&gt;Social Network Analysis&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse11254350" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=sna-120125090150-phpapp02&amp;stripped_title=social-network-analysis-11254350&amp;userName=rik0" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="wmode" value="transparent"/&gt;&lt;embed name="__sse11254350" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=sna-120125090150-phpapp02&amp;stripped_title=social-network-analysis-11254350&amp;userName=rik0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/rik0"&gt;rik0&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-8112653699607242544?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uLUWU-dNQOZ0KOJa-ulBNLw_UHU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uLUWU-dNQOZ0KOJa-ulBNLw_UHU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uLUWU-dNQOZ0KOJa-ulBNLw_UHU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uLUWU-dNQOZ0KOJa-ulBNLw_UHU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/q2V2msQ7_V0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/8112653699607242544/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=8112653699607242544" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8112653699607242544?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8112653699607242544?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/q2V2msQ7_V0/social-network-analysis.html" title="Social Network Analysis" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2012/01/social-network-analysis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYHRHk4eip7ImA9WhRWF0g.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-99099234629732074</id><published>2012-01-05T10:52:00.001+01:00</published><updated>2012-01-05T10:52:15.732+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-05T10:52:15.732+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Common Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Java and Clojure - How data structures influence language usage</title><content type="html">&lt;p&gt;One of the essential points is that we are using object for at least two different things: i) data-types and ii) domain objects. Data-types are usually general entities that can make sense in every program and are not particularly related to a specific application. Examples of these objects are numbers and strings, but also vectors, lists, maps. On the other hand domain objects are domain specific and depend on the specific context. Both a payroll system and a web-server have probably some use for a vector class, however web-server probably does not have an employee class.&lt;/p&gt;
&lt;p&gt;The logic level of the objects of the two different kinds is different and code using both should not be written. Essentially, the idea is that low-level code should be encapsulated in methods or functions that work at an higher level, thus making the whole source more details because low level stuff does not clutter the flow of information. Also notice that most standard library code uses low-level abstractions, because it shall be rather domain independent. Thus better data structures mean better code.&lt;/p&gt;
&lt;p&gt;So what are these data-types? Languages differ greatly in their choice of datatypes. C has only integers and arrays, for example (ok, it is not OO, but does not matter right now). C++ inherit this. Strings are a library function, so are more well behaved collections. The interesting thing is that the different parts of the STL do not depend much on each other. So for example streams do not play really well with strings (e.g., file names cannot be strings, but in fact streams do not play well with about everything else) and std::string does not have a method such as&lt;/p&gt;
&lt;pre&gt;
vector&amp;lt;string&amp;gt; string::split(string sep);
&lt;/pre&gt;
&lt;p&gt;or, better:&lt;/p&gt;
&lt;pre&gt;
some_range&amp;lt;String&amp;gt; string::split(string sep);
&lt;/pre&gt;
&lt;p&gt;In Java, we have Strings, but collections were retro-fitted. So for example String#split returns an array of strings. In my opinion, one of the essential problems of many "static" programming languages such as C++ and Java is right here: they have the wrong primitives. Writing low level code, is very cumbersome and unnecessarily imperative (C++ STL somewhat makes an exception as it has a somewhat functional flavor the rest of the language lack).&lt;/p&gt;
&lt;p&gt;I think that having entities that fit a similar role but have very different usage places a heavy conceptual burden. In Java arrays are really different from collections: they have a &lt;s&gt;nice&lt;/s&gt; ugly syntax (but at least they have one) and cannot be used in the same ways collections can. Have different methods, names, facilities. On the other hand, collections lack a literal syntax, which is something that makes them feel "first-class". C++ has basically the very same problem; however, the STL does a great job in normalizing access patterns between STL collections and regular arrays.&lt;/p&gt;
&lt;p&gt;Back to the main subject, I feel that Java actually lacks algorithmic code that eases manipulation of collections. In fact, the only "user-friendly" feature is the "for-each" statement. Other than that, code is very imperative and comparable with C code manipulating the same structures. Plus, Maps are really ugly because a first class tuple data-type is missing.&lt;/p&gt;
&lt;p&gt;Clojure, on the other hand, has plenty of functions to manipulate low level stuff. This is rather relevant as there is a lot of code that works at this level. Being able to write it quicky is very important. Moreover, using the correct abstractions, avoid bugs. Consider for example the map functions? In a col like&lt;/p&gt;
&lt;pre&gt;
(map f coll)
&lt;/pre&gt;
&lt;p&gt;there can be only one single point of failure: what f does on the single elements. There is no explicit looping, no offset problems, nothing. Consider for example the number of things that can go wrong imperatively writing a loop that calls a function on pairs of consecutive elements in a collection. Compare it with its functional equivalent:&lt;/p&gt;
&lt;pre&gt;
(let [coll (range 10)] (map + coll (rest coll)))
&lt;/pre&gt;
&lt;p&gt;Here nothing can go really wrong. It is easier to write and easier to understand (provided you know a bit of clojure). It is worth noting that real high level object oriented languages have almost this kind of abstraction. But hey, they also have FOF and LOL (first order functions and let ovel lambda -- actually, they do not have let, but the name doesn't matter, does it?). Besides, that kind of code may also be easier to parallelize (in the sense that the compiler could do it).&lt;/p&gt;
&lt;p&gt;Then comes class specific code. Object are great, fine. However, sometimes they are just used to group data together. In a sense, it makes sense. In Java there are no tuples, maps are ugly as hell and have the stupid requirement of type uniformity. Which means that either we abuse Object or we can't use them at all.&lt;/p&gt;
&lt;p&gt;As a consequence, many specific classes are created. They have no true purpose, but carrying around pieces of data together. And that is just the task for maps, tuples, vectors. Maps, tuples and vectors have a uniform interface, "do the right thing" regardless of the types (in a decently typed language -- new definition&amp;hellip; both static, e.g., Haskell, and dynamic, e.g., Clojure, Ruby, Python, languages can qualify! ). And there are plenty of functions to manipulate such stuff.&lt;/p&gt;
&lt;p&gt;I think that one of the clearest examples is the Python tuple. A tuple is not magic. Is not clever. It is simple. Still, while in Python functions return only single values, tuples in fact allow to simulate multiple return values. And that is something which is overly useful in many different situations. In Clojure vectors can be used with a similar meaning (in fact, Clojure vectors are quite similar to Python tuples). And the destructuring syntax is amazing (once again, both in Python and in Clojure).&lt;/p&gt;
&lt;pre&gt;
for k, v in some_map:
    do_something_with(k, v)
&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre&gt;
(for [[k v] some-map] (do-something-with k v))
(doseq [[k v] some-map] (do-something-with k v))
&lt;/pre&gt;
&lt;p&gt;
Amazingly enough, the set of orthogonal language features used in both languages is roughly the same. Consider that with using a
 Set[Map.Entry[K,V]] Map#getEntrySet method... here we have this new Entry class. And perhaps somewhere else we have a Pair class which basically does the same thing, but it is a separate type, with different methods and different usage patterns. In dynamic languages at least, as long as the signature of the methods is compatible, something could be saved... but in statically typed object oriented languages, good luck with that.
&lt;/p&gt;
&lt;p&gt;
I think these are some of the reasons I find especially pleasing writing algorithmic code in Python or Clojure and rather despise the very same thing in Java.
&lt;/p&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-99099234629732074?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/g2fR104zghwyEoLVYGyIUOekfwQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g2fR104zghwyEoLVYGyIUOekfwQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/g2fR104zghwyEoLVYGyIUOekfwQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/g2fR104zghwyEoLVYGyIUOekfwQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/1GpIh-F9R4s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/99099234629732074/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=99099234629732074" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/99099234629732074?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/99099234629732074?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/1GpIh-F9R4s/java-and-clojure-how-data-structures.html" title="Java and Clojure - How data structures influence language usage" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2012/01/java-and-clojure-how-data-structures.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUHQnkzeyp7ImA9WhRXFk4.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-4474424759830355266</id><published>2011-12-23T10:23:00.000+01:00</published><updated>2011-12-23T10:23:53.783+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-23T10:23:53.783+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Common Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms" /><title>Does Clojure fix "Fundamental problems with the Common Lisp language (citation)"?</title><content type="html">I was looking for some Common Lisp libraries to implement an idea of mine. For lots of reasons I was considering not using Python or Clojure and going directly with Common Lisp (in fact, I think it is going to be Scheme... but it is hard to tell).&lt;br /&gt;
&lt;br /&gt;
As it often happens when following semi-random links on Google, I stumbled on something quite interesting:&lt;br /&gt;
&lt;a href="http://ilc2009.scheming.org/node/7" target="_blank"&gt;Fundamental problems with the Common Lisp language&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Nothing extremely new, indeed. The only point that really surprised me was the "hard to compile efficiently" thing. I would have said that in general SBCL is a pretty fast environment. Not as fast as C++, perhaps not even as Java (but I believe that this depends from the specific benchmarks used), but still fast.&lt;br /&gt;
&lt;br /&gt;
However I was mostly interested in the other claimed problems:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Too many concepts; irregular&lt;/li&gt;
&lt;li&gt;Hard to compile efficiently&lt;/li&gt;
&lt;li&gt;Too much memory&lt;/li&gt;
&lt;li&gt;Unimportant features that are hard to implement&lt;/li&gt;
&lt;li&gt;Not portable&lt;/li&gt;
&lt;li&gt;Archaic naming&lt;/li&gt;
&lt;li&gt;Not uniformly object-oriented&lt;/li&gt;
&lt;/ol&gt;
May seem like a lame argument... but I think that clojure actually addresses all the problems but number 2 and 3. Please notice that I'm not claiming that clojure is a memory hog or that it is slow. Simply put, right now my impression is that common lisp is still faster than clojure. I believe that this is due to Clojure being an additional layer over Java. Java is itself probably marginally faster than SBCL (though your mileage may vary). With marginally faster I mean that really depends on what you are doing and one or the other may result faster.&lt;br /&gt;
&lt;br /&gt;
Alioth benchmarks are, like all benchmarks, not extremely relevant. Still, this is my general impression. SBCL does a wonderful job, in that CL is much higher level than Java and there are many more engineers optimizing the JVM. However, Clojure takes its toll, in that, according to my tests (and to alioth as well) there is quite a lot of work to do to make it catch up with Java.&lt;br /&gt;
&lt;br /&gt;
Probably for high level stuff or specific problems (where in Java there would be essentially some part of clojure runtime/libraries to be re-implemented) they are on par.&lt;br /&gt;
&lt;br /&gt;
About the memory, my feeling is that JVM is a rather memory intensive business, and Clojure can't do much about it. E.g., Python programs usually run using much less memory when confronted with similar data-sets.&lt;br /&gt;
&lt;br /&gt;
I'm not saying that we should drop CL and switch to clojure. However, I believe that clojure addressed some of the problem that many (some?) in the CL community feel CL has.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-4474424759830355266?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BEMwUKApvHAFXwoR-B_aE7XUjCc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BEMwUKApvHAFXwoR-B_aE7XUjCc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BEMwUKApvHAFXwoR-B_aE7XUjCc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BEMwUKApvHAFXwoR-B_aE7XUjCc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/VzjDyMnA8T4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/4474424759830355266/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=4474424759830355266" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/4474424759830355266?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/4474424759830355266?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/VzjDyMnA8T4/fundamental-problems-with-common-lisp.html" title="Does Clojure fix &quot;Fundamental problems with the Common Lisp language (citation)&quot;?" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/12/fundamental-problems-with-common-lisp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MERXk_cSp7ImA9WhRQGUk.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-8250500985302874531</id><published>2011-12-15T10:30:00.000+01:00</published><updated>2011-12-15T10:30:04.749+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-15T10:30:04.749+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="IntelliJ" /><category scheme="http://www.blogger.com/atom/ns#" term="PyCharm" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Better toys for us programmers</title><content type="html">Today PyCharm 2.0 is out. A couple of days ago, the last version of IntelliJ (11) was released as well.&lt;br /&gt;
&lt;br /&gt;
I'm somewhat reluctant to discuss the matter here; I'm not a free software integralist by any means (like for example posting from a beautiful MacBook Air, with OS X), still when discussing commercial software I feel a vague sense of guilt because I feel like I am doing advertisement. This is especially true as most of the times there it does not involve only reporting &lt;i&gt;facts&lt;/i&gt;&amp;nbsp;(which would be acceptable, as the truth tends to be true, even if in favor of a commercial entity) but &lt;i&gt;impressions&lt;/i&gt;, which could make me seem biased.&lt;br /&gt;
&lt;br /&gt;
These are the most interesting improvements I found in PyCharm/IntelliJ (it should be clear when stuff applies only to one of the two -- and amazingly enough, the what's new page on PyCharm is more detailed):&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Support for pypy (this is going to be immensely important for me, as I'm planning to move part of my development environment on pypy)&lt;/li&gt;
&lt;li&gt;Support for ipython (more on this later)&lt;/li&gt;
&lt;li&gt;Cython support (which may be something I'll be using soon enough)&lt;/li&gt;
&lt;li&gt;Git graphs (been a bit of a PITA lately to remember the proper log options to have them in the console, my memory ain't what it used to be)&lt;/li&gt;
&lt;li&gt;Gist support (I love that)&lt;/li&gt;
&lt;/ul&gt;
There is more. I did not even realize that before it was not there... but for example now PyCharm completes the keyword arguments in Python stuff. Which is extremely nice, in my opinion. And also the refactorings seem to work more accurately.&lt;br /&gt;
&lt;br /&gt;
Eventually, I want to point out a feature I was sorely missing in all environments I tried, i.e., choosing the method to step into when debugging. First, I'm not the kind of guy that spends lots of time in the debugger (see., that would be a clear smell on the quality of my unit tests). But when I do, I often feel rather boring having to walk step by step irrelevant code.&lt;br /&gt;
&lt;br /&gt;
Consider this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;my_object.that_is_some_method(
    ILuvDIP(...), self.that_is_interesting(), self.may_be_a_property)
&lt;/pre&gt;
&lt;br /&gt;
and suppose that I feel the bug is in that_is_interesting. Now, it may well be that my Python debugging skills are not excellent. Afterall only recently I stopped instrumenting my code with prints and always use a proper debugger. Before that I relied almost only on unittests and prints.&lt;br /&gt;
&lt;br /&gt;
Before PyCharm 2, it was hard to step into that_is_interesting and not in ILuvDIP. I believe that the same logic also applies to Java and IntelliJ and hopefully to Clojure. Then, back to us.&lt;br /&gt;
&lt;br /&gt;
I really ain't lots of problems with IntelliJ. I feel that an IDE is a very valuable asset when developing Java. In fact, I would say it is a PITA to do without. Perhaps with Emacs and some modules like JDEE. Still, I don't know... I try to avoid Emacs these days (as I'm finding vi more and more natural to me).&lt;br /&gt;
&lt;br /&gt;
The question is more interesting regarding Clojure and Python (and Ruby...). Probably if I would use Django a lot, PyCharm would be a clear winner. Support is awesome and you have to work in a frameworkish way in any case. There is nothing wrong with that, of course.&lt;br /&gt;
&lt;br /&gt;
These days I'm mostly writing library/algorithmic code in Python. And I feel like ipython+vim is a great tool here. It's got an almost Mathematica/Matlab vibe that is nice for what I'm doing. I also try using that approach with Clojure more often than not. Tests as documentation and specification, REPL as an integrated development environment. It is possible that with ipython builtin in PyCharm I could just move that workflow to PyCharm itself.&lt;br /&gt;
&lt;br /&gt;
There is however, the issue of code complete. Emacs fares pretty well to complete Clojure, but as far as I remember is not so good regarding completing Java (perhaps I should have installed JDEE). As a consequence, I used IntelliJ a lot even with Clojure.&lt;br /&gt;
&lt;br /&gt;
Recently, I started exploring Clojure+vim too. And it is a wonderful world. I have most of what I need and it is extremely lightweight. I have to investigate the issues further. However, IntelliJ remains a solid environment for Clojure development.&lt;br /&gt;
&lt;br /&gt;
Now the essential question is... I quite need IntelliJ for Java. And having it working with Clojure is a big plus (even if maybe not a strict necessity). But should I buy a separate PyCharm or just rely on IntelliJ plugin?&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-8250500985302874531?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/B_tQlE3xL3o3SMvDyJ7XeBUdmqQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B_tQlE3xL3o3SMvDyJ7XeBUdmqQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/B_tQlE3xL3o3SMvDyJ7XeBUdmqQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B_tQlE3xL3o3SMvDyJ7XeBUdmqQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/nmhJdthVYBs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/8250500985302874531/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=8250500985302874531" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8250500985302874531?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8250500985302874531?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/nmhJdthVYBs/better-toys-for-us-programmers.html" title="Better toys for us programmers" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/12/better-toys-for-us-programmers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4GRnY5cSp7ImA9WhRQFkQ.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-8113165400561193441</id><published>2011-12-12T14:52:00.001+01:00</published><updated>2011-12-12T14:52:07.829+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-12T14:52:07.829+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Object Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Common Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="Declarative Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="Erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Haskell" /><title>Erlang and OTP in Action (review)</title><content type="html">&lt;p&gt;First time I got into Erlang, it was with &lt;a href="http://www.amazon.com/Programming-Erlang-Software-Concurrent-World/dp/193435600X%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D193435600X"&gt;"Programming Erlang: Software for a Concurrent World" (Joe Armstrong)&lt;/a&gt;. It is a very nice book, in my opinion, and I enjoyed immensely reading it. That was like 4 years ago or something. Back then, the functional revolution was just at the beginning: no widespread Scala, no Clojure at all, essentially no F#. Back then it looked like OO was going to rule the industry for years and years, with no contender of sort. Rails was fresh, Django was fresher (back then the APress book was just being released).&lt;/p&gt;
&lt;p&gt;I bought the book because I wanted to see this "brand new" technology (20 year old, but just going to make it through in the circles I did frequent). And really, the language looked like 20 years old. Full of Prolog legacy, Unicode who's that guy? and so on. However, it no other piece of software I knew could as easily. Massive concurrency, hot swapping code. Wow.&lt;/p&gt;
&lt;p&gt;The language, I did not especially like. The runtime… WOW! As a language, I love Python or Clojure because the way apparently distant functionalities work together and create something even more beautiful. Erlang does not have that at language level. It has at a framework level.&lt;/p&gt;
&lt;p&gt;Think about hot swapping code in an object oriented software. First, I somewhat believe that object oriented modules are somewhat more tangled that functional equivalents. Partly because of the object reuse OO promotes (that can really be against you if you want to swap code). Then, there is the whole problem of references vs. addresses. Addresses have an additional level of indirection that makes it far easier to swap a process than it is to swap an object.&lt;/p&gt;
&lt;p&gt;But the very idea that state is in the function parameters and that process linking and easy restarting thing are at the very root of how easy it is to swap code in Erlang. But then… back to the books.&lt;/p&gt;
&lt;p&gt;The essential problem was that after seeing a bit of Erlang, I thought OTP was not a big deal. Yes, it is easier to use. But also plain Erlang is. And I convinced myself that should I need Erlang, I could just use plain Erlang. Than things changed: I read some OTP using code and I understood not so much of it. That was this year. What I understood, was that it could be helpful. I had to write a concurrent prototype and I welcomed the idea not to write as much code as possible.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;In the meantime, I forgot many things about Erlang. In this situations, instead of reading the same book twice, I buy another book to gain perspective. So I decided to buy another book. One of the candidates was &lt;a href="http://www.amazon.com/ERLANG-Programming-Francesco-Cesarini/dp/0596518188%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596518188"&gt;"ERLANG Programming" (Francesco Cesarini, Simon Thompson)&lt;/a&gt;. It also had excellent reviews. Essentially I believe it contains more material than Armstrong's book and is also a bit more recent. However, as far as I understand, is still a bit terse on OTP.&lt;/p&gt;
&lt;p&gt;As a consequence, I bought &lt;a href="http://www.amazon.com/Erlang-OTP-Action-Martin-Logan/dp/1933988789%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1933988789"&gt;"Erlang and OTP in Action" (Martin Logan, Eric Merritt, Richard Carlsson)&lt;/a&gt; instead. And I'm very happy of this choice. It complements Armstrong's book well and extensively covers OTP. In fact, I also believe that the approach is very interesting. Introduce OTP first and learn to use it, then when you know what it can do, you are going just to use that. Then, learn plain Erlang in order to extend OTP when your use case is not covered. And a nice plus was a detailed description of JInterface, which I could need as well.&lt;/p&gt;
&lt;p&gt;In fact, I do think that as it may make sense to introduce objects as early as possible in a book on an object oriented language, starting with OTP is a very big plus from a learning perspective. Then perhaps the point is that I did not need to get into a functional mindset (which I think Armstrong book does with more attention.&lt;/p&gt;
&lt;p&gt;If the question is however just "learn to think functionally" I believe that &lt;a href="http://www.amazon.com/Joy-Clojure-Thinking-Way/dp/1935182641%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1935182641"&gt;"The Joy of Clojure: Thinking the Clojure Way" (Michael Fogus, Chris Houser)&lt;/a&gt;, &lt;a href="http://www.enrico-franchi.org/2011/08/excellent-learn-you-haskell-for-greater.html"&gt;LYHFGG&lt;/a&gt; or &lt;a href="http://www.enrico-franchi.org/2010/12/land-of-lisp-part-1.html"&gt;Land of Lisp&lt;/a&gt; are probably better alternatives. Another interesting one is &lt;a href="http://www.amazon.com/Functional-Programming-Java-Developers-Concurrency/dp/1449311032%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1449311032"&gt;"Functional Programming for Java Developers: Tools for Better Concurrency, Abstraction, and Agility" (Dean Wampler)&lt;/a&gt;, even if it has a whole different perspective.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-8113165400561193441?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4qUhg0qREscCeXSu0EWWs1kXgBc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4qUhg0qREscCeXSu0EWWs1kXgBc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4qUhg0qREscCeXSu0EWWs1kXgBc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4qUhg0qREscCeXSu0EWWs1kXgBc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/bfKDu9Jq4oI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/8113165400561193441/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=8113165400561193441" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8113165400561193441?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8113165400561193441?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/bfKDu9Jq4oI/erlang-and-otp-in-action-review.html" title="Erlang and OTP in Action (review)" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/12/erlang-and-otp-in-action-review.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YBRXsyfip7ImA9WhRQFU0.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-549212680052598718</id><published>2011-12-07T10:00:00.000+01:00</published><updated>2011-12-10T10:25:54.596+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-10T10:25:54.596+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="xUnit" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="IntelliJ" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="LLVM" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Good and not so good reasons to learn Java (or any other language) [part 2.5]</title><content type="html">So this is the third part after the &lt;a href="http://www.enrico-franchi.org/2011/11/good-and-not-so-good-reasons-to-learn.html" target="_blank"&gt;not so good reasons to learn Java&lt;/a&gt; and the &lt;a href="http://www.enrico-franchi.org/2011/12/good-and-not-so-good-reasons-to-learn.html" target="_blank"&gt;other good reasons&lt;/a&gt; to do it.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Java could be fun&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Really. There is some stuff that is really nicely done. I like Akka, for example. And I find the idea of hacking with assertion really funny. It is a totally different approach to meta-programming that I really liked. I also like Antlr... after that every other library for imperative/oo-languages to build parsers seemed primitive.&lt;br /&gt;
&lt;br /&gt;
There is some nice stuff in the Python world as well (and yeah, in Lisp you have Lisp and Haskell has wonderful stuff to). But I can tell: implement a language in Java and in C++. In Java you will be finished so much earlier... of course, other languages are faster too. But your team may not include other Haskell hackers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Libraries, libraries, libraries&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In Java there is a library for everything. Quite often, they are very well done, even if somewhat over-engineered. Probably my idea of over-engineering is a bit extreme (it comes from having seen lots of lean languages). But really, they are robust and well tested.&lt;br /&gt;
&lt;br /&gt;
Moreover, Java is usually efficient enough to be a decent contendant for more demanding tasks.. Maybe C/C++ can be avoided for your application (and Java libraries are usually easier to use than C++ ones).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Java as an intermediate level platform&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Say you are interested in language design. As far as I can see, you have few choices.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Write your own runtime, vm, etc. That was the "old" approach (Python, Ruby)&lt;/li&gt;
&lt;li&gt;Implement your language on the top of a Lisp[0] or Prolog[1] interpreter&lt;/li&gt;
&lt;li&gt;Use LLVM&lt;/li&gt;
&lt;li&gt;Use JVM&lt;/li&gt;
&lt;li&gt;Use CLR/Mono&lt;/li&gt;
&lt;/ul&gt;
I would rule out the latter, because I don't do any windows. Between LLVM and JVM as far as I understand it may depend on the language. JVM has a few quirks (who said lack of TCO?), but has plenty of available documentation, real world examples (Scala &amp;amp; Clojure),&amp;nbsp;&lt;a href="http://www.enrico-franchi.org/2011/02/java-epic-fail.html" target="_blank"&gt;a large number of developers working for the well-being of the plarform&lt;/a&gt;, and a huge amount of libraries, libraries, libraries you may want to use.&lt;br /&gt;
&lt;br /&gt;
LLVM is probably going to be faster, though. And has lots of optimizations and stuff for static languages. In any case, to make an informed choice, you need to know Java&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Tools (IDEs, Maven, Ant)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
IDEs are the bless and the curse of Java. After having used for sometime IntelliJ I really feel that the amount of functionality that IDEs for other languages offer is puny. The possible exception is Emacs for Lisps.&lt;br /&gt;
&lt;br /&gt;
The funny thing is that I'm not an IDE gui. However, really, when you do refactoring (even simple stuff like moving functions and files around) it is an invaluable time-saver. I miss vim as a text manipulating programming language, but still... for Java IDEs are almost necessary.&amp;nbsp;&lt;i&gt;And&lt;/i&gt;&amp;nbsp;not only bridge part of the gap with other languages, they have lots of useful stuff.&lt;br /&gt;
&lt;br /&gt;
Regarding Maven... well, I just like it. I also like the fact that I'm able to build IntelliJ projects from Maven scripts is wonderful. And also Ant is a very good tool (although rather over-engineered). My humble opinion is that Ant is far easier to use than the whole autotools company. This may also have something to do with the fact that the whole Java deploy process is easier.&lt;br /&gt;
&lt;br /&gt;
In any case, the point here is not how cool is Maven. Developers from other platform may want to know what is boiling up in Java-land. Sometimes we have sub-par tools and we do not even know it. Of course quite often Java tools fix "Java problems" that are different from the ones we have in other languages. Sometimes not.&lt;br /&gt;
&lt;br /&gt;
E.g., the design of Maven could inspire similar tools for the other platform. Both for its strengths and for its weaknesses (to avoid them, of course).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Learn "classical" threads&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ah, this is weak. However, other languages have a "threading" module that is heavily inspired by the way Java does threading. I don't particularly like it, but being familiar with it may be a very good idea. As far as I can tell, is also what most people have in mind when thinking about threading. Who am I to say that they are wrong? I can just tell them there is better stuff.&lt;br /&gt;
&lt;br /&gt;
And yes, pthreads are even more a PITA.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Find Java in other languages. Sometimes.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is basically the extended version of the older argument. Java is hugely popular. Many "new" things are created in Javaland, and then are ported to other platforms. Or perhaps are not &lt;i&gt;created&lt;/i&gt;&amp;nbsp;but became first popular inside the Java community.&lt;br /&gt;
&lt;br /&gt;
For example, xUnit libraries are available everywhere, but I think that most people first started working with it in Java. Some of the authors of the original Smalltalk library actively work on JUnit, etc etc etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
I do not think that Java is particularly good. Not particularly bad, either. It is not the kind of enlightening language Scheme is. It is not easy to use and predictable like Python. However, its popularity may make it unwise not to learn it. Especially for communication reasons:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Books&lt;/li&gt;
&lt;li&gt;Other developers (talking about OOP, libraries)&lt;/li&gt;
&lt;li&gt;New ideas brewed in Javaland&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
wow... that's it. ;)&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
[0] Scheme, Clojure, Common Lisp...&lt;br /&gt;
[1] Erlang was created this way, even if now it has its own (wonderful) runtime&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-549212680052598718?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DP53YLQ7icS2pSgV2sjWfvsZNFI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DP53YLQ7icS2pSgV2sjWfvsZNFI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DP53YLQ7icS2pSgV2sjWfvsZNFI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DP53YLQ7icS2pSgV2sjWfvsZNFI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/sNd2iGFsZeM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/549212680052598718/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=549212680052598718" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/549212680052598718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/549212680052598718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/sNd2iGFsZeM/good-and-not-so-good-reasons-to-learn_07.html" title="Good &lt;s&gt;and not so good&lt;/s&gt; reasons to learn Java (or any other language) [part 2.5]" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/12/good-and-not-so-good-reasons-to-learn_07.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cBR30_fCp7ImA9WhRQFU0.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-2131399293716582364</id><published>2011-12-03T10:00:00.000+01:00</published><updated>2011-12-10T10:24:16.344+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-10T10:24:16.344+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scala" /><category scheme="http://www.blogger.com/atom/ns#" term="Object Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Good and not so good reasons to learn Java (or any other language)[part 2]</title><content type="html">So this is basically the second part of "&lt;a href="http://www.enrico-franchi.org/2011/11/good-and-not-so-good-reasons-to-learn.html" target="_blank"&gt;Good and not so good reasons to learn Java&lt;/a&gt;".&lt;br /&gt;
&lt;br /&gt;
And here I will discuss the &lt;i&gt;good&lt;/i&gt; reasons to learn Java. Some of them...&lt;br /&gt;
I decided to split this in two posts. The &lt;a href="http://www.enrico-franchi.org/2011/12/good-and-not-so-good-reasons-to-learn_07.html" target="_blank"&gt;next one&lt;/a&gt; will be published in a few days.&lt;br /&gt;
&lt;br /&gt;
If you know me a bit, you probably know that I do not like Java particularly. In fact I found out that the essential problem is with Java being presented as something modern or "superior". It is not. However, it did something very good in the software environment (a part from electing over-engineering as a form of art): many technology that were outside the mainstream and was dubbed slow (garbage collector) are now widely accepted and that is partly because of Java. This is no reason to learn Java, though.&lt;br /&gt;
&lt;br /&gt;
Moreover, my opinion is that Java is not a good first language. It is not a good second language either. However, after learning a high level language like Python or Ruby, a couple of functional languages (maybe Clojure and Haskell or Scheme and Scala) and something lower level, such as C, well... learning Java it could be a very good idea.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Lots of interesting stuff runs on the JVM&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Yes... I'm talking about Clojure and Scala. And perhaps JRuby too. Sometimes understanding the underlying platform helps understanding some design choices. Moreover, there is stuff (e.g., in Clojure) that has not yet a fully clojurized variant and we have to use Java stuff.&lt;br /&gt;
&lt;br /&gt;
Knowing Java is a plus, of course.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Lots of interesting books deal with Java&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I'm not talking here about the wonderful Effective Java or Java Puzzles. They are great Java books, of course. And some suggestions may also apply to other languages. Still, if you are not interested into Java, you may miss them.&lt;br /&gt;
&lt;br /&gt;
No, I'm talking about other great books...&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0132350882"&gt;Clean Code&lt;/a&gt; and &lt;a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0135974445"&gt;Agile Software Development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/xUnit-Test-Patterns-Refactoring-Code/dp/0131495054%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0131495054"&gt;xUnit Test Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Analysis-Patterns-Reusable-Object-Models/dp/0201895420%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201895420"&gt;Analysis Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0201485672"&gt;Refactoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0321127420"&gt;Patterns of Enterprise Application Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/First-Design-Patterns-Elisabeth-Freeman/dp/0596007124%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596007124"&gt;Head First Design Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/Functional-Programming-Java-Developers-Concurrency/dp/1449311032%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1449311032"&gt;Functional Programming for Java Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;Here the list could be really long...&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Some of them are not entirely in Java and some have non-Java alternatives. Still &lt;i&gt;reading&lt;/i&gt; Java is a huge plus in reading those books. I believe part of the reason is that:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Java is like a common-denominator object oriented language&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Forget the Java platform. Consider just the language. Essentially Java is really a common-denominator of other object oriented language. Other languages typically offer &lt;i&gt;more&lt;/i&gt;. Are more dynamic, offer more powerful type-systems, more expressive constructs.&lt;br /&gt;
&lt;br /&gt;
Just thing about the OOP building blocks. Here we are talking about the mis-interpreted OOP as a matter of types vs. a matter of messages. That is what most people think about when referring to OOP. Unfortunately, as I said.&lt;br /&gt;
&lt;br /&gt;
Java has those. But does not have much more. If you want to design OO stuff, Java gives you the building block, but does not stand above offering higher level construct. Think about Python or Ruby or Lisp... their OO facilities are so superior (plus they typically offer stuff outside the OOP model -- well, Lisp is so much more than an OO language...) that you are probably going to design stuff differently. Probably you are not going to over-engineer stuff.&lt;br /&gt;
&lt;br /&gt;
Modifications are cheap. Abstractions are easy. And of course you can go outside the OO model when it makes sense.&lt;br /&gt;
&lt;br /&gt;
On the other hand in Java you cannot. You can just get back at a procedural level, which is clearly inferior. The best thing you can do in Java is try to be as OO as possible: other choices usually do not pay.&lt;br /&gt;
&lt;br /&gt;
As a consequence:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Java is a great language to expose those "ill-conceived OOP" concepts that are used in every other language where ill-conceived OOP techniques are used.&lt;/li&gt;
&lt;li&gt;Java is a great language to truly learn to program like an object-oriented zealot&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
Please notice that I consider the latter a very good thing. It is a very good exercise that lets you understand the merits and the drawbacks of the paradigm. Probably when you think that something really sucks in Java, you hit a limit of OOP in a static language. Other languages may make that easier, but the wall is still there.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Java is good to learn "good OOP" too&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Yes! As I already said there is a lot of smart people working with Java. They have already discovered and taught how to do "good" OOP in Java. You should learn it too.&lt;br /&gt;
&lt;br /&gt;
Then, when using a different language things could only be easier. Some of the techniques you learned may be useless, because the language offers better abstractions. Still you will have a pretty clear understanding of what such abstractions are doing and perhaps you may develop a feeling for when not to use them.&lt;br /&gt;
&lt;br /&gt;
As a matter of fact, too much magic is bad, even if it may seem cool. While sticking too much to simple things may actually complicate the design in the long run (meta-programming leads to code that you do not write and that is the only kind of code that needs no debugging or testing or maintenance, as it does not exist), too much magic has the same effect at the opposite position of the spectrum.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Avoid writing Java in other languages&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
If you know Java, at a certain point you may discover you would be writing much the same code if you were using Java. If the language you are using is C++, you probably have done something wise: chosen a restricted subset of C++ and used that one (than we may argue if you actually left out good stuff).&lt;br /&gt;
&lt;br /&gt;
However, if you are using Python or Ruby, or, worse, Clojure, then you are writing awful code. $x code is not meant to be structured like Java. If it does, you are not using the language well. This is basically a side effect of "&lt;i&gt;Java is like a common-denominator object oriented language&lt;/i&gt;".&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-2131399293716582364?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6XQCGkElKGqXeWRWKwggkiVfCvc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6XQCGkElKGqXeWRWKwggkiVfCvc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6XQCGkElKGqXeWRWKwggkiVfCvc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6XQCGkElKGqXeWRWKwggkiVfCvc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/wLGZnIrJQYI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/2131399293716582364/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=2131399293716582364" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2131399293716582364?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2131399293716582364?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/wLGZnIrJQYI/good-and-not-so-good-reasons-to-learn.html" title="Good and not so good reasons to learn Java (or any other language)[part 2]" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/12/good-and-not-so-good-reasons-to-learn.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEGQ3Yzeip7ImA9WhRRGU8.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-2089304051938765570</id><published>2011-11-26T21:03:00.001+01:00</published><updated>2011-12-03T16:53:42.882+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-03T16:53:42.882+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Object Oriented Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Django" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="Erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Haskell" /><title>Good and not so good reasons to learn Java (or any other language)</title><content type="html">The first thing to consider is there is really not such a thing like a reason &lt;i&gt;not to learn&lt;/i&gt;&amp;nbsp;a programming language. Or better, there is only one reason: lack of time. Learning a language is a tricky business[0]. Learning to use a whole platform is way trickier.&lt;br /&gt;
&lt;br /&gt;
Please notice that some of the reasons presented here are general enough to be applied to &lt;i&gt;any&lt;/i&gt;&amp;nbsp;programming language (especially the bad reasons to learn a language). Others are specific of Java (especially the reasons to learn it).&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that the &lt;i&gt;good&lt;/i&gt;&amp;nbsp;reasons to learn Java will be presented in &lt;a href="http://www.enrico-franchi.org/2011/12/good-and-not-so-good-reasons-to-learn.html" target="_blank"&gt;another post&lt;/a&gt; because this one is becoming far to long to be readable in the few minutes I feel entitled to ask you, dear reader. So believe me... you probably &lt;i&gt;should&lt;/i&gt;&amp;nbsp;learn Java. Still, not for the reasons I list here.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Not so good reasons to learn Java&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It is widespread&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You may be lead to think that since Java is a very widespread language, it is easier to find jobs if you know it. In the case of Java there is the question that I am convinced that it is not a bad thing to know Java and that can have pleasant effect on finding jobs (more on that later), still I would not consider it a &lt;i&gt;good&lt;/i&gt;&amp;nbsp;reason to learn Java.&lt;br /&gt;
&lt;br /&gt;
Learning a widespread language means more jobs and more applicants. What really matters is the ratio between jobs demand and offer. And usually for very widespread languages it is not always very high. Skilled, experienced and "famous" developers do not care much. The others should.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It is object oriented&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This and the variant "it is &lt;i&gt;more&lt;/i&gt;&amp;nbsp;object oriented" are clearly wrong reasons. There is plenty of good object oriented languages. And it is rather hard to decide which is &lt;i&gt;more&lt;/i&gt;&amp;nbsp;object oriented (lacking function looks more like a wrong design decision than a clue of being &lt;i&gt;more&lt;/i&gt;&amp;nbsp;object oriented).&lt;br /&gt;
&lt;br /&gt;
Besides, I'm not even sure that being &lt;i&gt;more&lt;/i&gt;&amp;nbsp;object oriented is good (or bad for what matters). Well... not sure that being object oriented is inherently good either. Maybe in ten years the dominant paradigm will be another. Maybe in two. Three years ago "functional programming" was murmured in closed circles and outsiders trembled in fear at its very sound.&lt;br /&gt;
&lt;br /&gt;
No, joking. Most people thought that "functional" meant having functions (and possibly no objects) and thought about C or Pascal. They did not know it was about &lt;i&gt;not having crappy functions&lt;/i&gt;. Yeah, more than that, of course, but that's a start.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It is a good functional language&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Just checking if you were reading carefully...&lt;br /&gt;
That is a bad reason because it is not true!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It is fast/slow&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Oh, come on! Java implementations are decently fast, faster than most other language implementations out there and usually slower than implementations of languages such as C, C++, Fortran. Still, for some specific things it may be nearly as fast or faster. Sometimes it is not only CPU efficiency that matters.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It is good for concurrency&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The "classic" Java threading model sucks. It's &lt;i&gt;old&lt;/i&gt;. Nowadays other ways of doing concurrency are better (more efficient, easier to use).&lt;br /&gt;
&lt;br /&gt;
Such more efficient easier to use methods are built-in in languages such as Clojure (or Scala, or Erlang). Still, Java is probably the most supported platform in the world. Such concurrency models are not &lt;i&gt;inside&lt;/i&gt;&amp;nbsp;the language, but you may have them using libraries.&lt;br /&gt;
&lt;br /&gt;
Sometimes this is a real PITA (language support is a great thing, because the syntax is closer to the semantics).&lt;br /&gt;
&lt;br /&gt;
Moreover having the "older" concurrency model visible may be a problem with the newer stuff. And some other libraries and frameworks may just assume you want to do things the old way.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It is good for the web&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ok... most people do not even know how widespread is Java on the web. In fact, it is. But is it &lt;i&gt;really good?&lt;/i&gt;&amp;nbsp;I do not really think so. There is lots of good stuff in Java world for the web, of course. The point is that there is also for other platforms. Here Rails and Django spring to mind.&lt;br /&gt;
&lt;br /&gt;
Moreover, there is loads of extremely cool stuff coming from the functional world. Erlang and Haskell have some terrific platforms. Scala and Clojure also have some extremely interesting stuff &lt;i&gt;and &lt;/i&gt;can leverage mature Java stuff but make it really easier to use.&lt;br /&gt;
&lt;br /&gt;
Grails (web framwork) may seem on the same wavelength, still I think there is a very important difference.&amp;nbsp;First, I don't like Groovy at all. In fact Groovy very author says that he would not have created it if he knew Scala. And of course since I do not like Groovy, I do not see why I should be using Grails, which, as far as I know, does not offer killer features over Rails or Django.&lt;br /&gt;
&lt;br /&gt;
Scala and Clojure are different. They are not just "easier" than Java. They teach a different way of thinking and approaching development. And of couse, they are great for the web also.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;I already know it a bit&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is quite an interesting point. Why, if you know a language a little, shouldn't you learn it well? This essentially makes it clear the difference between a &lt;i&gt;not so good reason&lt;/i&gt;&amp;nbsp;to learn something and a reason &lt;i&gt;not to learn it&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
The point is simple: if you are interested in learning Java (for the good reasons), do it. But from knowing a language "a bit" and knowing it "well" there is quite the same distance that from not knowing it and knowing it well. So don't do it because you think your prior experience may be extremely relevant.&lt;br /&gt;
&lt;br /&gt;
There are languages which are just easier to master (where easier means that to learn them from scratch it takes less time that to become as proficient in Java as you would learning those languages -- yeah, Python, Ruby, [1]...)&lt;br /&gt;
&lt;br /&gt;
Besides, I feel that the second step in Java is rather hard. I think that Java is very easy to learn for experienced developers (it is not a joke). The very first step in Java is relatively easy (a part from lots of useless crap like having to declare a class to put there a static main method and overly complicated streams). The step just after that, the one that takes you from writing elementary useless programs to writing elementary useful programs is quite harder, since lots of useful stuff in Java requires to understand OO principles quite well to be used without too many surprises.&lt;br /&gt;
&lt;br /&gt;
So, you may have learnt Java at the college. Still, if you to hack something and "grow" there are languages that let you do it faster (Python or Ruby).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;I have to&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is the worse possible reason because I don't see the spark in it. You have to. You probably are an experienced developers that got bored to death reading this post, you did not know Java and you have to learn it. Maybe your boss wants you to do some Java.&lt;br /&gt;
&lt;br /&gt;
I'm sorry for you. Java is not easy to learn (especially to learn it at the point you can work with it). Mostly because everybody has been doing Java in the last fifteen years. Smart people and dumb people.&lt;br /&gt;
&lt;br /&gt;
As a consequence there are truly spectacular pieces of software it is a pleasure to work with and worthless pieces of over-engineered crap. I truly hope that you are going to work with the great stuff.&lt;br /&gt;
&lt;br /&gt;
Still I consider a "bad reason" to learn a language, because you are probably not going to enjoy the learning process. If you were, you would have used a different sentece... like "I want to".&lt;br /&gt;
And perhaps the thing would have been "My boss gives me the opportunity to increase my professional assets learning this new technology, Java".&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It was easier to download/find a book/my cousin knows it.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
One of the most popular reasons people pick up a language is because they find it installed on their system. That is not usually the case for Java, in the sense that usually the JDK is &lt;i&gt;not&lt;/i&gt;&amp;nbsp;installed, even if the VM is. Variants of this argument are a friend proficient in the language or, more frequently, availability of books at the local bookstores. This kind of arguments usually apply for complete programming beginners or people who had prior experience that has not been refreshed for years (e.g., old Basic programmers).&lt;br /&gt;
&lt;br /&gt;
It is true that it is easy to find manuals for Java. The point is that not every manual is a good starting point. Specifically, this kind of user really needs a manual targeted at a true beginner. Unfortunately, that is the category of books where more craps piles. First beginners usually do not really understand if the manual they are using is crap.&lt;br /&gt;
&lt;br /&gt;
If their learning process is too slow (supposed that they see it) they usually blame: (i) programming in general, (ii) the language or, worse (iii) themselves. Well, the language may have its faults (especially in the case of Java, still C++ is worse for a beginner), but it is important to understand that the culprit is usually the manual.&lt;br /&gt;
&lt;br /&gt;
The funny thing is that the people who know how to tell apart a good manual from a bad one are usually the ones that do not really need an introductory book, are probably not going to buy it and more often than not are not enquired about a good manual. So unless their cousin is actually a skilled programmer, beginners are really risking buying a bad manual. And please, notice that even skilled programmers are susceptible to a similar argument: if you are interested in a new language and you read a terrible manual you may build a wrong opinion on the language (and perhaps you are not interested in spending another 40 gold coins to convince you that the language is really bad).&lt;br /&gt;
&lt;br /&gt;
So please: read reviews on Amazon (or similar site -- notice that I'm not going to suggest to buy from Amazon, even if I often do &lt;i&gt;and&lt;/i&gt;&amp;nbsp;I am an associate -- here I'm just saying that the amount of reviews on books on Amazon -- com -- is usually large enough to make an idea). Find people that are experts &lt;i&gt;and&lt;/i&gt;&amp;nbsp;have teaching experience: their reviews are probably the one to base the judgment upon. Then buy the book from whatever source you want.&lt;br /&gt;
&lt;br /&gt;
So do not buy a Java book because you can find books on Java and not on Clojure[2]/Python/Ruby/Whatever[3]. Choose the language (this is hard), choose the book (this is easier), buy, read it, study it, code code code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;ol start="0"&gt;
&lt;li&gt;I kind of found out that for people really convinced that learning a language is easy one or more of the following apply: &lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;have an unmotivatedly high opinion of their knowledge of the languages they claim to have learned&lt;/li&gt;
&lt;li&gt;have a very inclusive definition of "learning" a language (e.g., writing hello world in it)&lt;/li&gt;
&lt;li&gt;only know and learn very similar languages (really, if you know C++ it's gonna be relatively easy to pick up Java, if you know Scheme probably Clojure is not going to be a big deal, etc.)&lt;/li&gt;
&lt;li&gt;and tend to write "blurb" in every language they know (so for example they write Python as if it was C++ -- and usually are very surprised when things go badly)&lt;/li&gt;
&lt;/ol&gt;
Of course there is also a lucky minority for which learning languages is very easy.&lt;/li&gt;
&lt;li&gt;It is funny that I am suggesting to learn only "object oriented dynamic" languages such as Python or Ruby. I understand that many advocates of functional programming may disagree. But I somewhat think that while some kind of people greatly benefit from learning a functional language as the first language they truly master, many others are just not fit for functional programming because it is too abstract and working imperatively may be easier for them. As a consequence, languages such as Python or Ruby may naturally lead you towards functional programming if it is the kind of stuff you like, but are still usable if you are not that kind of person. I have seen things...&lt;br /&gt;
And yes... if you are the kind of person that likes functional programming, you will get into functional programming sooner or later. This is just a bit later.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Notice Clojure here...&lt;/li&gt;
&lt;li&gt;Whatever is not a language. Still, it would be a great name for a language. Maybe not.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-2089304051938765570?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oWV63hc4urXgt9ECyMJumwqABkA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oWV63hc4urXgt9ECyMJumwqABkA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oWV63hc4urXgt9ECyMJumwqABkA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oWV63hc4urXgt9ECyMJumwqABkA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/i490AISRy0s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/2089304051938765570/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=2089304051938765570" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2089304051938765570?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2089304051938765570?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/i490AISRy0s/good-and-not-so-good-reasons-to-learn.html" title="&lt;s&gt;Good and&lt;/s&gt; not so good reasons to learn Java (or any other language)" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/11/good-and-not-so-good-reasons-to-learn.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUMSH0_cSp7ImA9WhRREkw.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-6000495856265172916</id><published>2011-11-25T11:18:00.001+01:00</published><updated>2011-11-25T11:18:09.349+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-25T11:18:09.349+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Mac OS X" /><category scheme="http://www.blogger.com/atom/ns#" term="Computer Science" /><title>Brief morning delusion…</title><content type="html">&lt;p&gt;So basically it's a couple of days I try to use a given piece of software. And for some unfathomable reason the thing does not do a specific thing which I need and it shall do. I'm not going to be more specific, because I do not want to point fingers.&lt;/p&gt;
&lt;p&gt;The point is that it does not give any clues on why it is failing or what is exactly trying to do (thus "how" it is failing). Since the project is open source I decided to take the sources and hack my way to the problem. I have a rather good understanding on the domain that I'm going to solve (it's related to unix processes -- though in OS X environment --). I'm familiar with both.&lt;/p&gt;
&lt;p&gt;It's been a while since I last wrote some Objective-C, but this time I should just look at the sources, perhaps set a couple of breakpoints and find out what is happening. My plan is that after that I could fix the source so that:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;It logs what is doing&lt;/li&gt;

  &lt;li&gt;It logs any errors that occur&lt;/li&gt;

  &lt;li&gt;Perhaps I fix the specific problem in the code&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first bad piece of new is that I spot some obvious software engineering mistakes in the software. Unfortunately it is stuff that needs more than a casual hacking to be fixed (specifically, I'm talking about configuration stuff hardcoded in the sources). Still, it is not probably a big issue. It may even make sense in some contexts… well, not really. But anyway. Some wrong data-structures… but everything is basically fine: the code, a part from that, is well written and rather clear.&lt;/p&gt;
&lt;p&gt;So I localize the piece of code that fails. It does a bloody lot of magic, in my opinion. My guts tell me that some of it is just unnecessary, some better design could lead to much simpler and less magic code. The only problem is that sometimes such kludges are just a consequence of unorthogonal design of the underlying systems (in this case OS X). But that is something I would do later on, after simply adding the code that logs possible errors (I think that is of paramount importance for the semi-technical users of the software, in the sense that they could better understand what is going awry when they customize it).&lt;/p&gt;
&lt;p&gt;Then a thought strikes me: compile the whole thing just before making modifications. The svn repo &lt;i&gt;should&lt;/i&gt; have been left in compilable state… but no. It is not. So I should have to find the last point where it can be compiled. Which I could do… well, another time.&lt;/p&gt;&lt;br /&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-6000495856265172916?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MLooHT2qQQwE4yXN90O_7HVAKnA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MLooHT2qQQwE4yXN90O_7HVAKnA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MLooHT2qQQwE4yXN90O_7HVAKnA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MLooHT2qQQwE4yXN90O_7HVAKnA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/CibVOosv8cY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/6000495856265172916/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=6000495856265172916" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/6000495856265172916?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/6000495856265172916?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/CibVOosv8cY/brief-morning-delusion.html" title="Brief morning delusion…" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/11/brief-morning-delusion.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QBSXc8cSp7ImA9WhRTFkQ.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-7558982119097517900</id><published>2011-11-07T17:40:00.000+01:00</published><updated>2011-11-07T20:49:18.979+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-07T20:49:18.979+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Java 7 for Mac OS X</title><content type="html">Just a preview, for now:
&lt;a href="http://jdk7.java.net/macportpreview/" title="Java Preview"&gt;link&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
Good. Performance improvements should also be seen in Clojure.&lt;br /&gt;
&lt;br /&gt;
Still I am not extremely familiar with all the various improvements. After I found out that closures were not going to make it, I just lost interest in the whole process.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-7558982119097517900?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/IvpQQlx_-K0RHUoQcPFLDWhIgcw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IvpQQlx_-K0RHUoQcPFLDWhIgcw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/IvpQQlx_-K0RHUoQcPFLDWhIgcw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IvpQQlx_-K0RHUoQcPFLDWhIgcw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/QC-uOebSuPM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/7558982119097517900/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=7558982119097517900" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/7558982119097517900?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/7558982119097517900?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/QC-uOebSuPM/java-7-for-mac-os-x.html" title="Java 7 for Mac OS X" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/11/java-7-for-mac-os-x.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MCQX08fyp7ImA9WhRTFEo.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-3975438097538332643</id><published>2011-11-05T08:51:00.000+01:00</published><updated>2011-11-05T08:51:00.377+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-05T08:51:00.377+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Scheme" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Scheme Rant, but a bright future lies ahead!</title><content type="html">&lt;p&gt;
    Is this the best moment for scheme ever? First of all, I have to admit
    that although I quite studied the language in the last years, I'm a
    bit outside the spirit of the community. My impressions basically come
    from some discussions I have with more experienced schemer friends
    and reading stuff on the web.
&lt;/p&gt;
&lt;p&gt;
    I have often wrote about my difficulties with finding a satisfactory
    scheme environment. Essentially problems boil down to two things:
&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;I have very high expectations for programming environment
        (batteries included, etc.)&lt;/li&gt;
    &lt;li&gt;I have very high expectations on Lisps, probably because every
        lisper I met spent a great deal of his non-programming time saying
        how lisp did this and that 30 years ago. So I expect to do it
        now, to do it fast and to do it well.
    &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
    The issue with the first point is that I'm mostly used to programming
    environments which are mostly unique. Python is just Python. I use the
    very same interpreter everywhere, I know what it does, which features
    are supported and which ones are not. Same thing for Clojure or
    Erlang and nowadays mostly true for Haskell. I avoided
    the issue with C/C++ being rigorously adherent to the standards or
    to very minor gcc extensions (and by the way, I'm always using gcc).
&lt;/p&gt;
&lt;p&gt;
    On the other hand in Scheme there are many implementations and there
    is not a clear winner. There are implementations which are "worse"
    than others, but among the good ones it is hard to choose.
&lt;/p&gt;
&lt;p&gt;
    The problem is especially significant because I somewhat got into
    a period of transition between R5RS and R6RS (which are two standards).
    I somewhat lived something like that with C++, but at least back then
    there was clear consensus that pre-standard C++ was unarguably worse
    than post-standard C++.
&lt;/p&gt;
&lt;p&gt;
    Essentially, R6RS came out in the mid 2007 and I started learning
    Scheme not much afterwards. Moreover (here discussions with my friend
    kick in) a large part of the Scheme community did not like the standard,
    feeling that the new language was too large (plus strictly speaking
    it should lack a REPL).
&lt;/p&gt;
&lt;p&gt;
    After reading Dybvig's 4th edition Scheme book I found that mostly
    I like the new stuff. However, for some unfathomable reason I sticked
    with Gambit, which does not implement it. So, while I like the idea
    that Scheme was a little language which you use to build your language,
    I missed lots of R6RS features which just make to much sense for me
    (as an "application/library" programmer, instead than a "language
    programmer"). That, and the fact that if you want to toy with a new
    language, you do not want to re-implement merge-sort (unless you are
    are explicitly choosing that example to learn the language).
&lt;/p&gt;
&lt;p&gt;
    So there were lots of incomprehensions between me and the my scheme
    learning process. But I'm afraid that lots of non schemer may be
    feeling the very same stuff about it (and perhaps jump to clojure,
    which fixes that issues by default).
&lt;/p&gt;
&lt;p&gt;
    Some time later, the other scheme implementation I used became another
    language (and I'm looking forward to read the new No Starch Press book
    about it). So the more "batteries included" tool I knew in scheme,
    ceased to be scheme.
&lt;/p&gt;
&lt;p&gt;
    I think things would have been easier if I just picked up an R6RS
    implementation and stick with it. However, things went differently.
    Not that I do not like Racket, still I find ackward to code in Racket
    when I want to grok Scheme and code written in Racket is so often
    not very portable to other schemes (and that is why Racket is
    Racket). I'm not complaining about Racket: I think they did the right
    thing.
&lt;/p&gt;
&lt;p&gt;
    However, nowadays the Racket book is scheduled. And there is going
    to be a new standard R7RS. And they decided to define a "small" and
    a "big" language. And I really do believe this is wonderful because
    it would make clear exactly what to expect from either language
    &lt;i&gt;also&lt;/i&gt; to newbies. Moreover, perhaps some of the more reasonable
    improvements with less reaching implication which R6RS will be added
    to the small language as well. E.g., how to define libraries and
    generic information about what to expect from the "platform". Or maybe
    "values" related stuff.
&lt;/p&gt;
&lt;p&gt;
    So, in essence, I think in the future it will be a great time to
    learn scheme. Maybe I will have the courage (and the time) to
    re-learn it from scratch and fix all my miscomprehensions which came
    from the way I originally learned the language.
&lt;/p&gt;



&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-3975438097538332643?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hZyU0BGyl7J9weQDkjx7Z_Ds_SA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hZyU0BGyl7J9weQDkjx7Z_Ds_SA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hZyU0BGyl7J9weQDkjx7Z_Ds_SA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hZyU0BGyl7J9weQDkjx7Z_Ds_SA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/chPWXMi28Tc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/3975438097538332643/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=3975438097538332643" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/3975438097538332643?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/3975438097538332643?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/chPWXMi28Tc/scheme-rant-but-bright-future-lies.html" title="Scheme Rant, but a bright future lies ahead!" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>7</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/11/scheme-rant-but-bright-future-lies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UCQXkzcSp7ImA9WhdaGUs.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-6973057598373446277</id><published>2011-10-30T10:01:00.000+01:00</published><updated>2011-10-30T10:01:00.789+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-30T10:01:00.789+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Closures" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Does Perl suck? (and something about this Quorum Language)</title><content type="html">&lt;p&gt;The short story is that a group of researchers created yet another language. And I see nothing wrong with that. Most people sooner or later implement their own language (or wish to); researchers just do it more often. These languages usually have specific goals and some of them become widespread programming languages. Other remain academic toys. This particular language was created to be intuitive and easy to use. And the researcher meant to make it intuitive and easy with usability studies. I will comment on the idea later.&lt;/p&gt;
&lt;p&gt;Fact is, that they put out a paper which compared their Quorum language with Perl and another language they designed to be bad. And they claim that the accuracy rates of their users were similar for Perl and Randomo (the bad language) and worse than Quorum.&lt;/p&gt;
&lt;h3&gt;Does Perl suck?&lt;/h3&gt;
&lt;p&gt;The question is that the story became very popular because of this: because they claim to have scientifically proved that Perl sucks. And such pieces of news have huge diffusion. The essence here is that I do not think that the results are so very relevant: they used only the easy part of Perl. As a consequence, I think that many other languages would have scored similarly. And think about it... if the easy part of Perl is hard for novices... what about the hard one?&lt;/p&gt;
&lt;p&gt;As far as I can tell, the thing is mostly a syntactical issue. I haven't found papers on the full semantics of Quorum. From the examples in the paper, it looks like the illegitimate child of Ada and Ruby. I'm sure that I'm missing something, but it is mostly a matter of substituitions like:&lt;/p&gt;
&lt;p&gt;for -&amp;gt; repeat [ which other major language had a repeat statement? ]&lt;br /&gt;
float -&amp;gt; number [*very* clear, especially before explaining the noobs how much different are floating point numbers from real numbers]&lt;/p&gt;
&lt;p&gt;I don't consider it particularly readable. On the contrary to me something like:&lt;/p&gt;
&lt;pre&gt;
  if d &amp;gt; e then
    return d
  end
  else then
  return e
  end
  
&lt;/pre&gt;
&lt;p&gt;looks like a walking syntax error. I think I would take lot of time to convince me that it is proper english. I'm not a native speaker, but to me:&lt;/p&gt;
&lt;pre&gt;
  if something is true, then do this, else do that
  
&lt;/pre&gt;
&lt;p&gt;sounds quite more convincing than:&lt;/p&gt;
&lt;pre&gt;
  if something is true, then do this, else &lt;strong&gt;then&lt;/strong&gt; do that
  
&lt;/pre&gt;
&lt;p&gt;All considered, it seems to me that they are optimizing the easy part of learning. The syntax is an issue in the first like 2-3 months of programming. After that the problems become semantic and theoretic. Computer Science is hard. It is not the syntax of the programming language you first learn to program with that makes it easier.&lt;/p&gt;
&lt;p&gt;To me, it looks like they would use sponge rubber balls to make rugby less violent, completely ignoring the full contact issue.&lt;/p&gt;
&lt;p&gt;Besides, I believe that most people who have serious issues with the syntax of todays' programming languages would also have problems with the semantics and with calculus and lambda calculus and whatever hard stuff is taught in the courses. Moreover, hiding the complexity is not always a good thing.&lt;/p&gt;
&lt;p&gt;In a computer we can't represent a real number. We know that. At a given point in our curriculum, we also know exactly why. However, usually the odd behavior of floating point number strikes. Odd in the sense that people usually expect them to behave like real numbers. They do not.&lt;/p&gt;
&lt;p&gt;A popular surprise is in Python when they use the console to make operations. In older Python versions, a number was printed just how it was in memory.&lt;/p&gt;
&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; 1.1
  1.1000000000000001
&lt;/pre&gt;
&lt;p&gt;and guess what... this is extremely surprising for noobies (and in Python 2.7 the algorithm changed so that the printed number tries to be more 'intuitive' and in the case just prints 1.1). The fact is that 1.1 cannot be represented in memory (as a floating point number) and an approximation is used. This is quite hard stuff.&lt;/p&gt;
&lt;p&gt;Pretending that floating point numbers are not floating point numbers is going to lead to disaster as soon as things get rough. So, I while I think there are far easier languages to learn to program with than Perl (Python, Ruby, Scheme) I don't think that Quorum is such a huge advantage past the "very very noob - why this does not compile if(foo); {...} else; {...}" part. And that is not the part to optimize.&lt;/p&gt;
&lt;h3&gt;And what about quorum?&lt;/h3&gt;
&lt;p&gt;Unfortunately enough, I do not know very much about usability. So I really cannot comment their methods. However, I think that I can say a couple of things from the point of view of language design. The first thing is that most languages that I think are worth learning and using have some very complex stuff and that stuff is what makes the language powerful. With powerful here I mean that it gets the job done quicker, with less line of code and, why not, shapes the programmer's mind in good ways, giving him insight.&lt;/p&gt;
&lt;p&gt;Remove this advanced stuff and you have only dumb ugly languages. Such languages would not make you or your programs better. Remove first order functions and macros from Lisp or Clojure and you are just coding Pascal.&lt;/p&gt;
&lt;p&gt;And I'm not exactly sure that "usability" can be applied to programming language design. Some argue that since most "experts" disagree on which features should be added to a programming language (and agree that having them all is a bad thing), such studies are needed to determine how to build the one and "true" language. And I have to say that I disagree.&lt;/p&gt;
&lt;p&gt;Democracy plainly does not work in technical issues. Noob programmers are plainly not entitled to discuss about advanced language features that they have not yet the experience to understand and which solve problems they have not yet encountered. So called "professional" (i would say business) programmers do not care about the programming language, be it Java or Cobol. They probably would not have advanced features either, because they may thing such features would slow their juniors down. They mostly care about powerful libraries: the discussion is not at the language level, but at an architectural level. They don't do algorithms, they have to make complex under-documented systems interact and work correctly.&lt;/p&gt;
&lt;p&gt;So we have just people who "love" programming languages. People who have a strong opinion on how a programming language should be. And guess what? We disagree. Some of us prefer Ruby to Python. Someone else thinks they are the same and that Haskell is the best.&lt;/p&gt;
&lt;p&gt;The simple decision of creating an object oriented imperative language is a very strong assumption. I could not rationally say that object oriented is easier than functional programming. Not even if I thought it. And you can't ask noobs if they prefer functional languages (which they do not know what they are), nor you can ask business programmers (which probably dislike them). And if you ask to object zealots, they will answer that FP is just harder.... however, if you ask to functional programmers, they will say that FP languages are easier.&lt;/p&gt;
&lt;p&gt;There are lots of design issues which are too bloody architectural to be decided with statistics.&lt;/p&gt;
&lt;p&gt;Regarding the Quorum language itself... I strolled through the library files. And what? I changed my initial opinion... its more something between VisualBasic and Java. It has generics. Which are one of the things which are bloody harder to understand in Java (especially if you throw in extends, ? and company). And if you don't, you have a type-system that cannot express some perfectly useful stuff.&lt;/p&gt;
&lt;p&gt;It has packages and includes (they are just called 'use'). The nice thing is that Java without an IDE is a PITA partly because of the redundancy of the interaction between classpath/packages and directory structure. And as far as I can tell that stuff is still there. Not sure that being strongly typed makes things easier for the noobs too.&lt;/p&gt;
&lt;p&gt;Well, good luck then... my first impression is that it is basically Java without some nice stuff and a visual basic-ish syntax. On the other hand the compiler code looks very well written (still... writing compilers in Haskell/scheme is just so much easier than doing that in Java)... but really: in 2011, with everybody re-discovering the merits of functional programming (Clojure/Land of Lisp/Learn yourself Haskell/Racket/.../C# being more functional than ever/Erlang)... do we need yet another object oriented language?&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-6973057598373446277?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/v8xaa_s-8NpkvdeCPZIulNlC_H8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/v8xaa_s-8NpkvdeCPZIulNlC_H8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/v8xaa_s-8NpkvdeCPZIulNlC_H8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/v8xaa_s-8NpkvdeCPZIulNlC_H8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/hdeAIxagCdk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/6973057598373446277/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=6973057598373446277" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/6973057598373446277?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/6973057598373446277?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/hdeAIxagCdk/does-perl-suck-and-something-about-this.html" title="Does Perl suck? (and something about this Quorum Language)" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/10/does-perl-suck-and-something-about-this.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQHSXY-cSp7ImA9WhRSEEQ.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-855028766252389017</id><published>2011-10-29T10:00:00.000+02:00</published><updated>2011-11-12T10:32:18.859+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-12T10:32:18.859+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><title>Working Java 7 on Ubuntu Oneiric Ocelot 11.10 (update-alternatives)</title><content type="html">I still have not figured out why the default openjdk installation on Ubuntu 11.10 seems broken. With broken I mean that there are no entries in the &lt;i&gt;alternatives&lt;/i&gt;&amp;nbsp;database and no command in the path (which follows from not being the default alternative).&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
As a consequence, I did the same old mumbo jumbo with update-alternatives. As the openjdk-7 is in&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/usr/lib/jvm/java-7-openjdk-i386/&lt;/span&gt;, I just run the following commands:&lt;/div&gt;
&lt;br /&gt;
&lt;pre&gt;% sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-7-openjdk-i386/bin/java 4 
% sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-7-openjdk-i386/bin/javac 4     t
% sudo update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/java-7-openjdk-i386/bin/jar 4 &lt;div&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;br /&gt;
I guess I may want to do &amp;nbsp;the trick for more&amp;nbsp;executable stuff. Moreover, I have no idea whether the browser plugin works or not. It has been ages since I actually used it and right at the moment I do not care. Hope this will be helpful.&lt;br /&gt;
&lt;br /&gt;
After that, just call the appropriate &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;update-alternatives --config ja(vac|va|r)&lt;/span&gt; stuff!&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I almost forgot... I just installed the plain openjdk-7-jdk/jdr stuff from the official ubuntu repositories.&lt;/div&gt;
&lt;br /&gt;
Besides... I have seen a package sun-java-{yadda-yadda}-bin which may have been the provider of the links in the first place (when I was using sun's JDK which was correctly packaged). Right at the moment I cannot see a similar package for OpenJDK. My Ubuntu went postal recently and consequently I cannot verify. :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-855028766252389017?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/di7sasqm0tC9Z099c-XtbGENXJE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/di7sasqm0tC9Z099c-XtbGENXJE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/di7sasqm0tC9Z099c-XtbGENXJE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/di7sasqm0tC9Z099c-XtbGENXJE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/d7bh12GsRgg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/855028766252389017/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=855028766252389017" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/855028766252389017?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/855028766252389017?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/d7bh12GsRgg/i-still-have-not-figured-out-why.html" title="Working Java 7 on Ubuntu Oneiric Ocelot 11.10 (update-alternatives)" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/10/i-still-have-not-figured-out-why.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08FQXo4fyp7ImA9WhdaGE8.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-8305606529667606021</id><published>2011-10-28T20:16:00.001+02:00</published><updated>2011-10-28T20:16:50.437+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-28T20:16:50.437+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="leiningen" /><title>Ubuntu 11.10</title><content type="html">&lt;p&gt;&lt;span style="font-family: arial, sans-serif; font-size: 13px; background-color: #FFFFFF; display: inline !important; float: none;"&gt;Yesterday I decided to update my netbook to the last incarnation of the Ubuntu distribution. In the past days I read something about bad bugs in the kernel regarding power saving and similar stuff; however, nothing happened here (yet).&lt;/span&gt;&lt;/p&gt;&lt;span style="color: #000000; font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); display: inline !important; float: none;"&gt;I was quite amazed to find a Linux 3.0 kernel. It is the single event that made me think how little I keep myself informed about Linux specific stuff. I still find it hard to study all the languages, technologies and theory which has to do with my work (which is also responsible for me posting very little, lately) and my generic interests (functional programming, for example). I simply dropped most stuff regarding system administration and even platforms. In fact, I haven't upgraded to Lion either.&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;span style="color: #000000; font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); display: inline !important; float: none;"&gt;So I don't know a thing about this Linux 3.0 kernel. On the other hand I remember I followed very closely the new features of the 2.2, 2.4 and 2.6 kernels. In fact, I have also some memories of stuff before that (I used mkLinux, though). I think this means I'm just growing older.&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;span style="color: #000000; font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); display: inline !important; float: none;"&gt;Anyway... I still don't like Unity. However, I'm one of those guys who basically open up a shell a fire some stuff from there (editor, interpreters and compilers). Or occasionally I open IntelliJ/PyCharm. So really, I'm not entitled to talk about that. I simply noticed that the colours moved from that tiring orange to shades of green which are just easier on my eyes. Nothing important. I just find it nice not to have the gnome menus, since I have a very very tiny screen. In this sense, my iPad screen feels just larger (even though it is not). I think it simply depends on the way applications are designed.&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;span style="color: #000000; font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); display: inline !important; float: none;"&gt;I just found out that for some reason I do not have Java properly installed, even if before the update I did have it. It felt akward to run clojure and get a "command not found: java" error; especially considering that up to 5 minutes before that I was debugging a Java project inside IntelliJ. Though I think it has something to do with my current installation of OpenJDK 7.&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;br style="color: rgb(0, 0, 0); font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" /&gt;
&lt;span style="color: #000000; font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); display: inline !important; float: none;"&gt;About the "good" things... Now leiningen is packaged (and decently recen, as far as I can tell); moreover, also clojure 1.2 (and contrib) are installable packages. Perhapsit could be enough... Waiting for Clojure 1.3, by the way.&lt;/span&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-8305606529667606021?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XmAoN-1tW5hQlBo4JEBOAJ2M1E0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XmAoN-1tW5hQlBo4JEBOAJ2M1E0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XmAoN-1tW5hQlBo4JEBOAJ2M1E0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XmAoN-1tW5hQlBo4JEBOAJ2M1E0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/uXywTHkfzVk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/8305606529667606021/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=8305606529667606021" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8305606529667606021?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/8305606529667606021?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/uXywTHkfzVk/ubuntu-1110.html" title="Ubuntu 11.10" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/10/ubuntu-1110.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UERH07cSp7ImA9WhdUGEU.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-758507669867606528</id><published>2011-10-06T10:09:00.000+02:00</published><updated>2011-10-06T10:20:05.309+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-06T10:20:05.309+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="Node.J" /><category scheme="http://www.blogger.com/atom/ns#" term="Scheme" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Node.js" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><title>Dahl (Node.Js), Sussman (Scheme) and the Scientific Method</title><content type="html">&lt;p&gt;Everything started with Dahl's post "&lt;a href="https://plus.google.com/115094562986465477143/posts/Di6RwCNKCrf"&gt;I hate almost all software&lt;/a&gt;" (probably not Node.js). I basically agree with the second sentence and the last one (that is to say "&lt;span style="font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"&gt;The only thing that matters in software is the experience of the user" and "&lt;/span&gt;&lt;span style="font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"&gt;It's unnecessary and complicated at almost every layer"). Other stuff is just a list of obvious thing: when systems evolve and nobody cuts broken parts out, then systems become complicated.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="arial, sans-serif"&gt;&lt;span style="font-size: 13px; line-height: 18px;"&gt;In fact, this is almost a built-in feature: for years our answer to complexity was "add another layer". Which led to the "abstraction leaks" Martelli talked about in some conferences and the obvious fact that the layer we just hid did not became any simpler. We just put the dirt under the carpet. Needles to say, the new layer becomes as complex as the old one in a few years/months/days.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;div class="Us c-ng Gk" style="overflow-x: hidden; overflow-y: hidden; padding-bottom: 12px; padding-top: 3px; text-overflow: ellipsis;"&gt;
  &lt;font face="arial, sans-serif"&gt;&lt;span style="font-size: 13px; line-height: 18px;"&gt;So what? I would also point out another apparently unrelated event. In 2009, Sussman explained why at MIT Python substituted Scheme in basic programming courses. And we all know how wonderful is SICP; still the authors themselves started thinkng about changing the course since 1995. Essentially the reason is that "engineering in 1980 was not what it was in the mid-90s or in 2000. In 1980, good programmers spent a lot of time thinking, and then produced spare code that they thought should work. Code ran close to the metal, even Scheme — it was understandable all the way down. [...] 6.001 had been conceived to teach engineers how to take small parts that they understood entirely and use simple techniques to compose them into larger things that do what you want.&lt;/span&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div class="Us c-ng Gk" style="overflow-x: hidden; overflow-y: hidden; padding-bottom: 12px; padding-top: 3px; text-overflow: ellipsis;"&gt;
  &lt;font face="arial, sans-serif"&gt;&lt;span style="font-size: 13px; line-height: 18px;"&gt;But programming now isn’t so much like that. Nowadays you muck around with incomprehensible or nonexistent man pages for software you don’t know who wrote. You have to do basic science on your libraries to see how they work, trying out different inputs and seeing how the code reacts. This is a fundamentally different job, and it needed a different course."&lt;/span&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div class="Us c-ng Gk" style="overflow-x: hidden; overflow-y: hidden; padding-bottom: 12px; padding-top: 3px; text-overflow: ellipsis;"&gt;
  &lt;font face="arial, sans-serif"&gt;&lt;span style="font-size: 13px; line-height: 18px;"&gt;Isn't that they are basically saying the very same thing about today software world? I think so. Software is so complicated that we ought to use experimental techniques to dig into it.&lt;/span&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div class="Us c-ng Gk" style="overflow-x: hidden; overflow-y: hidden; padding-bottom: 12px; padding-top: 3px; text-overflow: ellipsis;"&gt;
  &lt;font face="arial, sans-serif"&gt;&lt;span style="font-size: 13px; line-height: 18px;"&gt;The part that Dahl lives out is that Node.js is not any simpler (I will elaborate on that in another moment). In fact Javascript itself suffers all the problems described of being unnecessarily complex (to me lack of orthogonality and regularity is a form of complexity of the worse kind -- and it is also the very critique I move to languages I love, like Clojure). Adding a nice asynchronous layer on the top of a messy language is only going to create an asynchronous messy language. Nothing more, nothing less. But hey, V8 is fast.&lt;/span&gt;&lt;/font&gt;
&lt;/div&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-758507669867606528?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zKMaGZ2t04lrZqFaBmvNebLXmXM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zKMaGZ2t04lrZqFaBmvNebLXmXM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zKMaGZ2t04lrZqFaBmvNebLXmXM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zKMaGZ2t04lrZqFaBmvNebLXmXM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/0ngRQ2g2V-c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/758507669867606528/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=758507669867606528" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/758507669867606528?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/758507669867606528?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/0ngRQ2g2V-c/dahl-nodejs-sussman-scheme-and.html" title="Dahl (Node.Js), Sussman (Scheme) and the Scientific Method" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/10/dahl-nodejs-sussman-scheme-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYHRns-eyp7ImA9WhdVFUg.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-4656438885365245602</id><published>2011-09-20T22:22:00.001+02:00</published><updated>2011-09-20T22:22:17.553+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-20T22:22:17.553+02:00</app:edited><title>Eclipse...</title><content type="html">Is it possible that to upgrade a major version of Eclipse there is no other way than just reinstall every bloody plugin I'm using?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-4656438885365245602?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_PxHAoarJt8PqawEpG0eL-XHKSk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_PxHAoarJt8PqawEpG0eL-XHKSk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_PxHAoarJt8PqawEpG0eL-XHKSk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_PxHAoarJt8PqawEpG0eL-XHKSk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/duv0M9OXtJM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/4656438885365245602/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=4656438885365245602" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/4656438885365245602?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/4656438885365245602?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/duv0M9OXtJM/eclipse.html" title="Eclipse..." /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/09/eclipse.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUGRH85eSp7ImA9WhdWEkQ.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-5313820649860005924</id><published>2011-09-06T10:20:00.000+02:00</published><updated>2011-09-06T10:20:25.121+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-06T10:20:25.121+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Scheme" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="call/cc" /><title>Clojure: Quicksort in Continuation Passing Style and Trampolines</title><content type="html">&lt;h3&gt;
Introduction&lt;/h3&gt;
In this post we are going to write a completely recursive stack-wary version of the classical quicksort algorithm in continuation passing style, making use of trampolines.&lt;br /&gt;
I already discussed quicksort in continuation passing style in &lt;a href="http://www.enrico-franchi.org/2010/08/quicksort-in-continuation-passing-style.html"&gt;this post&lt;/a&gt;. The idea is to refer to the post as much as possible and introduce here more information. &lt;br /&gt;
From Wikipedia:&lt;br /&gt;
&lt;blockquote&gt;
Instead of "returning" values as in the more familiar direct style, a function written in continuation-passing style takes an explicit "continuation" argument, i.e. a function which is meant to receive the result of the computation performed within the original function. Similarly, when a subroutine is invoked within a CPS function, the calling function is required to supply a procedure to be invoked with the subroutine's "return" value. Expressing code in this form makes a number of things explicit which are implicit in direct style. These include: procedure returns, which become apparent as calls to a continuation; intermediate values, which are all given names; order of argument evaluation, which is made explicit; and tail calls, which simply is calling a procedure with the same continuation that was passed to the caller, unmodified.
&lt;/blockquote&gt;
Essentially there are two issues in CPS with Clojure. The first one is  recursion on the stack. CPS is tail recursive by default; however, most of the times it is about mutually recursive calls. Which essentially means trampolines.
&lt;br /&gt;
The second issue relates to the continuation themselves. First, they may occupy heap space (as the continuations stay in memory until evaluated), second, the continuations themselves need to be treated with trampolines, otherwise, when evaluated consume stack space.
&lt;br /&gt;
However, with massive usage of trampolines, both issues can be solved.
&lt;br /&gt;
&lt;h3&gt;
Append&lt;/h3&gt;
The first function we need to write is append (i.e., concat in Clojure Jargon). We need to write a new version because we need to have it deal with the continuation. And as we will see, append is a false friend.&lt;br /&gt;
&lt;pre&gt;(defn append-notramp [lst1 lst2 k]
  (cond
   (empty? lst1) (k lst2)
   :else (recur (rest lst1) lst2
                 (fn [rst]
                   (k (cons (first lst1) rst))))))
&lt;/pre&gt;
At first sight, his implementation looks correct. We can try it with simple inputs and convince ourselves that the semantics is right. Essentially if there are elements in the first list, the new continuation is a function taking a list rst and calling the continuation we received with a list where we consed the first element of lst1 on rst.
&lt;br /&gt;
However, running with increasingly large values for lst1 results in a stack overflow.&lt;br /&gt;
&lt;pre&gt;user&amp;gt; (cps/append-notramp (range 100000) (range 4) identity)
; Evaluation aborted.
&lt;/pre&gt;
In this case, recur is a false friend. We are lead to think that since append-notramp is tail-recursive, we do not have to worry about stack overflow. The issue here are the chain of continuations, however. And they cannot use recur, because even though they *are* tail recursive, they are mutually recursive. Luckily enough, Clojure provides trampolines and in this case, they are also relatively easy to use.
&lt;br /&gt;
&lt;pre&gt;(defn append [lst1 lst2 k]
  (cond
   (empty? lst1) #(k lst2)
   :else (recur (rest lst1) lst2
                 (fn [rst]
                   #(k (cons (first lst1) rst))))))
&lt;/pre&gt;
Here append plainly returns a chain of functions which returns functions and they can be resolved calling trampoline on them. I pass empty as the continuation because I do not want a list of some thousand of elements printed on standard output. The other function just checks the 0s are at the right places.
&lt;br /&gt;
&lt;pre&gt;user&amp;gt; (cps/append (range 100000) (range 4) empty)
#[cps$append$fn__5392 cps$append$fn__5392@30ea3e3c]
user&amp;gt; (trampoline (cps/append (range 100000) (range 4) empty))
()
user&amp;gt; (trampoline (cps/append (range 100000) (range 4)
                              #(and (= (nth % 0) 0)
                                    (= (nth % 100001)))))
true
&lt;/pre&gt;
&lt;h3&gt;
Partition&lt;/h3&gt;
Partition suffers from a similar problem than append, in the sense that a naive version blows the stack.
&lt;br /&gt;
&lt;pre&gt;(defn- partition-notramp [coll p? k]
  (loop [coll coll k k]
    (cond
     (empty? coll) (k () ())
     (p? (first coll)) (recur (rest coll)
                              (fn [p-true p-false]
                                (k (cons (first coll) p-true)
                                   p-false)))
     :else (recur (rest coll)
                  (fn [p-true p-false]
                    (k p-true
                       (cons (first coll)
                             p-false)))))))
&lt;/pre&gt;
The solution is also similar. When a continuation k is called, instead return a function which calls k, like #(k ...).&lt;br /&gt;
&lt;pre&gt;(defn- partition [coll p? k]
  (loop [coll coll k k]
    (cond
     (empty? coll) #(k () ())
     (p? (first coll)) (recur (rest coll)
                              (fn [p-true p-false]
                                #(k (cons (first coll) p-true)
                                   p-false)))
     :else (recur (rest coll)
                  (fn [p-true p-false]
                    (k p-true
                       (cons (first coll)
                             p-false)))))))
&lt;/pre&gt;
&lt;h3&gt;
Quicksort&lt;/h3&gt;
Now things become complicated. Quicksort is a doubly recursive function and is called inside the continuations. We basically have each continuation return a function which runs what would have been the continuation weren't we using trampolines. This works like a breeze: we just have to call trampoline before returning.
&lt;br /&gt;
&lt;pre&gt;(defn quicksort
  ([coll less? k]
     (letfn [(qs [coll k]
                 (if (empty? coll) #(k ())
                     (let [[pivot &amp;amp; coll1] coll]
                       (partition coll1
                                  (fn [x] (less? x pivot))
                                  (fn [less-than greater-than]
                                    (fn []
                                      (qs greater-than
                                          (fn [sorted-gt]
                                            (fn []
                                              (qs less-than
                                                  (fn [sorted-lt]
                                                    (append sorted-lt (cons pivot sorted-gt) k))))))))))))]
       (trampoline (qs coll k))))
     ([coll less?]
        (quicksort coll less? identity)))
&lt;/pre&gt;
&lt;h3&gt;
A word on performace&lt;/h3&gt;
Of course, performance is rather terrible. First, quicksort in functional settings rather sucks. I find it so much imperative oriented that it is even hard to think about it in this context (notice here we are using rather complex stuff to make it functionally looking).
    &lt;br /&gt;
Then there are a number of issues:
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Typical optimizations like switching to other algorithms with lower multiplicative constants is not easy to do. Every self-respecting implementation of quicksort when the list is sufficiently small switches to something like insertion sort because it is just faster (say... sublists of k elements).
    &lt;/li&gt;
&lt;li&gt;Other optimizations like recursing first in the smaller half of the array are also hard to do (because we are using lists... we should essentially use a custom variant of partition which takes care of such nuisances).
    &lt;/li&gt;
&lt;li&gt;Quicksort performs poorly if the pivot element is chosen as the first element in the list. However, in functional settings, where the core data structure is likely to (or just may be) a list, taking an element in the middle has an inacceptable algorithmic complexity&lt;/li&gt;
&lt;li&gt;Moreover, partition is likely to use far more memory than what would use in imperative settings&lt;/li&gt;
&lt;/ol&gt;
Consequently, Clojure sort is plainly faster, considering that it should call Java sort (which now is the blazingly fast tim-sort, a difficult if not impossible to beat algorithm). Comparisons in this sense are embarassing. That is why I did not even try to code smarter in order to make this quicksort faster. And no, I'm definitely not going to turn tim-sort in CPS+trampolines by hand.&lt;br /&gt;
Technorati Tags: 
&lt;a href="http://technorati.com/tag/Programmin" rel="tag"&gt;Programming&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Continuation+Passing+Style" rel="tag"&gt;Continuation Passing Style&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Functional+Programming" rel="tag"&gt;Functional Programming&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Clojure" rel="tag"&gt;Clojure&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Scheme" rel="tag"&gt;Scheme&lt;/a&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-5313820649860005924?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/c3TGlWciB-eV5SnENLVL_xEYt50/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c3TGlWciB-eV5SnENLVL_xEYt50/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/c3TGlWciB-eV5SnENLVL_xEYt50/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/c3TGlWciB-eV5SnENLVL_xEYt50/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/-Jc2V84cpAo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/5313820649860005924/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=5313820649860005924" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/5313820649860005924?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/5313820649860005924?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/-Jc2V84cpAo/clojure-quicksort-in-continuation.html" title="Clojure: Quicksort in Continuation Passing Style and Trampolines" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/09/clojure-quicksort-in-continuation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcDSH44eyp7ImA9WhdWEEg.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-2479718162139045570</id><published>2011-09-03T15:54:00.001+02:00</published><updated>2011-09-03T15:54:39.033+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-03T15:54:39.033+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="vim" /><category scheme="http://www.blogger.com/atom/ns#" term="Common Lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="leiningen" /><category scheme="http://www.blogger.com/atom/ns#" term="Erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Haskell" /><category scheme="http://www.blogger.com/atom/ns#" term="Emacs" /><title>Too many cool languages (Python, Clojure, ...)</title><content type="html">&lt;p&gt;There is plenty of languages I like. I'm naming just a bunch of them here... so a non exclusive list may be:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Python&lt;/li&gt;

  &lt;li&gt;Common Lisp&lt;/li&gt;

  &lt;li&gt;Scheme&lt;/li&gt;

  &lt;li&gt;Clojure&lt;/li&gt;

  &lt;li&gt;Erlang&lt;/li&gt;

  &lt;li&gt;Haskell&lt;/li&gt;

  &lt;li&gt;Prolog&lt;/li&gt;

  &lt;li&gt;Ruby&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The list is quite incomplete... for example I left out languages from the ML family. I do not have anything against them, I just think Haskell nowadays is way cooler (cooler != better) and also the Haskell platform is a definitive advantage. I did not mention languages such as Io, because although I'd really like to do something with it, it just does do not feel enough motivation to try and do it in Io instead than in one of the languages above.&lt;/p&gt;
&lt;p&gt;Same thing for Javascript. It's not that I do not like it... it is just that if I can, I would rather use one of the languages I mentioned (which at least in case of client side JS most of the times is a no go). I also left out things like CoffeeScript and a whole lot of languages that did not even jump to my mind right now.&lt;/p&gt;
&lt;p&gt;The list is quite representative of my tastes in programming languages. All the languages are very high level languages (I enjoy plain old C, but I tend to use it to extend the above languages and/or for problems which really need C points of strength). Most of them are declarative languages, almost every one of them has a strong functional flavor (basically just Prolog hasn't, the others are either functional languages or received a strong influence from functional programming).&lt;/p&gt;
&lt;p&gt;Some of the languages are better for certain tasks, because they are built for them or have widely tested libraries/frameworks. And this somewhat makes it a difficult choice which one to chose. For example, every time a network service has to be written, I consider Python (Twisted/Stackless), Erlang and recently Clojure. If the system has to be highly concurrent, probably Erlang has an edge, but also Haskell (with STM and lightweight threads) and Scheme (Gambit/Termite) are strong contenders.&lt;/p&gt;
&lt;p&gt;This is essentially about personal projects. In fact, for "serious" stuff, I am still using Python or Java (and C/C++ if more muscle is needed). This is basically because I have far more experience with those technologies. Clojure is probably a viable choice as well, as I can easily interact with Java and I have been using that quite intensively in the past two years (I also used it to extend one of the "serious" projects, though I had to remove it because I had other experimental components and it was tiresome to find out whether bugs were due to the other components or my relative inexperience with clojure). Besides, I have still to find winning debugging strategies for clojure: probably I'm missing something obvious here. I'm also trying to increase my expertise with Erlang.&lt;/p&gt;
&lt;p&gt;These are some random thought about developing in the environments.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Editing Tools&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The first issue, is to find the right tools. It is not exactly easy to discover the right tools to develop in non mainstream languages. For example, with Java any major IDE is a good enough tool. For Python, both PyCharm and WingIDE are excellent and easy to use tools. Moreover, vim is an excellent tool with only minor tweaking. Oddly enough, I'm still struggling to find a good setup for Emacs.&lt;/p&gt;
&lt;p&gt;On the contrary, Emacs is quite easily one of the best environments for Scheme/Common Lisp/Clojure (thanks to slime), Haskell, Erlang and Prolog (thanks to the improved modes). Still, after years of switching back and forth from Emacs to vim and vice versa, I think I'm more comfortable with vim. Unfortunately, it is not always the case that customizing vim for these languages is as easy as it is with Emacs. For example, I found an easy to use Erlang plugin, but I have still to try using advanced plugins for Haskell and Clojure (I know the plugins, still I did not finish the setup). For Clojure it's just easier to fire LaClojure or Emacs+Slime. For Haskell, I'm not serious enough to know my own needs. I wrote software for my bachelor's in Prolog with vim, and I have to say that Emacs is quite superior (especially considering Sicstus custom mode).&lt;/p&gt;
&lt;p&gt;Back in the day I used TextMate for Ruby. Right now I guess I'd probably go with RubyMine or vim.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Platform&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Now this is a serious point. Many of my "difficulties" with Scheme lie here: chose one interpreter/compiler with libraries to do most things I want to do and some tool to ease the installation of other libraries (I should probably just stick with Racket). For example with Python it is easy: pick the default CPython interpreter, use pip/easy_install for additional libraties.&lt;/p&gt;
&lt;p&gt;Common Lisp is also going well (SBCL + Quicklisp here). I was pleasantly surprised by Haskell: the Haskell platform is wonderful. Some years ago it was not completely clear which interpreter to use and external tools (like Haskell) were not completely immediate. Now with the Haskell platform you just have everything under control.&lt;/p&gt;
&lt;p&gt;About clojure, I feel rather satisfied. For project oriented stuff there is &lt;a href="https://github.com/technomancy/leiningen"&gt;leiningen&lt;/a&gt;, which works fine. My main objection is that most of the time I'm not *starting* with project oriented stuff... which is something which so much remembers me of the Java world, where first you start a project (as opposed to unix, where you just start with a file). Luckily enough in the clojure community there are also guys like me, and so there is &lt;a href="https://github.com/liebke/cljr"&gt;cljr&lt;/a&gt; which just fills the area of "before" something becomes a project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/liebke/cljr"&gt;Cljr&lt;/a&gt; is very nice with emacs/swank/slime. Unfortunately I've not yet found a way to make it interact with vim.&lt;/p&gt;
&lt;p&gt;Erlang already comes bundled with an interesting platform and rebar does lots of nice stuff too. Erlang/OTP tends to be a bit too project oriented but it quite makes sense. Basically all of the times you are setting up systems with many processes and all and it just makes sense to do it that way.&lt;/p&gt;
&lt;p&gt;Prolog is essentially a complete mess. I advise just using SWI-Prolog and forget the rest even exists, unless you need some of the advanced stuff Sicstus offers. In this case you pay and enjoy.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-2479718162139045570?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-21KbQ0pRtfBRss-oPevgedb4nI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-21KbQ0pRtfBRss-oPevgedb4nI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-21KbQ0pRtfBRss-oPevgedb4nI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-21KbQ0pRtfBRss-oPevgedb4nI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/gt-fgHj_yM0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/2479718162139045570/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=2479718162139045570" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2479718162139045570?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/2479718162139045570?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/gt-fgHj_yM0/too-many-cool-languages-python-clojure.html" title="Too many cool languages (Python, Clojure, ...)" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/09/too-many-cool-languages-python-clojure.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEHRnc9eip7ImA9WhdWEk4.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-7901138101896318285</id><published>2011-08-30T20:06:00.000+02:00</published><updated>2011-09-05T17:30:37.962+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-05T17:30:37.962+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Anamorphism" /><category scheme="http://www.blogger.com/atom/ns#" term="Scheme" /><category scheme="http://www.blogger.com/atom/ns#" term="Unfold" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Haskell" /><title>Clojure: Unfold and Anamorphisms</title><content type="html">&lt;p&gt;I found rather unusual the apparent lack of an unfold function in Clojure. Perhaps I was not able to find it in the documentation (which I hope is the case), in this case, happy to have done a useful, although slightly dull, exercise. However, if this is not the case, here it is unfold in Clojure.&lt;/p&gt;
&lt;p&gt;Unfold is a very powerful function which abstracts the idea of generators. I tried to make it lazy (please, feel free to break it) as we expect from clojure functions. Some examples are provided:&lt;/p&gt;
&lt;p&gt;Here, we simply generate a list of elements from 1 to 11 (included):&lt;/p&gt;
&lt;pre&gt;
(unfold #(= 0 %) identity dec 10)
&lt;/pre&gt;
&lt;p&gt;The following example is more interesting: here I show that unfold is at least as powerful as iterate. It is possible to regard iterate as a simpler (and easier to use) variant of unfold.&lt;/p&gt;
&lt;pre&gt;
(unfold
      (fn [x] false)
      identity
      inc
      0)
&lt;/pre&gt;

&lt;p&gt;The code is equivalent to &lt;span style="font-family: monospace"&gt;(iterate inc 0)&lt;/span&gt;. Now the idea is that:&lt;/p&gt;
&lt;p&gt;
&lt;ol&gt;
  &lt;li&gt;The first argument is a predicate that receives the seed (last argument). If it is true, the function returns the empty list; otherwise returns the cons where the first cell if the second argument applied to the seed and the second cell is a recursive call to unfold. All the arguments but the last one are the same. The last argument becomes g applied to seed.&lt;/li&gt;

  &lt;li&gt;The second argument is a unary function which is applied to each individual "value" which is generated. In this case we just use identity, because we want just the plain arguments. We could have used #(* %1 %1) to have the squares of the values or whatever makes sense.&lt;/li&gt;

  &lt;li&gt;The third argument is the function that generates the next seed given the current one&lt;/li&gt;

  &lt;li&gt;The last argument is just the seed&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;
&lt;p&gt;Unfold is extremely general. For example the classic function "tails" that returns all the non-empty sublists of a list ((1 2 3) -&amp;gt; ((1 2 3) (2 3) (3))) could be implemented as:&lt;/p&gt;
&lt;pre&gt;
(defn unfold-tails [s]
  (unfold empty? identity rest s))
  &lt;/pre&gt;

&lt;p&gt;The standard map, becomes:&lt;/p&gt;
&lt;pre&gt;
(defn unfold-map [f s]
  (unfold empty? #(f (first %)) rest s))
&lt;/pre&gt;
&lt;p&gt;Now, here the implementation:&lt;/p&gt;
&lt;script type="text/javascript" src="https://gist.github.com/1184113.js?file=unfold-util.clj"&gt;
&lt;pre&gt;;; Enrico Franchi (c) 2011
;; Released under the terms of the MIT License
;; http://www.opensource.org/licenses/mit-license.php

(ns unfold-util
  (:use [clojure.test]))

(defn unfold
  ([p f g seed tail-g]
   (lazy-seq
     (if (p seed)
       (tail-g seed)
       (cons (f seed)
             (unfold p f g (g seed))))))
  ([p f g seed]
   (unfold p f g seed (fn [_] ()))))

(deftest standard-unfold []
  (is (= (set (unfold #(= 0 %) identity dec 10))
    (set (range 1 11)))))

(deftest infinite-unfold []
  (is (=
    (take 10 (unfold
      (fn [x] false)
      identity
      inc
      0))
    (take 10 (iterate inc 0)))))

(run-tests)
&lt;/pre&gt;
&lt;/script&gt;
&lt;h3&gt;Upgrade&lt;/h3&gt;
&lt;p&gt;With this update, I present an upgraded version with the tail-g parameter. The classic srfi-1 Scheme version also has this argument. Originally, I thought that in Clojure I could use it to have different sequence types. On a second thought, it can't work because of the way Clojure manages sequences (at least, not in the sense that I intended it).&lt;/p&gt;
&lt;p&gt;On a second thought, however, it is highly useful. Consider for example the tails function I defined above. In fact it returns all non-empty substrings of a given string. This makes sense in lots of contexts, however it is different from the definition of the Haskell function.&lt;p&gt;
&lt;pre&gt;
tails                   :: [a] -&gt; [[a]]
tails xs                =  xs : case xs of
                                  []      -&gt; []
                                  _ : xs' -&gt; tails xs'
&lt;/pre&gt;
That could be roughly translated (losing laziness) as:
&lt;pre&gt;
(defn tails [xs]
  (cons xs
        (when (seq xs)
          (tails (rest xs)))))
&lt;/pre&gt;
&lt;p&gt;This function also returns the empty list. Surely, it would be possible to (cons () (unfold-tails xs)), but that would break the property that each (finite) element in the resulting sequence is longer than the following. Without the kludge, the unfold-tails function breaks the strictness property that the resulting list contains xs if xs is empty. Accordingly, tails should really be defined to include the empty list. Appending the empty list to the end of the list returned from unfold-tails would maintain both properties, but would be excessively inefficient.&lt;/p&gt;
&lt;p&gt;On the other hand, specifying the tail-g function allows a cleaner definition&lt;/p&gt;
&lt;pre&gt;
(defn tails [xs]
  (unfold empty? identity rest xs
          #(list %)))
&lt;/pre&gt;
&lt;p&gt;Essentially, without tail-g it is not possible to include in the resulting sequence elements which depend from the element which makes the sequence stop.&lt;/p&gt;
&lt;h3&gt;Updates&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Substituted (if ($1) (list) ($2)) with (when-not ($1) ($2)) after some tweets from @jneira and @hiredman_.&lt;/li&gt;
&lt;li&gt;Added version with tail-g&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rik0/ftclj"&gt;Here&lt;/a&gt; more functions and experiments with unfold.&lt;/li&gt;
&lt;li&gt;Removed HTML crap from cut and paste&lt;/li&gt;
&lt;/ul&gt;


&lt;!-- Technorati Tags Start --&gt;
&lt;p&gt; Technorati Tags:
&lt;a href="http://technorati.com/tag/Clojure" rel="tag"&gt;Clojure&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Anamorphism" rel="tag"&gt;Anamorphism&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Unfold" rel="tag"&gt;Unfold&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Functional+Programming" rel="tag"&gt;Functional Programming&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Programming" rel="tag"&gt;Programming&lt;/a&gt;
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-7901138101896318285?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-7901138101896318285?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MR7JR-WBI1v3KRr7VX3UcQjg97E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MR7JR-WBI1v3KRr7VX3UcQjg97E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MR7JR-WBI1v3KRr7VX3UcQjg97E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MR7JR-WBI1v3KRr7VX3UcQjg97E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/2ca3IYWHTms" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/7901138101896318285/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=7901138101896318285" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/7901138101896318285?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/7901138101896318285?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/2ca3IYWHTms/clojure-unfold-and-anamorphisms.html" title="Clojure: Unfold and Anamorphisms" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>7</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/08/clojure-unfold-and-anamorphisms.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUEQ3ozeCp7ImA9WhdXFUg.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-6639450243151387372</id><published>2011-08-28T18:50:00.000+02:00</published><updated>2011-08-28T18:50:02.480+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-28T18:50:02.480+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Scheme" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Atkin Sieve" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Haskell" /><category scheme="http://www.blogger.com/atom/ns#" term="Computer Science" /><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms" /><title>On monads and a poor old (dead) greek geek</title><content type="html">After immensely enjoying the &lt;a href="http://www.enrico-franchi.org/2011/08/excellent-learn-you-haskell-for-greater.html"&gt;LYHFFP&lt;/a&gt; book, I immediately started playing with Haskell a bit. Since lately I have been implementing sieves in different languages, I found that the Sieve of Eratosthenes was an excellent candidate. In fact, there are quite a few Haskell versions out there (and almost all of them are faster than the version I'm going to write, but this is about an enlightenment process, not an algorithm implementation).&lt;br /&gt;
&lt;h3&gt;

Bits of unrequested and useless background thoroughly mixed with rantings and out of place sarcasm&lt;/h3&gt;
I also had to reconsider some of my assumptions: I was familiar with Turner's "version" of the sieve and O'Neill's article, which was basically about Turner's version not being a real implementation of the sieve and about not everybody noticing that for like 30 years (and teaching that to student as a good algorithm). I found this story extremely amusing, in the sense that sometimes functional programmers are quite a bit too full of themselves and how cool is their language and overlook simple things.&lt;br /&gt;
&lt;br /&gt;
Turner's algorithm essentially was this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #f9f9f9; border-bottom-color: #2F6FAB; border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: #2F6FAB; border-left-style: dashed; border-left-width: 1px; border-right-color: #2F6FAB; border-right-style: dashed; border-right-width: 1px; border-top-color: #2F6FAB; border-top-style: dashed; border-top-width: 1px; color: black; line-height: 1.1em; padding-bottom: 1em; padding-left: 1em; padding-right: 1em; padding-top: 1em;"&gt;&lt;span style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;span style="color: #2040a0;"&gt;primesT&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;=&lt;/span&gt; &lt;span style="color: red;"&gt;2&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;:&lt;/span&gt; &lt;span style="color: #2040a0;"&gt;sieve&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: red;"&gt;3&lt;/span&gt;,&lt;span style="color: red;"&gt;5&lt;/span&gt;&lt;span style="color: #4444ff;"&gt;..&lt;/span&gt;&lt;span style="color: #4444ff;"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;  &lt;strong&gt;where&lt;/strong&gt;
&lt;span style="color: #2040a0;"&gt;  sieve&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: #2040a0;"&gt;p&lt;/span&gt;&lt;span style="color: #4444ff;"&gt;:&lt;/span&gt;&lt;span style="color: #2040a0;"&gt;xs&lt;/span&gt;&lt;span style="color: #4444ff;"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;=&lt;/span&gt; &lt;span style="color: #2040a0;"&gt;p&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;:&lt;/span&gt; &lt;span style="color: #2040a0;"&gt;sieve&lt;/span&gt; &lt;span style="color: #4444ff;"&gt;&lt;strong&gt;[&lt;/strong&gt;&lt;/span&gt;&lt;span style="color: #2040a0;"&gt;x&lt;/span&gt; | &lt;span style="color: #2040a0;"&gt;x&lt;/span&gt;&lt;strong&gt;&amp;lt;-&lt;/strong&gt;&lt;span style="color: #2040a0;"&gt;xs&lt;/span&gt;, &lt;span style="color: #2040a0;"&gt;rem&lt;/span&gt; &lt;span style="color: #2040a0;"&gt;x&lt;/span&gt; &lt;span style="color: #2040a0;"&gt;p&lt;/span&gt; /&lt;span style="color: #4444ff;"&gt;=&lt;/span&gt; &lt;span style="color: red;"&gt;0&lt;/span&gt;&lt;span style="color: #4444ff;"&gt;&lt;strong&gt;]&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;
And essentially here the point is that to me it does not really look like a sieve, but like a trial division algorithm. Quite amusingly I found a lengthy discussion about that &lt;a href="http://en.literateprograms.org/Sieve_of_Eratosthenes_(Haskell)#chunk%20def:guarded_Eratosthenes"&gt;here&lt;/a&gt;. The good part is that they rather easily (if you read Haskell as you drink water) derive optimized versions of this algorithm which have decent algorithmic performance and then take some lines in trying to convince us that the code above should not be called naive (which I do not intend as an insult, but as a mere consideration) and that should be regarded as a "specification".&lt;br /&gt;
&lt;br /&gt;
Now I quite understand that declarative languages are excellent tools to write definitions of mathematical stuff (and Haskell is especially good at this), but as far as I know the context in which the one-liner was presented is that of an algorithm, not of a specification.&lt;br /&gt;
&lt;br /&gt;
Essentially this unrequested bit of background is just to retaliate against the world for me not being able to come up with a really fast implementation. Basically the optimized version of Turner's algorithm is quite faster than my monadic versions. Which is fine, as my goal was to get some insight on monads, which I think I did. More on this &lt;a href="http://www.haskell.org/haskellwiki/Prime_numbers"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: 14px; font-weight: bold;"&gt;On the author's unmistakably twisted mind&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: 14px; font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
So... back to our business. I struggled a lot to use Data.Array.ST to implement the sieve. Essentially the point is that I find the monadic do notation quite less clear than the pure functional notation with &amp;gt;&amp;gt;= and &amp;gt;&amp;gt;. This is probably a symptom my brain having been corrupted by maths and myself turning in a soulless robot in human form. Nevertheless, I finished the task but I was so ashamed I buries the code under piles of new git commits.&lt;br /&gt;
&lt;br /&gt;
Essentially, I found mixing and matching different monads (like lists) excruciatingly confusing in do notation. Notice, that was just *my* problem, but I just had to struggle with the types, write outer helper functions to check their type and so on. Basically I was resorting to try and error and much shame will rain on me for that. So I threw away the code and started writing it simply using &amp;gt;&amp;gt;= and &amp;gt;&amp;gt;. Now everything kind of made sense. To me it looked like a dual of CPS, which is something I'm familiar with. The essential point is that the resulting code was:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Hopefully correct.&lt;/li&gt;
&lt;li&gt;Written in one go, essentially easily&lt;/li&gt;
&lt;li&gt;Rather unreadable&lt;/li&gt;
&lt;/ol&gt;
So the resulting code is:&lt;br /&gt;
&lt;script src="https://gist.github.com/1171446.js?file=snippets/erat2.hs"&gt;
&lt;/script&gt;
&lt;br /&gt;
Essentially for (3) I decided it was time to use some do notation. Perhaps things could be improved. What I came out with is a rather slow implementation, but I am rather satisfied. I think it is extremely readable: it retains a very imperative flavor (which is good in the sense that the original algorithm was quite imperative) and I believe could be written and understood even by people not overly familiar with Haskell. It almost has a pseudo-code like quality, wasn't it for some syntactical gimmicks like "&lt;span style="font-family: 'Bitstream Vera Sans Mono', Courier, monospace; line-height: 16px; white-space: pre;"&gt;&lt;span class="o" style="font-weight: bold; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;$&lt;/span&gt; &lt;span class="nf" style="color: #990000; font-weight: bold; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;\&lt;/span&gt;&lt;span class="n" style="line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;idx&lt;/span&gt; &lt;span class="ow" style="font-weight: bold; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;".&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1171446.js?file=snippets/erat1.hs"&gt;
&lt;/script&gt;
&lt;br /&gt;
Somewhere in the rewrite process I left out the small optimizations regarding running to sqrt(lastPrime) instead of just to lastPrime, but this is not really the point. Still... I'm quite happy because I feel I now have a better grasp of some powerful Haskell concepts.&lt;br /&gt;
&lt;br /&gt;
However, I feel like Clojure macros are greatly missed. Moreover, I found really easier to understand the correspondingly "difficult" concepts of Clojure or Scheme (a part from call/cc which kind of eludes me, think I have to do some explicitly tailored exercises sooner or later).&lt;br /&gt;
&lt;br /&gt;
I also feel like continuously jumping from language to language could lead to problems in the long run, in the sense that if I want to use some language in the real world I probably need more experience with that particular language, otherwise I will just stick with Python because even when sub-optimal I'm so much more skilled in the python platform than in other platforms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-6639450243151387372?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/_Q6yKaAU68CdNLZ8Svuwr8OvtCY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_Q6yKaAU68CdNLZ8Svuwr8OvtCY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/_Q6yKaAU68CdNLZ8Svuwr8OvtCY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/_Q6yKaAU68CdNLZ8Svuwr8OvtCY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/Zq1D9PRIfno" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/6639450243151387372/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=6639450243151387372" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/6639450243151387372?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/6639450243151387372?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/Zq1D9PRIfno/on-monads-and-poor-old-dead-greek-geek.html" title="On monads and a poor old (dead) greek geek" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.enrico-franchi.org/2011/08/on-monads-and-poor-old-dead-greek-geek.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8NRXo4fip7ImA9WhdQGEg.&quot;"><id>tag:blogger.com,1999:blog-6082788733343957185.post-5373242495280845050</id><published>2011-08-20T18:25:00.001+02:00</published><updated>2011-08-20T18:31:34.436+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-20T18:31:34.436+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Functional Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Freedom Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Declarative Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Programming Languages" /><category scheme="http://www.blogger.com/atom/ns#" term="Clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="Haskell" /><title>Excellent Learn You a Haskell for Greater Good</title><content type="html">This is the third book explicitly about Haskell I directly buy (a part from things such as Functional Data Structers or Pearls of Functional Algorithm Design), the others being Haskell School of Expression and Real World Haskell, plus some online tutorials and &lt;a href="http://homepages.cwi.nl/~jve/HR/"&gt;freely available books&lt;/a&gt;. I believe they are all excellent books, although with slightly different focus. They come from different ages as well (with HSOE being quite holder).&lt;br /&gt;
&lt;br /&gt;
Back then I enjoyed a lot HSOE, but I think I missed something. Large part of the book used libraries not easily available on the Mac, for example. Moreover, the book did not use large parts of the Haskell standard library which are very useful. For that and other reasons, I did not go on working with Haskell. Real World Haskell has a very practical focus and I quite enjyoed that. Unfortunately, I still remembered too much Haskell not to "jump" the initial parts of the book (and that is usually a bad thing, because you don't get comfortable with the author style before jumping to more elaborate subjects). Moreover, the book is quite massive and I had other stuff to do back then (like graduating).&lt;br /&gt;
&lt;br /&gt;
I did not even want to buy LYHFGG. Afterall, I am a bit skeptical over using Haskell for real world stuff (I prefer more pragmatic languages like Python or Clojure) and so I tried to resist the urge to buy another Haskell book (I could finish RWH, afterall). For a combination of events I did not even remember, I put the book in an amazon order. Understanding a couple of Haskell idioms could improve my clojure, I thought, and I started reading the book in no time.&lt;br /&gt;
&lt;br /&gt;
The first part of the book is very well done but somewhat uninteresting. By the time I started reading it, I had forgotten most Haskell I knew and consequently I read that carefully: however, I made the mistake not to start a small project just to toy with the language. That is the reason I say "somewhat uninteresting": it is very basic, very easy and very clear. Still, I did only remind me of things I knew, without really improving my way of thinking much. Still, the writing was fun and light and I read through it quickly. I consider it a very good introduction to functional programming in Haskell and to functional programming in general and as such the tag line "a beginner guide" is well deserved.&lt;br /&gt;
&lt;br /&gt;
Later in chapter 11 comes the real meat. Functors, Applicative Functors, Monoids and then Monads are presented. The order is excellent: after having learned Applicative Functors, Monads require only a small further understanding steps. Moreover, repeating all the reasoning on Maybe and lists really clarifies the thing. The examples were also in HSOE, but connecting the dots was somewhat left to the reader. This time I did not make the mistake to see monads as just a tool to implement state monad and reached a deeper insight on the subject.&lt;br /&gt;
&lt;br /&gt;
About the book itself, I just love no starch press...&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;img src="http://ecx.images-amazon.com/images/I/41-CJxuUV%2BL._SL160_.jpg" /&gt;&lt;br /&gt;
&lt;a href="http://www.amazon.com/Learn-You-Haskell-Great-Good/dp/1593272839%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1593272839"&gt;"Learn You a Haskell for Great Good!: A Beginner's Guide" (Miran Lipovaca)&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;img height="160" src="http://ecx.images-amazon.com/images/I/511DnNxEViL._SL160_.jpg" width="116" /&gt;&lt;br /&gt;
&lt;a href="http://www.amazon.com/Haskell-School-Expression-Functional-Programming/dp/0521644089%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0521644089"&gt;"The Haskell School of Expression: Learning Functional Programming through Multimedia" (Paul Hudak)&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;img height="160" src="http://ecx.images-amazon.com/images/I/41%2BD3wuYk-L._SL160_.jpg" width="122" /&gt;&lt;br /&gt;
&lt;a href="http://www.amazon.com/Real-World-Haskell-Bryan-OSullivan/dp/0596514980%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0596514980"&gt;"Real World Haskell" (Bryan O'Sullivan, John Goerzen, Don Stewart)&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;img src="http://ecx.images-amazon.com/images/I/41vKmriWp-L._SL160_.jpg" /&gt;&lt;br /&gt;
&lt;a href="http://www.amazon.com/Pearls-Functional-Algorithm-Design-Richard/dp/0521513383%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0521513383"&gt;"Pearls of Functional Algorithm Design" (Richard Bird)&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;img src="http://ecx.images-amazon.com/images/I/41XlPaC%2BZqL._SL160_.jpg" /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504%3FSubscriptionId%3D0PZ7TM66EXQCXFVTMTR2%26tag%3Drik-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0521663504"&gt;"Purely Functional Data Structures" (Chris Okasaki)&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;/div&gt;
Technorati Tags: &lt;a href="http://technorati.com/tag/Haskell" rel="tag"&gt;Haskell&lt;/a&gt;, &lt;a href="http://technorati.com/tag/Functional+Programming" rel="tag"&gt;Functional Programming&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6082788733343957185-5373242495280845050?l=www.enrico-franchi.org' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/IMoKugiuwa3VsWoRP3vRYPSB4Eg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IMoKugiuwa3VsWoRP3vRYPSB4Eg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/IMoKugiuwa3VsWoRP3vRYPSB4Eg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/IMoKugiuwa3VsWoRP3vRYPSB4Eg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Rik0TechTemple/~4/VN8Nun5zve0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.enrico-franchi.org/feeds/5373242495280845050/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6082788733343957185&amp;postID=5373242495280845050" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/5373242495280845050?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6082788733343957185/posts/default/5373242495280845050?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Rik0TechTemple/~3/VN8Nun5zve0/excellent-learn-you-haskell-for-greater.html" title="Excellent Learn You a Haskell for Greater Good" /><author><name>enrico franchi</name><uri>https://profiles.google.com/112243281728981403168</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-qLCWd3s-YF0/AAAAAAAAAAI/AAAAAAAAAVU/0iiZLO1KbGA/s512-c/photo.jpg" /></author><thr:total>0</thr:total><georss:featurename>Parma, Italy</georss:featurename><georss:point>44.8078657 10.3295478</georss:point><georss:box>44.6886707 10.2151533 44.9270607 10.4439423</georss:box><feedburner:origLink>http://www.enrico-franchi.org/2011/08/excellent-learn-you-haskell-for-greater.html</feedburner:origLink></entry></feed>

