Literate Programming in org-babel (ob-clojure.el) is broken under nrepl.el

499 views
Skip to first unread message

lambdatronic

unread,
Sep 6, 2012, 12:42:05 PM9/6/12
to clo...@googlegroups.com
For those people (like myself) who do a lot of Literate Programming in Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is somewhat non-trivial. This is because the existing Clojure support in org-babel (ob-clojure.el) relies on slime and swank-clojure when running org-babel-execute-src-block (which redirects to org-babel-execute:clojure in ob-clojure.el).

So clearly this is actually an issue for both nrepl.el and ob-clojure.el, not simply one or the other. All the same, I've hacked together a simple workaround that fixes the problem and makes Literate Programming under nrepl possible once again. If there is some slick way this could be worked into nrepl.el's codebase that wouldn't break its existing behavior (as this does), I'd be excited to see it.

Here we go:

;; Patch result table rendering bug in ob-clojure (NREPL version)
(defun nrepl-send-request-sync (request)
  "Send a request to the backend synchronously (discouraged).
The result is a plist with keys :value, :stderr and :stdout."
  (with-current-buffer "*nrepl-connection*"
    (setq nrepl-sync-response nil)
    (nrepl-send-request request (nrepl-sync-request-handler (current-buffer)))
    (while (not (plist-get nrepl-sync-response :done))
      (accept-process-output))
    nrepl-sync-response))

