J Source Code Blocks in Org Mode

Table of Contents

Org Mode support for J

Introduction

J is a modern, high-level, general-purpose, high-performance programming language. J is portable and runs on Windows, Unix, Mac, both as a GUI and in a console. J systems can be installed and distributed for free.

J source code blocks in Org Mode can be used to perform calculations, plot graphs and produce reproducible research papers.

Requirements and Setup

J source code blocks in Org Mode require a working J installation. Precompiled binary distributions for Gnu/Linux, Mac OS X, and Windows are available at the http://www.jsoftware.com/stable.htm. The source can be found at http://www.jsoftware.com/source.htm. After the installation, make sure that jconsole executable is in your path (and that it's actually the J console, not some Java thing).

For :session evaluation, j-mode package is required. It's available in MELPA and links to https://github.com/zellio/j-mode. Note that the package in Marmalade is different at the moment.

Finally, you'll need to ensure that org-babel-load-languages includes an entry for J. Typically, org-babel-load-languages will contain many entries. The example below omits other languages.

(org-babel-do-load-languages
 'org-babel-load-languages
 '((J . t)))

Org Mode Features for J Source Code Blocks

Header Arguments

There are no J-specific default header arguments.

There are no J-specific header arguments.

Sessions

Sessions are fully supported by J source code blocks. They can be used as one way to preserve state accessed by several source code blocks. Sessions are also useful for debugging, since it is possible to view the values of variables created during the session.

Result Types

Only basic text output is supported.

Examples of Use

Hello World!

#+begin_src J :exports both
'Hello , World!'
#+end_src
#+RESULTS:
: Hello , World!

Common uses

plot a graph

Note that in order for this to work, plot libarary has to be installed. You can install it on Linux by running jgtk and selecting the menu Tools/Package Manager. Afterwards, the experience is similar to synaptic. This should plot a sine. On my system, it creates a plot.png file and opens it in a browser.

#+begin_src J
load 'plot'
plot 1 o. 0.1 * i.200
#+end_src

mini-SQL

Suppose we have two tables

#+begin_src SQL
CREATE TABLE Customers (ID INT, Name TEXT, Age INT, Salary INT)
CREATE TABLE Orders (OID INT,  Date  DATETIME,  CustomerID INT, Amount INT)
#+end_src

And here's the query that we'd like to perform:

#+begin_src SQL
SELECT * FROM Orders o
INNER JOIN Customers c ON o.CustomerID = c.ID AND o.Amount < 2000
#+end_src
  • API implementation
    #+begin_src J :session
    createTable =: [:|:,.&a:
    union =: ([:{.[),:[:([:<[:;]#~~:&a:)"1([:{:[),.([:{:]){~([:{.])i.[:{.[
    insert =: [union[:({.,:([:([:<[:(]$~[:1&,#)>)"0{:))[:|:[:>]
    rows =: {.([:<,:)"1 1[:|:[:([:<"1[:,.>)"0{:
    value =: [:(]`{.@.([:1&=#))[:,[:>[((([:<[)=[:{.])#[:{:])[:>]
    pr =: [:,[:(([:>[)(([:<([:>[),.[:>])"0 0)"0 1[:>])/[:([:<[:rows>)"0]
    join =: 1 : '((([:{.[:>{.),:[:([:<(>"0))"1[:{:[:1 2 0&|:[:>([:,u"0)#]) (pr y))'
    #+end_src
    
  • Create and fill the tables
    #+begin_src J :session :exports both
    [Customers =: createTable 'ID';'Name';'Age';'Salary'
    [Orders =: createTable 'OID';'Date';'CustomerID';'Amount'
    
    Customers =: Customers insert (<'ID'; 1),(<'Name'; 'Ramesh'),(<'Age'; 32),(<'Salary'; 2000)
    Customers =: Customers insert (<'ID'; 2),(<'Name'; 'Khilan'),(<'Age'; 25),(<'Salary'; 1500)
    Customers =: Customers insert (<'ID'; 3),(<'Name'; 'kaushik'),(<'Age'; 23),(<'Salary'; 2000)
    Customers =: Customers insert (<'ID'; 4),(<'Name'; 'Chaitali'),(<'Age'; 25),(<'Salary'; 6500)
    Customers =: Customers insert (<'ID'; 5),(<'Name'; 'Hardik'),(<'Age'; 27),(<'Salary'; 8500)
    Customers =: Customers insert (<'ID'; 6),(<'Name'; 'Komal'),(<'Age'; 22),(<'Salary'; 4500)
    Customers =: Customers insert (<'ID'; 7),(<'Name'; 'Muffy'),(<'Age'; 24),(<'Salary'; 10000)
    
    Orders =: Orders insert (<'OID'; 102),(<'Date'; '2009-10-08'),(<'CustomerID'; 3),(<'Amount'; 3000)
    Orders =: Orders insert (<'OID'; 100),(<'Date'; '2009-10-08'),(<'CustomerID'; 3),(<'Amount'; 1500)
    Orders =: Orders insert (<'OID'; 101),(<'Date'; '2009-11-20'),(<'CustomerID'; 2),(<'Amount'; 1560)
    Orders =: Orders insert (<'OID'; 103),(<'Date'; '2008-05-20'),(<'CustomerID'; 4),(<'Amount'; 2060)
    Customers
    Orders
    #+end_src
    
    #+RESULTS:
    #+begin_example
    ┌──┬────┬───┬──────┐
    │ID│Name│Age│Salary│
    ├──┼────┼───┼──────┤
    │  │    │   │      │
    └──┴────┴───┴──────┘
    
    ┌───┬────┬──────────┬──────┐
    │OID│Date│CustomerID│Amount│
    ├───┼────┼──────────┼──────┤
    │   │    │          │      │
    └───┴────┴──────────┴──────┘
    
    ┌──┬────────┬───┬──────┐
    │ID│Name    │Age│Salary│
    ├──┼────────┼───┼──────┤
    │1 │Ramesh  │32 │ 2000 │
    │2 │Khilan  │25 │ 1500 │
    │3 │kaushik │23 │ 2000 │
    │4 │Chaitali│25 │ 6500 │
    │5 │Hardik  │27 │ 8500 │
    │6 │Komal   │22 │ 4500 │
    │7 │Muffy   │24 │10000 │
    └──┴────────┴───┴──────┘
    
    ┌───┬──────────┬──────────┬──────┐
    │OID│Date      │CustomerID│Amount│
    ├───┼──────────┼──────────┼──────┤
    │102│2009-10-08│3         │3000  │
    │100│2009-10-08│3         │1500  │
    │101│2009-11-20│2         │1560  │
    │103│2008-05-20│4         │2060  │
    └───┴──────────┴──────────┴──────┘
    #+end_example
    
  • The query
    #+begin_src J :session :exports both
    (([:2000&>'Amount'&value)*.'CustomerID'&value='ID'&value) join Customers; < Orders
    #+end_src
    
    #+RESULTS:
    ┌──┬────────┬───┬──────┬───┬──────────┬──────────┬──────┐
    │ID│Name    │Age│Salary│OID│Date      │CustomerID│Amount│
    ├──┼────────┼───┼──────┼───┼──────────┼──────────┼──────┤
    │2 │Khilan  │25 │1500  │101│2009-11-20│2         │1560  │
    │3 │kaushik │23 │2000  │100│2009-10-08│3         │1500  │
    └──┴────────┴───┴──────┴───┴──────────┴──────────┴──────┘
    

Sudoku solver

Note that this takes a few seconds to solve. Hence this example not suitable for :session use, since session has a set limit of 0.1 seconds to wait for jconsole to print something and then copy that output to org.

#+begin_src J :exports both
i =: ,((,|:)i.9 9),,./,./i.4$3
c =: (#=[:#~.)@-.&0
t =: [:(([:*/_9:c\])"1#])i&{+"1 1(>:i.9)*/[:i&=i.&0
r =: [:,`$:@.(0:e.,)[:;(<@t)"1
s =: 9 9&$@r@,
]m =: 9 9 $"."0'200370009009200007001004002050000800008000900006000040900100500800007600400089001'
s m
#+end_src
#+RESULTS:
#+begin_example
2 0 0 3 7 0 0 0 9
0 0 9 2 0 0 0 0 7
0 0 1 0 0 4 0 0 2
0 5 0 0 0 0 8 0 0
0 0 8 0 0 0 9 0 0
0 0 6 0 0 0 0 4 0
9 0 0 1 0 0 5 0 0
8 0 0 0 0 7 6 0 0
4 0 0 0 8 9 0 0 1

2 8 4 3 7 5 1 6 9
6 3 9 2 1 8 4 5 7
5 7 1 9 6 4 3 8 2
1 5 2 4 9 6 8 7 3
3 4 8 7 5 2 9 1 6
7 9 6 8 3 1 2 4 5
9 6 7 1 4 3 5 2 8
8 1 3 5 2 7 6 9 4
4 2 5 6 8 9 7 3 1
#+end_example

Documentation from the http://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.