UP | HOME

Support via Liberapay

Org-babel-Oz

Org-babel support for Oz

Introduction

org-babel-oz extends org-babel by support for executing Oz source code. Oz code is executed by sending it to the Oz Programming Environment (OPI), the Emacs mode and compiler interface for Oz programs.

Oz distinguishes between statements and expressions. org-babel-oz supports both of them, but the org-babel header argument :results must be set accordingly. :results output requires the respective code block to be an Oz statement and :results value requires an Oz expression. org-babel inserts the result of expressions automatically into an org buffer, as usual. A statement has no result (i.e. the result of :results output is always nil), but it can produce output as a side effect (e.g., use the Oz browser or output a file).

The OPI keeps running in the background between executing multiple code blocks (e.g., it remembers variable values). Therefore, org-babel-oz always runs in session mode (the org-babel :session header argument is ignored). In practice, non-session code blocks are handled equally well by the session mode. However, only a single session is supported.

Expression evaluation happens synchronously. Therefore there is an additional header argument :wait-time <number>, which specifies the maximum time to wait for the result of a given expression. nil means to wait as long as it takes to get a result (potentially wait forever).

Requirements

org-babel-oz requires the Mozart Programming System. Mozart is the implementation of the Oz programming language (http://www.mozart-oz.org/), which includes the major mode mozart for editing Oz programs.

Enabling org-babel-oz

Add the following to your ~/.emacs file.

(require 'ob-oz)

Feeding statements with :results output

The top-level expression of a typical Oz program is a statement (not an expression). The following code block calls the Oz browser for printing the Oz atom 'Hello org-babel!' (as usual, execute the block with C-c C-c).

#+begin_src oz :results output
  {Browse 'Hello org-babel!'}
#+end_src

This code does not return anything (no result is shown in the org buffer) – it only feeds a statement to the OPI compiler. Note that :results output is a required header argument (the default is :results value).

Feeding expressions and getting back results with :results value

Oz expressions are executed with the org-babel header argument :results value. org-babel inserts the the result of an expression into an org buffer, as usual.

#+begin_src oz :results value
  39 + 3
#+end_src
42

Oz does not distinguish between lists of integers and strings. The interface is currently set to output virtual strings "as is". This approach works fine for plain strings, on the one hand. …

#+begin_src oz :results value
  "Bla"
#+end_src
Bla

…, and for concatenated virtual strings, on the other hand.

#+begin_src oz :results value
  foo#bar
#+end_src
foobar

However, list of integers are translated into the corresponding string by org-babel.

#+begin_src oz :results value
  [60 61 62 63]
#+end_src
<=>?

As a workaround, a list of integers can explicitly be translated into a string.

#+begin_src oz :results value
  {Value.toVirtualString [60 61 62 63]
   100 100}
#+end_src
[60 61 62 63]

Nested data structures are supported as well. However, they are not pretty printed.

#+begin_src oz :results value
  seq([note(duration:2
            pitch:60
            amplitude:80)
       note(duration:2
            pitch:64
            amplitude:60)
       note(duration:2
            pitch:67
            amplitude:50)
       note(duration:6
            pitch:72
            amplitude:100)]
      startTime: 0
      timeUnits: beats(4))
#+end_src
seq([note(amplitude:80 duration:2 pitch:60) note(amplitude:60 duration:2 pitch:64) note(amplitude:50 duration:2 pitch:67) note(amplitude:100 duration:6 pitch:72)] startTime:0 timeUnits:beats(4))

Oz objects without a literal representation are returned as they would be shown, e.g., in the Oz emulator. This example creates a Strasheela score object (so Strasheela must be installed).

#+begin_src oz :results value
  {Score.make seq
   unit}
#+end_src
<O: Sequential>

Org-babel variables

Code blocks can contain variables in org-babel that are bound with the code block header argument :var. The variable syntax must comply with the syntax of variables for the programming language in question. Oz variables always start with a capital letter.

Variables can also be bound with the result of Emacs lisp code. In the following example, the path of the directory of the present file is browsed.

#+begin_src oz :results output :var Path=(format "'%s%s'" (file-name-directory (buffer-file-name)) "")
{Browse Path}
#+end_src

Any Oz code can be expressed by wrapping it into an (Emacs lisp) string. In the following example, the variable Foo is bound to the (result of the) Oz expression 2+3.

#+begin_src oz :results output :var Foo="2+3"
{Browse Foo}
#+end_src

Another use for variables is for the Library of Babel. When the following code block is executed (C-c C-c), it calls the code block browse defined below. Arguments must be valid binding statements for Oz variables (e.g., X=3).

#+lob: browse(X=3)
#+lob: browse(X="This is a test")

You can see in the Oz Compiler buffer the actual Oz code generated from such calls (org-babel-oz automatically surrounds the code block by a local statement, i.e. declares these variables).

#+name: browse(X)
#+begin_src oz
  {Browse X}
#+end_src

Multiple variables are separated by commas (which is org-babel and not Oz syntax).

#+lob: browse2(X=3, Y=7)
#+name: browse2(X, Y)
#+begin_src oz :results output
  {Browse X#Y}
#+end_src

Literate example

Org-babel supports literate programming, and org-babel-oz inherits this functionality. An example is shown below. The following code block contains the code <<declaration>>, which expands to the code block named declaration shown below. Code blocks with such noweb syntax require the header argument :noweb yes. Interactive execution of literate programs that are split into multiple chunks works like the interactive execution plain code blocks (i.e. using C-c C-c)

#+begin_src oz :results output :tangle LP-test :noweb yes
  <<declaration>>
  {Browse X+Y}
#+end_src

A complete Oz source file combining code chucks is created when calling org-babel-tangle. The a resulting file name (without extension) is given to the header argument :tangle.

Following is the named code block declaration, which is used as a chunk in this literate programming example. Note that the order of code block definitions is not the order in which these code blocks (chunks) appear in the resulting program!

#+name: declaration
#+begin_src oz :results output
  declare
  X = 7
  Y = 3
#+end_src

TODO Ideas for Improving Literate Programming Support of Org-Babel

  • Important: the names of literate programming code blocks must appear in the exported files (e.g., HTML), otherwise the resulting literate program is incomprehensible (e.g., using a notation like = <code>). These code names should likely be created automatically, but there seems to be also no strait-forward manual way to name code blocks (e.g., #+CAPTION: does not work for code blocks).
  • Important: every "call" to a code block (e.g., ) should somehow directly link to its definition (e.g., HTML link, or ref to section number)
  • Less important: Noweb syntax of chord block insertion is also valid Oz syntax (macro call) – the different should be somehow made clear to avoid confusion

Session-based evaluation

As mentioned above, org-babel-oz always runs in session mode. Sessions can consist of statements and expressions. In the following statement, the variable X is declared.

#+begin_src oz :results output
  declare
  X = 7
#+end_src

In a later code block, the variable X is browsed (also a statement).

#+begin_src oz :results output
  {Browse X}
#+end_src

The value of this variable can also be returned (expression).

#+begin_src oz :results value
  X
#+end_src
7

Inline source blocks

The following code example is only shown in the source, while the export contains the result: . Nevertheless, the code can also be evaluated interactively.

Handling Oz Exceptions

In case an Oz statement results in an exception, then this exception is shown in the Oz Compiler buffer, as usual (it does not block the Oz compiler).

#+begin_src oz :results output
  {Bla} % undefined procedure
#+end_src

For Oz expressions that result in an exception, the exception is shown and additionally the result error returned.

#+begin_src oz :results value
   1 div 0 % division by 0 error
#+end_src
error

Note that some exceptions are not caught by the Oz interface and thus block Emacs. In the following example, the variable Bla is not declared and Emacs is blocked for the default value of the header argument :wait-time (1 sec).

#+begin_src oz :results value
   Bla
#+end_src

Bugs

While evaluating Oz statements with :results output is stable, evaluating Oz expressions with :results value is not. In particular, when Oz is halted and restarted, then [sometimes?] the connection between org-babel-oz and Oz is broken. Workaround: execute the Emacs Lisp code (org-babel-oz-create-socket) (problem: "Address already in use").

Whenever an Oz expression is evaluated (:results value), the printing of the result is delayed by one evaluation. In other words, if the expression is changed and re-evaluated, then the result of the previous evaluation is inserted into the buffer and so forth.

Documentation from the orgmode.org/worg/ website (either in its HTML format or in its Org format) is licensed under the GNU Free Documentation License version 1.3 or later. The code examples and css stylesheets are licensed under the GNU General Public License v3 or later.