guide.org 7.5 KB

About

This section aims to provide the minimal steps required to get literate programming in org-mode working for GNU Guile.

Setup

Installing Emacs

We will use GNU Guix to create a reproducible environment, in which we will run Emacs, install Emacs packages and configure Emacs using Elisp code.

Reproducible Emacs using GNU Guix

Create manifest.scm

cat < manifest.scm (specifications->manifest '("gnutls" "guile" "bash" "emacs")) EOT

cat manifest.scm

:results: (specifications->manifest '("gnutls" "guile" "bash" "emacs")) :end:

Create channels.scm

guix describe --format='channels' > 'channels.scm' cat 'channels.scm'

:results: (list (channel (name 'guix) (url "https://git.savannah.gnu.org/git/guix.git") (branch "master") (commit "22d6e36005") (introduction (make-channel-introduction "9edb3f66fd" (openpgp-fingerprint "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) :end:

Install packages

command -V guile ls -al $(command -V guile)

# compare to guile installed in the environment created via guix shell:

guix time-machine \ --channels="channels.scm" -- \ shell \ --cores=8 \ --manifest="manifest.scm" -- \ which guile && ls -al $(which guile)

:results: guile is home/xiaolong.guix-profile/bin/guile lrwxrwxrwx 1 root root 65 Jan 1 1970 home/xiaolong.guix-profile/bin/guile -> gnu/store/1jgcbdzx2ss6xv59w55g3kr3x4935dfb-guile-3.0.8/bin/guile /gnu/store/abw05ikf9q0by8xp7g19hd7d7hj40cvi-profile/bin/guile lrwxrwxrwx 1 root root 65 Jan 1 1970 /home/xiaolong.guix-profile/bin/guile -> /gnu/store/1jgcbdzx2ss6xv59w55g3kr3x4935dfb-guile-3.0.8/bin/guile :end:

Command for running Emacs inside reproducible environment

guix time-machine \ --channels="channels.scm" -- \ shell \ --cores=8 \ --pure \ --container \ --network \ --no-cwd \ --preserve='TERM' \ --manifest="manifest.scm" -- \ emacs \ --no-init-file \ --no-site-file \ --no-site-lisp \ --no-splash \ --no-x-resources \ --no-desktop \ --no-loadup \ --no-window-system

Or with graphical window:

guix time-machine \ --channels="channels.scm" -- \ shell \ --cores=8 \ --pure \ --container \ --network \ --no-cwd \ --share=/tmp/.X11-unix \ --preserve='DISPLAY' \ --preserve='TERM' \ --manifest="manifest.scm" -- \ emacs \ --no-init-file \ --no-site-file \ --no-site-lisp \ --no-splash \ --no-x-resources \ --no-desktop \ --no-loadup

Installing required Emacs packages

Add melpa-stable package repository

To install geiser, we need to add the package repository, from which we can pull it.

Run the following elisp code:

(require 'package) ;; (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t) (package-initialize)

Install org

org is already installed. Not sure how to tell Emacs, that it should instead install org from GNU Elpa, so do this manually:

  • M-x list-pack RET
  • search for org from GNU Elpa
  • install org

Installing geiser-guile

As Elisp code:

(package-install 'geiser-guile)

Configuring Emacs using Elisp code

The following Elisp code needs to be evaluated, to be able to evaluate org source blocks of Scheme code using GNU Guile:

;; Tell Emacs to use the command `guile` to evaluate Scheme ;; code. (setq scheme-program-name "guile")

;; The following enables source blocks of specific ;; programming languages to be executed. By default only ;; elisp is allowed to be executed. First we define an ;; association list of languages to booleans, which enable ;; or disable support for a language. (setq org-babel-load-languages '((scheme . t)))

;; Then we use org-babel-do-load-languages to actually tell ;; org babel, that the languages should be supported. (org-babel-do-load-languages 'org-babel-load-languages '((scheme . t)))

;; The following defines a procedure, which determins, which ;; source blocks of programming languages can be run without ;; confirmation, depending on the language. The procedure ;; can then be used as org-confirm-babel-evaluate value. (defun xiaolong/org-confirm-babel-evaluate (lang body) (not (or (string= lang "scheme"))))

;; Set a procedure predicate for org babel, to determin, which languages can ;; be run without confirmation. (setq org-confirm-babel-evaluate 'xiaolong/org-confirm-babel-evaluate)

Test

Running geiser

Run geiser-guile using the following command:

M-x run-geiser RET

Since only geiser-guile is installed, this should start a Geiser Guile REPL.

Literate programming document

Now we should be all set to try some literate programming in Scheme.

Here is an example document:

cat example.org

,#+NAME: defmember ,#+begin_src scheme :noweb yes :results none :exports code :eval never-export :language guile (define member? (λ (a lat) (cond [(null? lat) #f] [else (or (eq? a (car lat)) (member? a (cdr lat)))]))) ,#+end_src

Lets test it:

,#+NAME: usemember ,#+begin_src scheme :noweb yes :results output :exports both :eval never-export <>

(display (simple-format #f "(member? 1 '(3 2 1)) -> ~a\n" (member? 1 '(3 2 1))))

(display (simple-format #f "(member? 1 '(3 2 4)) -> ~a\n" (member? 1 '(3 2 4)))) ,#+end_src

  1. Open a new =.org= file.
  2. Paste the example.org document into the buffer of the =.org= file.
  3. Place the cursor inside the usemember source block.
  4. Input C-c C-c to evaluate the source block.

Report

The above does not seem to work. The result of the example source block is merely the following:

Geiser Interpreter produced no output