(defun org-babel-execute:clojure (body params)
  "Execute a block of Clojure code with Babel."
  (let ((result-plist (nrepl-send-string-sync (org-babel-expand-body:clojure body params) nrepl-buffer-ns))
        (result-type  (cdr (assoc :result-type params))))
    (org-babel-script-escape
     (cond ((eq result-type 'value)  (plist-get result-plist :value))
           ((eq result-type 'output) (plist-get result-plist :value))
           (t                        (message "Unknown :results type!"))))))

Have fun!

Tim King

unread,
Sep 6, 2012, 1:09:55 PM9/6/12
to clo...@googlegroups.com
On Thu, Sep 6, 2012 at 9:42 AM, lambdatronic <gwjo...@uvm.edu> wrote:
For those people (like myself) who do a lot of Literate Programming in Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is somewhat non-trivial. This is because the existing Clojure support in org-babel (ob-clojure.el) relies on slime and swank-clojure when running org-babel-execute-src-block (which redirects to org-babel-execute:clojure in ob-clojure.el).

So clearly this is actually an issue for both nrepl.el and ob-clojure.el, not simply one or the other. All the same, I've hacked together a simple workaround that fixes the problem and makes Literate Programming under nrepl possible once again. If there is some slick way this could be worked into nrepl.el's codebase that wouldn't break its existing behavior (as this does), I'd be excited to see it.


Hi,
You may want to check out the below thread... there has been some recent activity in this area and nrepl.el 0.1.4-preview should have better support for org-babel.


Cheers,
Tim

lambdatronic

unread,
Sep 7, 2012, 9:45:44 AM9/7/12
to clo...@googlegroups.com
Thanks, Tim. This looks great.

For those of you who don't want to go digging through the thread, here's the summary:

Step 1. Download nrepl-0.1.4-preview from Marmalade or MELPA (depends on clojure-mode 1.11).

Step 2. Add this code to your .emacs file:

;; Patch ob-clojure to work with nrepl
(declare-function nrepl-send-string-sync "ext:nrepl" (code &optional ns))

(defun org-babel-execute:clojure (body params)
  "Execute a block of Clojure code with Babel."
  (require 'nrepl)
  (with-temp-buffer
    (insert (org-babel-expand-body:clojure body params))
    ((lambda (result)
       (let ((result-params (cdr (assoc :result-params params))))
         (if (or (member "scalar" result-params)
                 (member "verbatim" result-params))
             result
           (condition-case nil (org-babel-script-escape result)
             (error result)))))
     (plist-get (nrepl-send-string-sync
                 (buffer-substring-no-properties (point-min) (point-max))
                 (cdr (assoc :package params)))
                :value))))

Step 3. Get Literate!
 

Denis Labaye

unread,
Sep 8, 2012, 4:24:26 AM9/8/12
to clo...@googlegroups.com
It seems to be very interesting, I am already using Emacs / org-mode / clojure a lot, I was aware of org-babel, but never used it.
Would you have a simple example project (on github, ...) on how to bootstrap this ? 

Thanks, 

Denis

 

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Gary Johnson

unread,
Sep 11, 2012, 4:13:55 PM9/11/12
to clo...@googlegroups.com
I just put together a simple example repo on GitHub, containing a literate programming solution to the Potter Kata  (http://codingdojo.org/cgi-bin/wiki.pl?KataPotter) using Emacs' org-babel mode. You can check it out here:

  https://github.com/lambdatronic/org-babel-example

Also be sure to take a look at the canonical online org-babel docs:


In particular the intro section:


And even though it's a little bit dated w.r.t. the current org-mode version in Emacs 24, this journal article on Org-Mode's literate programming and reproducible research features is really, really cool to work through (lots of nice code examples):


Happy hacking,
  ~Gary

Giorgio Valoti

unread,
Sep 8, 2012, 4:05:21 AM9/8/12
to clo...@googlegroups.com
Il giorno 07/set/2012, alle ore 15:45, lambdatronic ha scritto:

Thanks, Tim. This looks great.

For those of you who don't want to go digging through the thread, here's the summary:

Step 1. Download nrepl-0.1.4-preview from Marmalade or MELPA (depends on clojure-mode 1.11).

Step 2. Add this code to your .emacs file:

Thank you! Will your patch be needed from now on to use Org with nrepl?

[…]

--
Giorgio Valoti

Denis Labaye

unread,
Sep 12, 2012, 5:10:20 AM9/12/12
to clo...@googlegroups.com
On Tue, Sep 11, 2012 at 10:13 PM, Gary Johnson <gwjo...@uvm.edu> wrote:
I just put together a simple example repo on GitHub, containing a literate programming solution to the Potter Kata  (http://codingdojo.org/cgi-bin/wiki.pl?KataPotter) using Emacs' org-babel mode. You can check it out here:

  https://github.com/lambdatronic/org-babel-example

Also be sure to take a look at the canonical online org-babel docs:


In particular the intro section:


And even though it's a little bit dated w.r.t. the current org-mode version in Emacs 24, this journal article on Org-Mode's literate programming and reproducible research features is really, really cool to work through (lots of nice code examples):


Happy hacking,
  ~Gary


That's very cool, great example !

Thanks 

Ben Mabey

unread,
Sep 12, 2012, 11:29:07 PM9/12/12
to clo...@googlegroups.com
Thanks for the great example Gary!  I've been meaning to try org-babel out for a while but never got around to it.

I just tried your example and when I run org-babel-tangle the code blocks are not expanded into the source file, but rather the code block names are just inserted into the source destination (e.g. <<find-discounted-subsets>> instead of the actual function).  Any ideas on what may be wrong?  Do you have global settings that are perhaps making the tangle work differently on your setup?  I was able to export the document to HTML just fine and execute the clojure code, so the only issue appears to be tangling.

I'm using Emacs 24 and the only org specific code I have is applying your provided patch after requiring ob-clojure.

Thanks again for the example,
Ben

Ben Mabey

unread,
Sep 12, 2012, 11:46:04 PM9/12/12
to clo...@googlegroups.com
On 9/12/12 9:29 PM, Ben Mabey wrote:
Thanks for the great example Gary!  I've been meaning to try org-babel out for a while but never got around to it.

I just tried your example and when I run org-babel-tangle the code blocks are not expanded into the source file, but rather the code block names are just inserted into the source destination (e.g. <<find-discounted-subsets>> instead of the actual function).  Any ideas on what may be wrong?  Do you have global settings that are perhaps making the tangle work differently on your setup?  I was able to export the document to HTML just fine and execute the clojure code, so the only issue appears to be tangling.

I found the problem was a missing :noweb argument:

https://github.com/lambdatronic/org-babel-example/pull/1

Gary Johnson

unread,
Sep 14, 2012, 5:58:42 PM9/14/12
to clo...@googlegroups.com
Yep. Thanks for the patch, Ben. I had set org-babel-default-header-args:clojure to '((:noweb . "tangle")) in my .emacs, so I was getting the benefit of automatic noweb expansion when tangling (but not weaving). It's all fun and games until you break someone else's setup!  ;)

  ~Gary
Reply all
Reply to author
Forward
0 new messages