{"id":3176,"date":"2016-04-05T09:34:24","date_gmt":"2016-04-05T13:34:24","guid":{"rendered":"http:\/\/fgiasson.com\/blog\/?p=3176"},"modified":"2016-06-27T16:39:43","modified_gmt":"2016-06-27T20:39:43","slug":"using-clojure-in-org-mode-and-implementing-asynchronous-processing","status":"publish","type":"post","link":"https:\/\/fgiasson.com\/blog\/index.php\/2016\/04\/05\/using-clojure-in-org-mode-and-implementing-asynchronous-processing\/","title":{"rendered":"Using Clojure in Org-mode and Implementing Asynchronous Processing"},"content":{"rendered":"<div id=\"content\">\n<div id=\"outline-container-orgheadline1\" class=\"outline-2\">\n<div id=\"text-orgheadline1\" class=\"outline-text-2\">\n<p>I recently started to get interested in <a href=\"http:\/\/orgmode.org\/\">Org-mode<\/a> which was still unknown to me just a few weeks ago until I read this <a href=\"http:\/\/howardism.org\/Technical\/Emacs\/literate-programming-tutorial.html\">great article<\/a> from Howard Abrams about <a href=\"https:\/\/en.wikipedia.org\/wiki\/Literate_programming\">literate programming<\/a> using Org-mode. Initially I was wondering what this Emacs package was really about (it does all kind of things like document outlining (\u00c3\u00a0 la Markdown), tasks management and planning, agenda generation, time clocking\u00e2\u20ac\u00a6 and it has a series of features related to <a href=\"http:\/\/orgmode.org\/manual\/Working-With-Source-Code.html#Working-With-Source-Code\">literal programming<\/a> that let you embed and run <code>code blocks<\/code> using sub-processes and to display results directly into the Org-mode [text] document.<\/p>\n<p>What I was really interested in are the <code>code block<\/code> related features of Org-mode. Initially I wanted to test Org-mode using as a Notebook application but I also wanted to re-start trying to coding in <code>literate programming<\/code> format. I will extend on the later in my next blogpost, for now I will concentrate on why I want to use Org-mode as notebook style programming user interfaces. Since everything I code these days is in <a href=\"https:\/\/clojure.org\/\">Clojure<\/a> programming language, I wanted to be able to use Org-mode&#8217;s code blocks with Clojure.<\/p>\n<p>Finally I will describes a few issues I experimented in the process and how I update the Org-babel-clojure package to fix those issues.<\/p>\n<\/div>\n<div id=\"outline-container-orgheadline2\" class=\"outline-3\">\n<h3 id=\"orgheadline2\">Notebook Creations Using Org-mode<\/h3>\n<div id=\"text-orgheadline2\" class=\"outline-text-3\">\n<p>My partner Mike Bergman got me interested in notebook style programming user interfaces maybe a year ago. We wanted to find a way to easily experiment with different data management structures and frameworks we are developing at <a href=\"http:\/\/structureddynamics.com\/\">Structured Dynamics<\/a>. The idea behind a Notebook was quite interesting: it is to run code snippets anywhere in a document, to see the results within that document and finally to be able to document the process. Then if something changed in the data, or in the code, then each code snipped within a Notebook could be rerun at any time, and the results updated. This is a great way to do experimentation, to keep tracks of the tests your are doing and to document the whole process.<\/p>\n<p>The idea is really interesting for the kind of work we are doing. I tested the <a href=\"http:\/\/gorilla-repl.org\/\">Gorilla REPL<\/a> which is an implementation of this style user interface in Clojure. Other such interfaces exists in other programming languages like <a href=\"https:\/\/ipython.org\/\">IPython<\/a>, <a href=\"http:\/\/www.wolfram.com\/\">Wolfram<\/a>, etc. However, I always had an issue with what I was using: I had a hard time re-purposing the content I was creating; I couldn&#8217;t easily export this information in different format (blog posts, papers, etc.). Saving, reloading, re-running in different environment was often too much trouble: until I find Org-mode.<\/p>\n<p>I am not sure why I didn&#8217;t came across Org-mode before, maybe because it was not advertised as as &#8220;notebook style programming user interface&#8221; but this is really what it is (mostly) all about, at least to me. As far as I know, this is the only such software that let you work with any kind of programming language in the same notebook. It can also export the notebooks in virtually any formats (several formats are supported by Org-mode itself, others can be exported using <a href=\"http:\/\/pandoc.org\/\">Pandoc<\/a>).<\/p>\n<p>This being said, I started experimenting with Org-mode to create different kind of Notebooks using Clojure. I am using notebooks that shows how to use different APIs we are creating, or ones that shows how different data processing workflows actually works or that shows how some structures (like <a href=\"http:\/\/umbel.org\/\">UMBEL<\/a>) have been created and how they can be leveraged. I am also creating notebooks to research and experiment different kind of algorithms that we are trying to implement in our products, or to do bug investigation reports for our clients, or\u00e2\u20ac\u00a6 the possibilities are probably endless. But the core idea is almost always the same: communication. We write these notebooks to communicate (write) information for other people to consume (or more important, his future self).<\/p>\n<p>Given this kind of tasks that I am performing in a notebook, I often have to run procedures that may takes minutes or even hours before their processing is finalized. However, as you will see below, running procedures that takes minutes to finalize is a show stopper with the current Org-mode <code>Org-babel-clojure (ob-clojure.el)=<\/code> package that let Org-mode to run Clojure code.<\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgheadline3\" class=\"outline-3\">\n<h3 id=\"orgheadline3\">Installing &amp; Configuring Org-mode<\/h3>\n<div id=\"text-orgheadline3\" class=\"outline-text-3\">\n<p>Before outlining the issues I had with the current implementation of the <a href=\"http:\/\/orgmode.org\/worg\/org-contrib\/babel\/languages\/ob-doc-clojure.html\">Org-babel-clojure<\/a> package, let me explain how I installed and configured Org-mode locally.<\/p>\n<p>First of all I installed <code>Org-mode contribs<\/code> from ELPA, then I configured it that way in my <code>.emacs<\/code> file. Note that I made multiple little changes here and there to end-up with the kind of editor I am comfortable to use. So this is about installing, enabling and tweaking Org-mode in Emacs:<\/p>\n<div class=\"org-src-container\">\n<pre class=\"src src-elisp\"><span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Configure Org-mode with Cider<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Load Org-mode<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>add-to-list 'load-path <span style=\"color: #e6db74;\">\"~\/.emacs.d\/lib\/org-mode\/\"<\/span><span style=\"color: #a1efe4;\">)<\/span>\n<span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">org<\/span><span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Here I specify the languages I want to be able to use with Org-babel.<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>org-babel-do-load-languages\n 'org-babel-load-languages\n '<span style=\"color: #e6db74;\">(<\/span><span style=\"color: #66d9ef;\">(<\/span>clojure . t<span style=\"color: #66d9ef;\">)<\/span>\n   <span style=\"color: #66d9ef;\">(<\/span>sh . t<span style=\"color: #66d9ef;\">)<\/span>\n   <span style=\"color: #66d9ef;\">(<\/span>emacs-lisp . t<span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Specify the Clojure back-end we want to use in Org-mode.<\/span>\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">I personally use Cider, but one could specify Slime<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>setq org-babel-clojure-backend 'cider<span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Let's have pretty source code blocks<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>setq org-edit-src-content-indentation 0\n      org-src-tab-acts-natively t\n      org-src-fontify-natively t\n       org-confirm-babel-evaluate nil\n      org-support-shift-select 'always<span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Useful keybindings when using Clojure from Org<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>org-defkey org-mode-map <span style=\"color: #e6db74;\">\"\\C-x\\C-e\"<\/span> 'cider-eval-last-sexp<span style=\"color: #a1efe4;\">)<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>org-defkey org-mode-map <span style=\"color: #e6db74;\">\"\\C-c\\C-d\"<\/span> 'cider-doc<span style=\"color: #a1efe4;\">)<\/span>      \n\n<span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">cider<\/span><span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Remove the markup characters, i.e., \"\/text\/\" becomes (italized) \"text\"<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>setq org-hide-emphasis-markers t<span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">No timeout when executing calls on Cider via nrepl<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>setq org-babel-clojure-nrepl-timeout nil<span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Turn on visual-line-mode for Org-mode only<\/span>\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Note: you have to install \"adaptive-wrap\" from elpa<\/span>\n<span style=\"color: #a1efe4;\">(<\/span>add-hook 'org-mode-hook 'turn-on-visual-line-mode<span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #75715e;\">;; <\/span><span style=\"color: #75715e;\">Enable Confluence export (or any other contributed export formats)<\/span>\n<span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">ox-confluence<\/span><span style=\"color: #a1efe4;\">)<\/span>\n<\/pre>\n<\/div>\n<p>Note that most of these configurations comes from the <a href=\"http:\/\/orgmode.org\/worg\/org-contrib\/babel\/languages\/ob-doc-clojure.html\">Org-babel-clojure<\/a> webpage.<\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgheadline4\" class=\"outline-3\">\n<h3 id=\"orgheadline4\">Timeout issues<\/h3>\n<div id=\"text-orgheadline4\" class=\"outline-text-3\">\n<p>The first issue I encountered is when I started to run code that was taking longer than 10 seconds. Every time I was running such code, I ran into the follow error:<\/p>\n<blockquote><p>&#8220;nrepl-send-sync-request: Sync nREPL request timed out&#8221;<\/p><\/blockquote>\n<p>What this error means is the the synchronous request to nREPL (the Clojure back-end that run the actual code written into Org-mode) timeout. I was really not expecting a query to timeout that way. This led me to start reading the <code>Org-babel-clojure<\/code> code to see where such an error may be coming from. However, I have to do a disclaimer here: I never really looked into <code>Elisp<\/code> code until now. The only other work I did with Elisp was to configure Emacs so be indulgent with me and report all awkward code I may be writing here.<\/p>\n<p>My journey started with the <a href=\"http:\/\/orgmode.org\/cgit.cgi\/org-mode.git\/plain\/lisp\/ob-clojure.el\">ob-clojure.el<\/a> which is the file used to make the bridge between Org-mode and the Clojure back-end (Cider\/nREPL in this case). It is after reading that code that I noticed the following function: <code>org-babel-execute:clojure<\/code> which appeared to be the thing that is run when we run a Clojure code block in Org-mode. Then I noticed the call to the function <code>nrepl-sync-request:eval<\/code>. That needed to be the culprit and what sent this <i>Sync<\/i> timeout error. <a href=\"https:\/\/github.com\/clojure-emacs\/cider\/blob\/faba0fe732bff3bd36dc3717e75429cf0c3b95ac\/nrepl-client.el#L1047\">I found this function in the Cider code<\/a>. But then I found this other function that is called by the later: <a href=\"https:\/\/github.com\/clojure-emacs\/cider\/blob\/faba0fe732bff3bd36dc3717e75429cf0c3b95ac\/nrepl-client.el#L931\">nrepl-send-sync-request<\/a>. It is when I read this function that I noticed the <a href=\"https:\/\/github.com\/clojure-emacs\/cider\/blob\/faba0fe732bff3bd36dc3717e75429cf0c3b95ac\/nrepl-client.el#L956\">nrepl-sync-request-timeout<\/a> variable. Looking back at <code>org-babel-execute:clojure<\/code> I couldn&#8217;t see where I could define this timeout parameter. I looks like it was not possible to define it, which was a big issue to me since I needed to be able to run procedure that takes minutes to run.<\/p>\n<p>It is at that time that I choose to hack the <code>ob-clojure.el<\/code> code to expose that timeout setting such that I could setup it properly for my own needs. The code I created for that purpose is:<\/p>\n<div class=\"org-src-container\">\n<pre class=\"src src-elisp\"><span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Addition of the org-babel-clojure-nrepl-timeout setting<\/span>\n<span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #f92672;\">defvar<\/span> <span style=\"color: #fd971f;\">org-babel-clojure-nrepl-timeout<\/span> nil<span style=\"color: #a1efe4;\">)<\/span>\n\n<span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #f92672;\">defun<\/span> <span style=\"color: #a6e22e;\">org-babel-execute:clojure<\/span> <span style=\"color: #e6db74;\">(<\/span>body params<span style=\"color: #e6db74;\">)<\/span>\n  <span style=\"color: #75715e;\">\"Execute a block of Clojure code with Babel.\"<\/span>\n  <span style=\"color: #e6db74;\">(<\/span><span style=\"color: #f92672;\">let<\/span> <span style=\"color: #66d9ef;\">(<\/span><span style=\"color: #fd971f;\">(<\/span>expanded <span style=\"color: #a6e22e;\">(<\/span>org-babel-expand-body:clojure body params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n        result<span style=\"color: #66d9ef;\">)<\/span>\n    <span style=\"color: #66d9ef;\">(<\/span>case org-babel-clojure-backend\n      <span style=\"color: #fd971f;\">(<\/span>cider\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">cider<\/span><span style=\"color: #a6e22e;\">)<\/span>\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">let<\/span> <span style=\"color: #e6db74;\">(<\/span><span style=\"color: #66d9ef;\">(<\/span>result-params <span style=\"color: #fd971f;\">(<\/span>cdr <span style=\"color: #a6e22e;\">(<\/span>assoc <span style=\"color: #f92672;\">:result-params<\/span> params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span>\n         <span style=\"color: #e6db74;\">(<\/span>setq result\n               <span style=\"color: #66d9ef;\">(<\/span>nrepl-dict-get\n                <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Addition of the org-babel-clojure-nrepl-timeout setting<\/span>\n                <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #f92672;\">let<\/span> <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #a1efe4;\">(<\/span>nrepl-sync-request-timeout org-babel-clojure-nrepl-timeout<span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span>\n                  <span style=\"color: #a6e22e;\">(<\/span>nrepl-sync-request:eval\n                   expanded <span style=\"color: #a1efe4;\">(<\/span>cider-current-connection<span style=\"color: #a1efe4;\">)<\/span> <span style=\"color: #a1efe4;\">(<\/span>cider-current-session<span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n                <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #f92672;\">if<\/span> <span style=\"color: #a6e22e;\">(<\/span>or <span style=\"color: #a1efe4;\">(<\/span>member <span style=\"color: #e6db74;\">\"output\"<\/span> result-params<span style=\"color: #a1efe4;\">)<\/span>\n                        <span style=\"color: #a1efe4;\">(<\/span>member <span style=\"color: #e6db74;\">\"pp\"<\/span> result-params<span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span>\n                    <span style=\"color: #e6db74;\">\"out\"<\/span>\n                  <span style=\"color: #e6db74;\">\"value\"<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n      <span style=\"color: #fd971f;\">(<\/span>slime\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">slime<\/span><span style=\"color: #a6e22e;\">)<\/span>\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">with-temp-buffer<\/span>\n         <span style=\"color: #e6db74;\">(<\/span>insert expanded<span style=\"color: #e6db74;\">)<\/span>\n         <span style=\"color: #e6db74;\">(<\/span>setq result\n               <span style=\"color: #66d9ef;\">(<\/span>slime-eval\n                `<span style=\"color: #fd971f;\">(<\/span>swank:eval-and-grab-output\n                  ,<span style=\"color: #a6e22e;\">(<\/span>buffer-substring-no-properties <span style=\"color: #a1efe4;\">(<\/span>point-min<span style=\"color: #a1efe4;\">)<\/span> <span style=\"color: #a1efe4;\">(<\/span>point-max<span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n                <span style=\"color: #fd971f;\">(<\/span>cdr <span style=\"color: #a6e22e;\">(<\/span>assoc <span style=\"color: #f92672;\">:package<\/span> params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span>\n    <span style=\"color: #66d9ef;\">(<\/span>org-babel-result-cond <span style=\"color: #fd971f;\">(<\/span>cdr <span style=\"color: #a6e22e;\">(<\/span>assoc <span style=\"color: #f92672;\">:result-params<\/span> params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n      result\n      <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #f92672;\">condition-case<\/span> nil <span style=\"color: #a6e22e;\">(<\/span>org-babel-script-escape result<span style=\"color: #a6e22e;\">)<\/span>\n        <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #fd971f; font-weight: bold; font-style: italic; text-decoration: underline;\">error<\/span> result<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span>\n<\/pre>\n<\/div>\n<p>What I modified in this code is to add a new global setting <code>org-babel-clojure-nrepl-timeout<\/code>. If this setting is <code>nil<\/code> then there won&#8217;t be any timeout, otherwise the timeout value will be in seconds. What I did is simply to bind its value to the nREPL setting <code>nrepl-sync-request-timeout<\/code> and be done with it.<\/p>\n<p>That solved this issue. After I updated <code>ob-clojure.el<\/code> accordingly, I could run Clojure code that may takes several minutes in Org-mode! That was fanstastic, but it was not optimal.<\/p>\n<p>In fact, when I am running workflows that may take 30 minutes to finalize, I normally output processing steps in the REPL such that I know where the process is and what it is currently processing.<\/p>\n<p>The problem with the current implementation of <code>Org-babel-clojure<\/code> is that it uses the synchronous API of the nREPL. What I want is to be able to run Clojure code asynchronously such that I can get some feedbacks (via the REPL) from the procedure I am running. This opened a kind of a Pandora box, and something that looked simple turned out to be more complex than anticipated for someone without any knowledge into Elisp, internal mechanisms and APIs of Emacs.<\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgheadline5\" class=\"outline-3\">\n<h3 id=\"orgheadline5\">Making Org-babel-clojure &#8220;Asynchrone&#8221;<\/h3>\n<div id=\"text-orgheadline5\" class=\"outline-text-3\">\n<p>The next goal I had is to try to make <code>Org-babel-clojure<\/code> asynchrone. What I wanted is to be able to get, somehow, was the output of a Clojure procedure when that procedure was outputing something to the REPL. My second journey started after reading John Kitchin&#8217;s blog post about <a href=\"http:\/\/kitchingroup.cheme.cmu.edu\/blog\/2015\/11\/20\/Asynchronously-running-python-blocks-in-org-mode\/\">Asynchronously running Python code<\/a> into Org-mode code blocks. What I found out is that Python code was run via a <code>sub-process<\/code> which run the Python interpreter. John&#8217;s solution was to use a local file to write what the interpreter is outputing and then to feed that output to a new window that got created by John&#8217;s function.<\/p>\n<p>I took that example as a given, and then I tried to implement the same solution, but for Clojure (without knowing what I was really doing). It is in this process that I found that the Clojure solution to that problem would be quite different than John&#8217;s. There is an asynchronous API in nREPL, it is just that it is not used in <code>Org-babel-clojure<\/code>. What I ended-up using from John&#8217;s example is not his code, but his core idea: using a new window to output the asynchrone process and then to kill it once the processing is finalized and before populating <code>#+RESULSTS<\/code> section of the Org-mode file.<\/p>\n<p>After much testing and debugging I ended-up with the following solution to my problem:<\/p>\n<div class=\"org-src-container\">\n<pre class=\"src src-elisp\"><span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #f92672;\">defun<\/span> <span style=\"color: #a6e22e;\">org-babel-execute:clojure<\/span> <span style=\"color: #e6db74;\">(<\/span>body params<span style=\"color: #e6db74;\">)<\/span>\n  <span style=\"color: #75715e;\">\"Execute a block of Clojure code with Babel.\"<\/span>\n  <span style=\"color: #e6db74;\">(<\/span>lexical-let* <span style=\"color: #66d9ef;\">(<\/span><span style=\"color: #fd971f;\">(<\/span>expanded <span style=\"color: #a6e22e;\">(<\/span>org-babel-expand-body:clojure body params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n                 <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">name of the buffer that will receive the asyn output<\/span>\n                 <span style=\"color: #fd971f;\">(<\/span>sbuffer <span style=\"color: #e6db74;\">\"*Clojure Sub Buffer*\"<\/span><span style=\"color: #fd971f;\">)<\/span>\n                 <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">determine if the :async option is specified for this block<\/span>\n                 <span style=\"color: #fd971f;\">(<\/span>async <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">if<\/span> <span style=\"color: #e6db74;\">(<\/span>assoc <span style=\"color: #f92672;\">:async<\/span> params<span style=\"color: #e6db74;\">)<\/span> t nil<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n                 <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">generate the full response from the REPL<\/span>\n                 <span style=\"color: #fd971f;\">(<\/span>response <span style=\"color: #a6e22e;\">(<\/span>cons 'dict nil<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n                 <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">keep track of the status of the output in async mode<\/span>\n                 status\n                 <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">result to return to Babel<\/span>\n                 result<span style=\"color: #66d9ef;\">)<\/span>\n    <span style=\"color: #66d9ef;\">(<\/span>case org-babel-clojure-backend\n      <span style=\"color: #fd971f;\">(<\/span>cider\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">cider<\/span><span style=\"color: #a6e22e;\">)<\/span>\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">let<\/span> <span style=\"color: #e6db74;\">(<\/span><span style=\"color: #66d9ef;\">(<\/span>result-params <span style=\"color: #fd971f;\">(<\/span>cdr <span style=\"color: #a6e22e;\">(<\/span>assoc <span style=\"color: #f92672;\">:result-params<\/span> params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span>\n         <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Check if the user want to run code asynchronously<\/span>\n         <span style=\"color: #e6db74;\">(<\/span><span style=\"color: #f92672;\">when<\/span> async\n           <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Create a new window with the async output buffer<\/span>\n           <span style=\"color: #66d9ef;\">(<\/span>switch-to-buffer-other-window sbuffer<span style=\"color: #66d9ef;\">)<\/span>\n\n           <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Run the Clojure code asynchronously in nREPL<\/span>\n           <span style=\"color: #66d9ef;\">(<\/span>nrepl-request:eval\n            expanded \n            <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #f92672;\">lambda<\/span> <span style=\"color: #a6e22e;\">(<\/span>resp<span style=\"color: #a6e22e;\">)<\/span> \n              <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">when<\/span> <span style=\"color: #a1efe4;\">(<\/span>member <span style=\"color: #e6db74;\">\"out\"<\/span> resp<span style=\"color: #a1efe4;\">)<\/span>\n                <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Print the output of the nREPL in the asyn output buffer<\/span>\n                <span style=\"color: #a1efe4;\">(<\/span>princ <span style=\"color: #e6db74;\">(<\/span>nrepl-dict-get resp <span style=\"color: #e6db74;\">\"out\"<\/span><span style=\"color: #e6db74;\">)<\/span> <span style=\"color: #e6db74;\">(<\/span>get-buffer sbuffer<span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span>\n              <span style=\"color: #a6e22e;\">(<\/span>nrepl--merge response resp<span style=\"color: #a6e22e;\">)<\/span>\n              <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Update the status of the nREPL output session<\/span>\n              <span style=\"color: #a6e22e;\">(<\/span>setq status <span style=\"color: #a1efe4;\">(<\/span>nrepl-dict-get response <span style=\"color: #e6db74;\">\"status\"<\/span><span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n            <span style=\"color: #fd971f;\">(<\/span>cider-current-connection<span style=\"color: #fd971f;\">)<\/span> \n            <span style=\"color: #fd971f;\">(<\/span>cider-current-session<span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span>\n\n           <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Wait until the nREPL code finished to be processed<\/span>\n           <span style=\"color: #66d9ef;\">(<\/span><span style=\"color: #f92672;\">while<\/span> <span style=\"color: #fd971f;\">(<\/span>not <span style=\"color: #a6e22e;\">(<\/span>member <span style=\"color: #e6db74;\">\"done\"<\/span> status<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n             <span style=\"color: #fd971f;\">(<\/span>nrepl-dict-put response <span style=\"color: #e6db74;\">\"status\"<\/span> <span style=\"color: #a6e22e;\">(<\/span>remove <span style=\"color: #e6db74;\">\"need-input\"<\/span> status<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n             <span style=\"color: #fd971f;\">(<\/span>accept-process-output nil 0.01<span style=\"color: #fd971f;\">)<\/span>\n             <span style=\"color: #fd971f;\">(<\/span>redisplay<span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span>\n\n           <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Delete the async buffer &amp; window when the processing is finalized<\/span>\n           <span style=\"color: #66d9ef;\">(<\/span><span style=\"color: #f92672;\">let<\/span> <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #a6e22e;\">(<\/span>wins <span style=\"color: #a1efe4;\">(<\/span>get-buffer-window-list sbuffer nil t<span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n             <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #f92672;\">dolist<\/span> <span style=\"color: #a6e22e;\">(<\/span>win wins<span style=\"color: #a6e22e;\">)<\/span>\n               <span style=\"color: #a6e22e;\">(<\/span>delete-window win<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n             <span style=\"color: #fd971f;\">(<\/span>kill-buffer sbuffer<span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span>\n\n           <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Put the output or the value in the result section of the code block<\/span>\n           <span style=\"color: #66d9ef;\">(<\/span>setq result <span style=\"color: #fd971f;\">(<\/span>nrepl-dict-get response \n                                        <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">if<\/span> <span style=\"color: #a1efe4;\">(<\/span>or <span style=\"color: #e6db74;\">(<\/span>member <span style=\"color: #e6db74;\">\"output\"<\/span> result-params<span style=\"color: #e6db74;\">)<\/span>\n                                                <span style=\"color: #e6db74;\">(<\/span>member <span style=\"color: #e6db74;\">\"pp\"<\/span> result-params<span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span>\n                                            <span style=\"color: #e6db74;\">\"out\"<\/span>\n                                          <span style=\"color: #e6db74;\">\"value\"<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span>\n         <span style=\"color: #75715e;\">; <\/span><span style=\"color: #75715e;\">Check if user want to run code synchronously<\/span>\n         <span style=\"color: #e6db74;\">(<\/span><span style=\"color: #f92672;\">when<\/span> <span style=\"color: #66d9ef;\">(<\/span>not async<span style=\"color: #66d9ef;\">)<\/span>\n           <span style=\"color: #66d9ef;\">(<\/span>setq result\n                 <span style=\"color: #fd971f;\">(<\/span>nrepl-dict-get\n                  <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">let<\/span> <span style=\"color: #a1efe4;\">(<\/span><span style=\"color: #e6db74;\">(<\/span>nrepl-sync-request-timeout \n                         org-babel-clojure-nrepl-timeout<span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span>\n                    <span style=\"color: #a1efe4;\">(<\/span>nrepl-sync-request:eval\n                     expanded <span style=\"color: #e6db74;\">(<\/span>cider-current-connection<span style=\"color: #e6db74;\">)<\/span> <span style=\"color: #e6db74;\">(<\/span>cider-current-session<span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span>\n                  <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">if<\/span> <span style=\"color: #a1efe4;\">(<\/span>or <span style=\"color: #e6db74;\">(<\/span>member <span style=\"color: #e6db74;\">\"output\"<\/span> result-params<span style=\"color: #e6db74;\">)<\/span>\n                          <span style=\"color: #e6db74;\">(<\/span>member <span style=\"color: #e6db74;\">\"pp\"<\/span> result-params<span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span>\n                      <span style=\"color: #e6db74;\">\"out\"<\/span>\n                    <span style=\"color: #e6db74;\">\"value\"<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n      <span style=\"color: #fd971f;\">(<\/span>slime\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">require<\/span> '<span style=\"color: #ae81ff;\">slime<\/span><span style=\"color: #a6e22e;\">)<\/span>\n       <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #f92672;\">with-temp-buffer<\/span>\n         <span style=\"color: #e6db74;\">(<\/span>insert expanded<span style=\"color: #e6db74;\">)<\/span>\n         <span style=\"color: #e6db74;\">(<\/span>setq result\n               <span style=\"color: #66d9ef;\">(<\/span>slime-eval\n                `<span style=\"color: #fd971f;\">(<\/span>swank:eval-and-grab-output\n                  ,<span style=\"color: #a6e22e;\">(<\/span>buffer-substring-no-properties <span style=\"color: #a1efe4;\">(<\/span>point-min<span style=\"color: #a1efe4;\">)<\/span> <span style=\"color: #a1efe4;\">(<\/span>point-max<span style=\"color: #a1efe4;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n                <span style=\"color: #fd971f;\">(<\/span>cdr <span style=\"color: #a6e22e;\">(<\/span>assoc <span style=\"color: #f92672;\">:package<\/span> params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span>\n    <span style=\"color: #66d9ef;\">(<\/span>org-babel-result-cond <span style=\"color: #fd971f;\">(<\/span>cdr <span style=\"color: #a6e22e;\">(<\/span>assoc <span style=\"color: #f92672;\">:result-params<\/span> params<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span>\n      result\n      <span style=\"color: #fd971f;\">(<\/span><span style=\"color: #f92672;\">condition-case<\/span> nil <span style=\"color: #a6e22e;\">(<\/span>org-babel-script-escape result<span style=\"color: #a6e22e;\">)<\/span>\n        <span style=\"color: #a6e22e;\">(<\/span><span style=\"color: #fd971f; font-weight: bold; font-style: italic; text-decoration: underline;\">error<\/span> result<span style=\"color: #a6e22e;\">)<\/span><span style=\"color: #fd971f;\">)<\/span><span style=\"color: #66d9ef;\">)<\/span><span style=\"color: #e6db74;\">)<\/span><span style=\"color: #a1efe4;\">)<\/span>\n<\/pre>\n<\/div>\n<p>The first thing this code does, is to expose a new <code>#+BEGIN_SRC<\/code> option called <code>:async<\/code>. If the new <code>:async option<\/code> is specified in a block code for the <code>Clojure<\/code> language, then that code block will be processed asynchronously. What this means is that a new window will be created in Emacs, it will be populated with anything that is outputted to the REPL and then it will be closed once the processing will be finalized.<\/p>\n<p>Here is an example of a code block that would use that new option:<\/p>\n<pre class=\"example\">#+BEGIN_SRC clojure :results output :async\n\n(dotimes [n 10]\n  (println n \".\")\n  (Thread\/sleep 500))\n\n#+END_SRC\n<\/pre>\n<p>This code would output &#8220;1. 2.&#8221; etc into a new window and would close that window when it reaches 10 and then populate the <code>#+RESULTS<\/code> section with the output of the code.<\/p>\n<p>This code works with the <code>:results<\/code> options <code>output<\/code>, <code>value<\/code> and <code>silent<\/code>. If <code>output<\/code> is specified, then everything that was outputted into the window will be added into the results section of the code block. If <code>value<\/code> is specified, then all output will still be displayed into the window, but only the resulting value will be added to the results section of the code block. If <code>silent<\/code> is specified, then all the output will still be displayed into the window, but nothing will be displayed in the results section of the code block.<\/p>\n<p>If the <code>:async<\/code> is omitted, then the normal behavior of <code>Org-babel-clojure<\/code> will be used, with the new timeout setting <code>org-babel-clojure-nrepl-timeout<\/code>.<\/p>\n<\/div>\n<\/div>\n<div id=\"outline-container-orgheadline6\" class=\"outline-3\">\n<h3 id=\"orgheadline6\">Call for help!<\/h3>\n<div id=\"text-orgheadline6\" class=\"outline-text-3\">\n<p>As I mentioned above, this is my attempt in coding something for Emacs using Elisp. There are certainly things that should be done differently. So if you have any Elisp and\/or Cider\/nREPL knowledge, and if you have some time to review this code, I am sure we could improve the usage of this function. The only thing I know is that such asynchronous capabilities of the Clojure code blocks is essential.<\/p>\n<p>There is one major area of improvement that I noted. Right now, the results comes asynchronously, but we still can&#8217;t use the Emacs instance to do other things (like writing in the Org-mode file while the process is running in background and results reported in this other buffer. Until this other issue is resolved, I don&#8217;t think we can say that this really makes <code>Org-babel-clojure<\/code> really 100% asynchronous. If this can be done (I did not have time to look into this yet), then I think the <code>:async<\/code> feature would be fully and properly integrated, but I am not yet sure if this is possible.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3>\u00c2\u00a0Sources<\/h3>\n<p>For the ones interested in this update of Org-babel-clojure, here is:<\/p>\n<ul>\n<li>The<a href=\"https:\/\/fgiasson.com\/blog\/wp-content\/uploads\/2016\/04\/using-clojure-in-org-mode.org\"> <code>Org-mode<\/code> file<\/a> of this blogpost which you can run to test the updated <code>org-babel-execute:clojure<\/code> function<\/li>\n<li>The <a href=\"https:\/\/fgiasson.com\/blog\/wp-content\/uploads\/2016\/04\/ob-clojure.el_.diff\"><code>diff<\/code> file<\/a> if you want to update your local <code>ob-clujure.el<\/code> file<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I recently started to get interested in Org-mode which was still unknown to me just a few weeks ago until I read this great article from Howard Abrams about literate programming using Org-mode. Initially I was wondering what this Emacs package was really about (it does all kind of things like document outlining (\u00c3\u00a0 la [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[251,279,277],"tags":[273],"class_list":["post-3176","post","type-post","status-publish","format-standard","hentry","category-clojure","category-emacs","category-literate-programming","tag-clojure-org-mode-literate-programming-notebook"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3176","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=3176"}],"version-history":[{"count":6,"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3176\/revisions"}],"predecessor-version":[{"id":3204,"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3176\/revisions\/3204"}],"wp:attachment":[{"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=3176"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=3176"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fgiasson.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=3176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}