From org file with local bibtex to LaTeX and PDF

Screenshot of orgmode source, PDF preview on the right, interactive citation selection in the minibuffer. Click for full resolution.

I have (co-)written a few LaTeX documents in my time.

However, as I have been writing my life and lab notes and many of my technical blog posts in Emacs orgmode for the past few years, I wanted to see how one would go about using BiBTeX references in orgmode files (using John Kitchin’s org-ref package) such that they would render correctly in orgmode’s export LaTeX and PDF.

My use case is of course slightly different than the norm: I maintain my master bibliography using the wonderful Zotero software, and I prefer exporting document-specific BiBTeX files from that main database.

This post shows you how to do it.


  • Make sure that latexmk is installed on your system. This is one of the easiest ways to make sure that pdflatex and bibtex are executed in the correct sequence, and a sufficient number of times.
  • With M-x package-install RET org-ref install the org-ref package. This will enable interactive selection and insertion of bibtex references from your local bib file.
  • You should also have the ox-latex Emacs package installed. This is what gives orgmode its LaTeX output powers.

Emacs setup

In your init.el somewhere, use the following code to ensure that the orgmode LaTeX exporter invokes latexmk in the correct way:

(setq org-latex-pdf-process
    '("latexmk -pdflatex='pdflatex -interaction nonstopmode' -pdf -bibtex -f %f"))

A minimal but complete orgmode example

The usual org-ref workflow is that you use it to manage a single main BiBTeX file, which is configured in your init.el. As mentioned above, I prefer using small document-specific BiBTeX files.

This is what the first three lines sets up using an Emacs file variable. Note that the local bib file is specified without quotes of any kind. Also, because there’s no path specified, it lives together with the orgmode document itself, which I prefer.

# Local Variables:
# org-ref-default-bibliography: local-bibtex-file.bib
# End:

After this, I have two LaTeX-specific lines ensuring that the output PDF looks prettier than default. You can thank me later.

The third LATEX_HEADER line imports the natbib package, which means I have extra cite commands to differentiate between for example textual citing (the first example) and parenthetical citing (the second example).

#+LATEX_CLASS_OPTIONS: [a4paper, 11pt, colorlinks=true, citecolor=., linkcolor=black, urlcolor=black]
#+LATEX_HEADER: \usepackage{fourier}
#+LATEX_HEADER: \usepackage{natbib}

#+TITLE: Example orgmode to LaTeX

* Introduction

  This is that really difficult intro spection, as was also
  demonstrated by cite:huang_identification_2016.

* Conclusions

  This is the even more difficult final section. We will now use a
  parenthetical citation citep:meyer_four-level_2012.

Finally, very importantly, I have the orgmode orgmode markup to select a suitable bibliography style, and again to specify the bib file. This will get automatically translated to the suitable LaTeX or even HTML versions.

Putting it all together

With something like the example above in your orgmode file, and a suitable bib-file, you can do C-c C-e l o to export to LaTeX, execute the latexmk command we specified above, and view the PDF.

In the screenshot at the start of this post, you can see what this looks like on my setup. I am using PDFTools for viewing the PDF inside of Emacs (this gets updated automatically whenever I rebuild the PDF).

You can also see the ivy-based completion as I’m in the process of interactively inserting a new citation into the document.

The default helm-based completion is more attractive, but it takes over the whole display, which is why I made use of ivy for instruction’s sake.

mu4e 0.9.18: E-Mailing with Emacs now even better.

In this post I talk about three great new features in the latest release of mu4e, an email programme that runs in Emacs. I also show my mu4e configuration as an example to others who would like a similar setup.

mu4e 0.9.18 screenshot showing selected context (bottom right of main) and visual-line-mode (long lines) which is activated by the format=flowed support.

After recently discovering that plaintext format=flowed in Thunderbird works only partially, it was time to check back in on mu4e after my previous happy stint using it.

I was pleasantly surprised to see that mu4e development had been quite active, and that this Emacs mail user agent had acquired a number of highly useful new features.

Three features I find particularly interesting are:

Full and deterministic format=flowed support

As I explained in another blog post, format=flowed is a really clever extension to old-school plain text emails that enables any receiving mail app that supports the standard to reflow emails for better display on smaller or larger displays.

mu4e now has first-class and deterministic support of the format=flowed feature.

I do understand that HTML has won the email format war.

However, HTML formatting gives users entirely too much freedom when writing their emails, resulting in misguided typesetting and other unnecessary visual elements, analogous to and just as irritating as chart junk, that regularly damage sensitive eyes.

This is why I prefer writing in plain text. With reliable format=flowed support, mu4e enables me to focus on the content whilst fixing plain-text email’s only real flaw: Reflowing on mobile devices.

Compose emails in a separate window

This, just like anything else, one could previously implement by oneself in emacs-lisp. However, it’s now a welcome core feature activated via the mu4e-compose-in-new-frame variable.

When you press C to compose a new email, a separate frame (this is what Emacs calls a window) is opened. After sending the email with C-c C-c the frame is automatically closed.


In my previous setup, I had made a bunch of emacs-lisp functions to switch between different email identities (from addresses).

This worked, but it was not nearly as convenient and well thought-out as mu4e’s new contexts.

I now have a separate context defined for each email identity. I can switch between them using ; followed by the self-configured shortcut character.

They also activate automatically based on a configurable match function, for example examining the destination address of an email I am replying to. My configuration example below shows this in a little more detail.

My configuration

Because of these new features and a number of other changes, I put together this new configuration from scratch based on mu4e’s excellent documentation and examples.

I am still using `offlineimap` to synchronise my email with the IMAP server (fastmail in my case), but I’m currently sending email using the Emacs smtpmail package.

Here is a slightly shortened and simplified version of my configuration:

;; I installed mu4e from the 0.9.18 tarball
;; this is where make install put the emacs bits
(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu4e")

(require 'mu4e)

;; I want my format=flowed thank you very much
;; mu4e sets up visual-line-mode and also fill (M-q) to do the right thing
;; each paragraph is a single long line; at sending, emacs will add the
;; special line continuation characters.
(setq mu4e-compose-format-flowed t)

;; every new email composition gets its own frame! (window)
(setq mu4e-compose-in-new-frame t)

;; give me ISO(ish) format date-time stamps in the header list
(setq mu4e-headers-date-format "%Y-%m-%d %H:%M")

;; show full addresses in view message (instead of just names)
;; toggle per name with M-RET
(setq mu4e-view-show-addresses 't)

;; path to our Maildir directory
(setq mu4e-maildir "~/Maildir")

;; the next are relative to `mu4e-maildir'
;; instead of strings, they can be functions too, see
;; their docstring or the chapter 'Dynamic folders'
(setq mu4e-sent-folder   "/Sent"
      mu4e-drafts-folder "/Drafts"
      mu4e-trash-folder  "/Trash")

;; the maildirs you use frequently; access them with 'j' ('jump')
(setq   mu4e-maildir-shortcuts
    '(("/Archive"     . ?a)
      ("/INBOX"       . ?i)
      ("/Sent"        . ?s)))

;; the list of all of my e-mail addresses
(setq mu4e-user-mail-address-list '(""

;; the headers to show in the headers list -- a pair of a field
;; and its width, with `nil' meaning 'unlimited'
;; (better only use that for the last field.
;; These are the defaults:
(setq mu4e-headers-fields
    '( (:date          .  25)    ;; alternatively, use :human-date
       (:flags         .   6)
       (:from          .  22)
       (:subject       .  nil))) ;; alternatively, use :thread-subject

;; program to get mail; alternatives are 'fetchmail', 'getmail'
;; isync or your own shellscript. called when 'U' is pressed in
;; main view.

;; If you get your mail without an explicit command,
;; use "true" for the command (this is the default)
;; when I press U in the main view, or C-c C-u elsewhere,
;; this command is called, followed by the mu indexer
(setq mu4e-get-mail-command "offlineimap")

;; not using smtp-async yet
;; some of these variables will get overridden by the contexts
 send-mail-function 'smtpmail-send-it
 message-send-mail-function 'smtpmail-send-it
 smtpmail-smtp-server ""
 smtpmail-smtp-service 465
 smtpmail-stream-type 'ssl

;; don't keep message buffers around
(setq message-kill-buffer-on-exit t)

;; here come the contexts
;; I have about 5 of these, chopped down to 2 for demonstration purposes
;; each context can set any number of variables (see :vars)
;; for example below here I'm using two different SMTP servers depending on identity
(setq mu4e-contexts
      `( ,(make-mu4e-context
           :name "c"
           :enter-func (lambda () (mu4e-message "Enter context"))
           :leave-func (lambda () (mu4e-message "Leave context"))
           ;; we match based on the contact-fields of the message (that we are replying to)
           :match-func (lambda (msg)
                         (when msg 
                           (mu4e-message-contact-field-matches msg 
                                                               :to "")))
           :vars '( ( user-mail-address      . ""  )
                    ( user-full-name         . "Charl P. Botha" )
                    ( smtpmail-smtp-server   . "" )
                    ( mu4e-compose-signature .
                                              "dr. charl p. botha\n"

           :name "s"
           :enter-func (lambda () (mu4e-message "Enter context"))
           ;; no leave-func
           ;; we match based on the contact-fields of the message
           :match-func (lambda (msg)
                         (when msg 
                           (mu4e-message-contact-field-matches msg 
                                                               :to "")))
           :vars '( ( user-mail-address       . "" )
                    ( user-full-name          . "Charl P. Botha" )
                    ( smtpmail-smtp-server    . "" )
                    ( mu4e-compose-signature  .
                                               "Dr. Charl P. Botha\n"
                                               "Science Officer :: Stone Three Venture Technology\n"


;; start with the first (default) context; 
(setq mu4e-context-policy 'pick-first)

;; compose with the current context if no context matches;
(setq mu4e-compose-context-policy nil)

;; these are the standard mu4e search bookmarks
;; I've only added the fourth one to pull up flagged emails in my inbox
;; I sometimes use this to shortlist emails I need to get around to ASAP
(setq mu4e-bookmarks
  `( ,(make-mu4e-bookmark
       :name  "Unread messages"
       :query "flag:unread AND NOT flag:trashed"
       :key ?u)
       :name "Today's messages"
       :query ""
       :key ?t)
       :name "Last 7 days"
       :query ""
       :key ?w)
       :name "Flagged in INBOX"
       :query "maildir:\"/INBOX\" and flag:flagged"
       :key ?f)))


This is currently running smoothly on two of my Linux workstations as well as my early 2015 retina MacBook Pro.

The general setup procedure is to install offlineimap using pip2 install --user offlineimap (the offlineimap configuration file hasn’t changed much since the previous post), run offlineimap for the first time, then build and install mu4e from its tarball, and finally to run mu index to initialise the index.

After this, your mail, and plain-text nirvana, is a simple M-x mu4e away.

Date-sorted interactive recursive search with ivy, counsel and ag

A core part of my note-taking strategy is a growing collection of Emacs Org mode files containing my monthly lab journals, project summaries and various technical documents.

Usually I rely on Projectile’s Helm integration to perform recursive searches with The Silver Searcher (ag) using helm-projectile-ag (trigged by the completely muscle-memorised C-c p s s) through all of the org files in my notes hierarchy. Recursive regular expression search results are shown interactively as you type. Wonderful!

However, recently I found that I really missed the ability to see my search results sorted by last modified date, so that the most recently touched files would show up first. For a chronological notes database, this sorting makes the most sense.

A few frustrating hours later, interspersed with bouts of seriously pondering the exact nature of my relationship with Emacs, I managed to attain the desired result using the Emacs packages ivy and counsel.

Although I’m sticking with Helm for the rest, in this case the ivy API made it much simpler to do what I needed to do. It is understandable that this is not a straight-forward endeavour, as ag is heavily parallelised and furthermore is handled asynchronously by both helm and ivy / counsel. Sorting the results slows matters down, but for this specific case the slowdown is a reasonable price to pay.

Read on for more detail.

Video demo of end result

If you follow the instruction below, you too will be able to achieve the following feats of recall:

Search results are returned as I type, as is usually the case with counsel-ag and helm-ag. However, they are now sorted by file modified date, last modified file at the top. This usually means I find what I need faster.

Show me the code

The ivy-read function (this is ivy’s single API entrypoint) has two required parameters, one of which is the collection. This is a function returning the list of items that the user wants to narrow down, or the list itself.

Because we need to tell ivy to sort the results by associating a sorting function with a specific collection function, we wrap the supplied counsel-ag-function collection function.

We also supply a new sorting function that will take two of the ag-generated search results, each of the form relative_filename:line_number:line_contents, derive the filenames from that, determine the modified timestamps of both the files and then return t or nil depending on which file is newer.

We finally (for this first snippet) associate the sorting function with our wrapped collection function.

(defun cpb/ag-collection (string)
  "Search for pattern STRING using ag.
We only have this as a separate function so we can assoc with sort function."
  ;; this will use counsel--async-command to run asynchronously
  (counsel-ag-function string ""))

;; modified from
;; * directory to counsel--git-grep-dir: that's where AG is working
;; * removed directory logic: ag returns files
;; * parsed out filename from ag results
(defun eh-ivy-sort-file-by-mtime (x y)
  "Determine if AG sort result X is newer than Y."
  (let* ((x (concat counsel--git-grep-dir (car (split-string x ":"))))
         (y (concat counsel--git-grep-dir (car (split-string y ":"))))
         (x-mtime (nth 5 (file-attributes x)))
         (y-mtime (nth 5 (file-attributes y))))
    (time-less-p y-mtime x-mtime)))

(add-to-list 'ivy-sort-functions-alist
             '(cpb/ag-collection . eh-ivy-sort-file-by-mtime))

In the second and final snippet, we create a new version of the counsel-ag function where we specify our own collection function, and we supply a truthful :sort argument.

(defun cpb/counsel-ag (&optional initial-input initial-directory
                                 extra-ag-args ag-prompt)
  "Grep for a string in the current directory using ag.
INITIAL-INPUT can be given as the initial minibuffer input.
INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'.
AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.

Modified by cpbotha: Sort results last modified file first."
   (list nil
         (when current-prefix-arg
           (read-directory-name (concat
                                 (car (split-string counsel-ag-base-command))
                                 " in directory: ")))))
  (ivy-set-prompt 'counsel-ag counsel-prompt-function)
  (setq counsel--git-grep-dir (or initial-directory default-directory))
  (ivy-read (or ag-prompt (car (split-string counsel-ag-base-command)))
            ;; specify collection function so we can assoc with sort function
            :initial-input initial-input
            :dynamic-collection t
            ;; yes, we want to sort the results
            :sort t
            :keymap counsel-ag-map
            :history 'counsel-git-grep-history
            :action #'counsel-git-grep-action
            :unwind (lambda ()
            :caller 'cpb/counsel-ag))


You can invoke cpb/counsel-ag interactively to search from the current directory, or you can point it at a directory of your choosing by passing in the initial-directory argument.

In my Emacs initialisation, I have bound another wrapper function that invokes cpb/counsel-ag on my notes directory, so I can instantly search through my notes in reverse chronological order.

I believe that my relationship with Emacs is safe for now.

Step-by-step guide to C++ navigation and completion with Emacs and the Clang-based rtags

If you want C++ completion and navigation (jump to definition, jump to declaration, and so forth), there are several good options for Emacs. For a QtQuick / C++ project I’m working on, I needed the best Emacs has to offer.

This turned out to be the Clang-based rtags system.

Rtags is not the easiest of the options to get going, hence this short tutorial. I initially configured irony-mode, which is also Clang-based and was significantly easier to get going, but it soon started hanging on the completion of for example QStringList methods in my project. Because it also doesn’t support navigation, I decided to try rtags. So far, rtags has been working quite well on a Qt 5.x project of slightly under 200K lines of C++.


On Ubuntu 14.04, I tested this with both libclang-3.6-dev from the standard repos and with libclang-3.8-dev from the LLVM repos. CMake should also be installed.

On OSX 10.11 (El Capitan), homebrew took care of the dependencies for me (see next step).

Get and build rtags

From the documentation, simply clone the rtags repo and build it:

git clone --recursive
cd rtags

Make a compilation database for your project

rtags needs a compilation database file, usually called compile_commands.json, to figure out what compile options were used to compile which source files. If your project is using cmake, you only have to add the -DCMAKE_EXPORT_COMPILE_COMMANDS=1 to the cmake invocation to generate that file.

In my case, and perhaps in yours, you have to use something else like Qt’s qmake system. In this case, you can use a tool like Build Ear (BEAR) or the Python-rewrite of scan-build. In both cases, you invoke the utility with your normal build command. In my Qt project, I do:

bear --append make -j16

As your project builds, bear will capture all of the compilation commands and put them in compile_commands.json. With my project, the compile_commands.json finds itself in the out-of-source (shadow) build directory.

(The first time, you have to do this after a clean, or a make clean, so all of the compile commands can be captured.)

BEAR is preferable, but on the latest OSX with its new system integrity protection (SIP) and on some linuxes, it won’t work and you’ll end up with an empty compilation database. In these cases, use the intercept-build command from the scan-build package linked above.

Start the rtags daemon RDM

You can do this from emacs, but due to better system process handling, I invoke this from a normal terminal:

cd /where/you/built/rtags/bin
nohup ./rdm &

When working with rtags, always make sure that RDM is running.

Tell RDM about your project using RC

rc is the rtags command one uses to communicate with the rtags daemon RDM.

Importantly, make sure that rc is in your path.

We only have to tell RDM once about the location of any new project. Do this as follows:

cd /your/project/source
rc -J /dir/containing/compile_commands.json/

Note that the -J parameter is the directory containing the compile_commands.json file.

Configure your Emacs

Install the Emacs rtags package:

M-x package-install RET rtags RET

Make sure that you also have the company package installed.

Next, add the following to your Emacs init.el:

;; ensure that we use only rtags checking
(defun setup-flycheck-rtags ()
  (flycheck-select-checker 'rtags)
  ;; RTags creates more accurate overlays.
  (setq-local flycheck-highlighting-mode nil)
  (setq-local flycheck-check-syntax-automatically nil))

;; only run this if rtags is installed
(when (require 'rtags nil :noerror)
  ;; make sure you have company-mode installed
  (require 'company)
  (define-key c-mode-base-map (kbd "M-.")
    (function rtags-find-symbol-at-point))
  (define-key c-mode-base-map (kbd "M-,")
    (function rtags-find-references-at-point))
  ;; disable prelude's use of C-c r, as this is the rtags keyboard prefix
  (define-key prelude-mode-map (kbd "C-c r") nil)
  ;; install standard rtags keybindings. Do M-. on the symbol below to
  ;; jump to definition and see the keybindings.
  ;; comment this out if you don't have or don't use helm
  (setq rtags-use-helm t)
  ;; company completion setup
  (setq rtags-autostart-diagnostics t)
  (setq rtags-completions-enabled t)
  (push 'company-rtags company-backends)
  (define-key c-mode-base-map (kbd "<C-tab>") (function company-complete))
  ;; use rtags flycheck mode -- clang warnings shown inline
  (require 'flycheck-rtags)
  ;; c-mode-common-hook is also called by c++-mode
  (add-hook 'c-mode-common-hook #'setup-flycheck-rtags))

You can either just eval this new code, or restart your emacs.

Using rtags

I mostly use M-. to jump to any symbol’s definition. Pressing M-. again will jump to and fro between definition and declaration. Use =M-,= to see all references to the symbol under the cursor. This is where Helm comes in especially useful.

Use C-c r [ and C-c r ] to jump backwards and forwards through the position stack that rtags builds up as you jump between symbols. You can use C-c r I to get a list of rtags-extracted symbols in the current file, although semantic-mode with helm (C-c h i) gives you slightly less accurate but more colourful results. I use both.

As you type, company-mode will usually interrupt after you’ve entered the first three characters of a symbol or member. I can’t wait that long, so I press C-tab to get a list of completions immediately.

As an additional bonus, you’ll see Clang warnings indicated in bright red (usually) in your code window!

As you’re working, remember to do builds with bear --append as shown above. I do this via M-x compile. rdm will pick up all changes and re-analyse files as you work!

Conclusions and other rambling

I am quite impressed by how well rtags works on complex C++ projects! It is indeed clang under the hood, but rtags has overcome the considerable challenge of exposing this to Emacs in a robust and usable fashion.

With this setup, I am able to take longer breaks from using QtCreator, which I don’t like very much. QtCreator has great potential, but unfortunately its Emacs keyboard emulation is sorely lacking (this could be forgiven) and as a general C++ IDE it still has a long way to go in the usability department. I remain optimistic that with competition like JetBrains (when I’m not in Emacs, I’m in something by JetBrains; their Emacs emulation is bearable!) out there, QtCreator will improve over time.

Feel free to join the discussion in the comments below or on the reddit topic!

Up and running with ECL and Emacs SLIME in four easy steps

ECL is of course Embeddable Common Lisp, a small but quite complete Common Lisp implementation that can be easily embedded in your C applications to act as dynamic extension language, but it is also a fine stand-alone implementation. It includes an interpreter and a compiler, and can even produce compact binaries. Read this blog post by Chris Kohlhepp for a brief and practical overview.

SLIME is the Superior Lisp Interaction Mode for Emacs, a great Emacs environment within which one can write code for a number of Common Lisp implementations.

I had to consult a number of different sources to get SLIME and ECL working on OSX (El Capitan) using homebrew, so I’ve decided to put it all together in this short howto.

(This post assumes you have homebrew and Emacs installed. For Emacs on OSX, I usually just do brew install --cocoa --srgb emacs. Thanks to user Aidenn0 on reddit for the reminder to mention the emacs install!)

Step 1: Install XCode command-line tools

I use this MacBook for development with XCode, so I would not have thought this step necessary. Without it however, your SLIME will break at startup during the ECL compile of the SWANK slime server due to Clang not being able to find the gmp.h file. The error looks something like this:

In file included from /usr/local/Cellar/ecl/16.0.0/include/ecl/ecl-cmp.h:22:
In file included from /usr/local/Cellar/ecl/16.0.0/include/ecl/ecl.h:35:
/usr/local/Cellar/ecl/16.0.0/include/ecl/config.h:56:10: fatal error: 'gmp.h' file not found
#include "gmp.h"
1 error generated.

This is all the more infuriating, because homebrew does install the GMP header file in /usr/local/include as a dependency of ECL (see later).

Furthermore, at first start SLIME will hence display an infinite number of polling messages in your minibuffer, as it can’t connect to the SWANK server that ECL should have compiled.

If you install the xcode command-line tools by typing the following in a term and following the prompts:

xcode-select --install

… the clang compiler will henceforth also search in /usr/local/include, avoiding the error above when you startup slime for the first time.

Step 2: Install ECL

Install ECL using homebrew. This will also pull down and install gmp:

brew install ecl

Step 3: Install and configure SLIME

In Emacs, install the SLIME package by doing M-x package-install RET slime RET

After having done this, add the following two lines to your Emacs init.el:

(setq inferior-lisp-program "ecl")
(setq slime-contribs '(slime-fancy))

Without that second line, starting slime will only get you an *inferior-lisp* buffer, and not the *slime-repl ECL* that you deserve!

You can either eval those two lines and then continue with the next step, or restart Emacs if you’re the restarting type. (too much Windows can do that to you)

Step 4: Fire up the SLIME!

In Emacs, do M-x slime RET, at which point you should find yourself in a lovely *slime-repl ECL* buffer, where you can talk to the inferior Lisp process (it’s being modest, because it’s actually superior) with syntax completion, real-time code documentation and other niceties.

You can now enter some Lisp code in a new .lisp buffer, for example something like this:

(defun harmonic_tr (n accum)
  "tail-recursive harmonic function - cpb"
  (if (<= n 1) (+ accum 1)
      (harmonic_tr (- n 1) (+ accum (/ 1.0 n)))))

(time (loop for i from 1 to 10 collect (harmonic_tr 1000000 0)))

You can now put your cursor anywhere on the harmonic_tr function, and press C-c C-c (M-x slime-compile-defun), and then on the time loop (hehe), to have it calculate the millionth harmonic number ten times. As you do this, various outputs will appear in the REPL. You can also switch to the REPL, and continue experimenting with your newly defined functions over there.

Why the harmonic number?

This specific function is due to some completely-for-fun micro-benchmarks I did in 2005 with OCaml, Octave, Python, Pyrex (what later became Cython), and C to compare with Lush. Then I used the harmonic number, because that’s what Lush had on its website as a demonstration of Lush’s looping speed.

Fast forward 10 years, and on this early 2015 MacBook Pro with a 2.7GHz i5 and Embeddable Common Lisp (ECL) 16.0.0 I get 0.0736 seconds per call to harmonic_tr(1000000), averaged over 10 calls. The loop version does marginally better.

For comparison, the straight Python 3.5.1 loop code does 0.1187, a tail-recursive version in Guile 2.0.11 Scheme does 0.0904 seconds (ask me in the comments if you’d like to see this), the clang -O3 loop code in C does 0.0033, and PyPy 2.6.0 on the Python code does 0.0024 seconds.

This micro-benchmark is fun, but do remember that when you’re embedding a dynamic language, you are usually focusing not only on raw performance, but on other matters like the language’s expressivity and, more importantly, on the best impedance match for you extension writer and their domain.