How to get a nice output when calling jconsole?

433 views Asked by At

I've recently started to learn J. If find it useful when learning a new language to be able to quickly map a bit of source code to an output and store it for later reference in Emacs org-mode.

But I'm having trouble with the cryptic jconsole when I want to do the evaluation. For instance jconsole --help doesn't work. And man jconsole brings up something about a Java tool. Same applies to googling.

I have for instance this bit of code from the tutorial saved in temp.ijs:

m =. i. 3 4
1 { m
23 23 23 23 (1}) m

Now when I run jconsole < temp.ijs, the output is:

      4 5 6 7
    0  1  2  3
23 23 23 23
 8  9 10 11

Ideally, I'd like the output to be:

 4 5 6 7

 0  1  2  3
23 23 23 23
 8  9 10 11

Again, ideally I'd like to have this without changing the source code at all, i.e. just by passing some flag to jconsole. Is there a way to do this?

3

There are 3 answers

5
MPelletier On

The problem is with loose declarations. Every time you give the console a command, it replies with the answer. You should format your code in a verb and have it echo what you need.

foo =: 3 : 0
    m =. i. 3 4
    echo ''
    echo 1 { m
    echo ''
    echo 23 23 23 23 (1}) m
    ''
)
foo''

It can also be nameless and self executing if you're in a hurry:

3 : 0 ''
    m =. i. 3 4
    echo ''
    echo 1 { m
    echo ''
    echo 23 23 23 23 (1}) m
    ''
)
1
abo-abo On

I'm currently going with solving the problem on Emacs side, instead of on jconsole side. I intersperse the source code with echo'':

(defun org-babel-expand-body:J (body params)
  "Expand BODY according to PARAMS, return the expanded body."
  (mapconcat #'identity (split-string body "\n") "\necho''\n"))

Execute it like this:

(j-strip-whitespace
 (org-babel-eval
  (format "jconsole < %s" tmp-script-file) ""))

And post-process assuming that only first row of each array is misaligned (that has been my experience so far). Here's the result:

#+begin_src J
m =. i. 3 4
1 { m
23 23 23 23 (1}) m
#+end_src

#+RESULTS:
: 4 5 6 7
: 
:  0  1  2  3
: 23 23 23 23
:  8  9 10 11

And here's the post-processing code:

(defun whitespacep (str)
  (string-match "^ *$" str))
(defun match-second-space (s)
  (and (string-match "^ *[^ ]+\\( \\)" s)
       (match-beginning 1)))
(defun strip-leading-ws (s)
  (and (string-match "^ *\\([^ ].*\\)" s)
       (match-string 1 s)))
(defun j-print-block (x)
  (if (= 1 (length x))
      (strip-leading-ws (car x))
    ;; assume only first row misaligned
    (let ((n1 (match-second-space (car x)))
      (n2 (match-second-space (cadr x))))
      (setcar
       x
       (if (and n1 n2)
       (substring (car x) (- n1 n2))
     (strip-leading-ws (car x))))
      (mapconcat #'identity x "\n"))))
(defun j-strip-whitespace (str)
  (let ((strs (split-string str "\n" t))
    out cur s)
    (while (setq s (pop strs))
      (if (whitespacep s)
      (progn (push (nreverse cur) out)
         (setq cur))
    (push s cur)))
    (mapconcat #'j-print-block
           (delq nil (nreverse out))
       "\n\n"))) 
0
aks On

You need to use echo for explicit output, rather than rely on implicit output which is the case for the REPL function of jconsole normally.

Create the script, which I'm calling "tst2.js" below, and place the following code in it:

#!/Applications/j64/bin/jconsole
9!:7'+++++++++|-'
m =. i. 3 4
echo 1 { m
echo ''
echo 23 23 23 23 (1}) m
exit''

Of course, if your path to jconsole is different, then update the "shebang" line to be the actual path for your system.

Next, make sure the script is executable:

$ chmod +x tst2.js

or whatever you called your script.

Next, invoke it:

$ ./tst2.js
4 5 6 7

 0  1  2  3
23 23 23 23
 8  9 10 11

Note that the above output is identical to the output generated when you are in the interactive jconsole.