Foreword

  • This article goes in assuming that you've read and have performed the steps found here

  • This article will show how to get further niceties using APL in org-babel source-blocks

  • I've been using this to learn APL using literate programming, the same as a jupyter session, but in emacs

  • This could also be used to write books and articles easily without needing to copy/paste output from RIDE

  • It will improve on that article in these aspects:

    • Glyph input :: Using dyalog-apl-input from =dyalog-mode=

    • Proper fontification :: previously I just had to turn off mixed-pitch-mode and have everything monospace, including prose (not good)

    • Syntax hilighting :: Also using dyalog-mode

Package installation

  • There's only one package to install, dyalog-mode (here)

  • Follow the installation steps in the README, then come back here to set up the functionality for org source blocks

Configuration

  • Now that dyalog-mode is installed, we can trick org-babel into giving us syntax hilighting from dyalog-mode, but execute using jupyter-apl (through the APL Jupyter kernel installed in my previous article)

  • When you enter the language for a source-block, org-babel infers what major-mode the code would normally run in

  • If you enter racket, say, as the language for a source-block, if org-src-fontify-natively is non-nil the function org-src-font-lock-fontify-block will spawn a buffer with the inferred major-mode (racket-mode) and display the block with the same syntax highlighting

  • From this you also get language-aware indentation and some other things the major mode provides

  • We will use dyalog as the language for our src-blocks, but since dyalog-mode doesn't let us execute those blocks, we will do that using jupyter-apl

  • We will create two 'cloned' functions that will run when we hit RET inside our dyalog src-blocks. They will call jupyter-apl to do the execution

  • Hopefully that explains the thought behind the following code we need:

(use-package! ob-eval
  :config
  ;; Here are our cloned functions
  (defun org-babel-execute:dyalog (body params)
    (org-babel-execute:jupyter-apl body params))

  (defun org-babel-dyalog-initiate-session (&optional arg1 arg2)
    (org-babel-jupyter-apl-initiate-session &optional arg1 arg2))

  (setq org-babel-default-header-args:jupyter-apl '((:kernel . "dyalog-kernel")
                                                    (:session . "*new*")
                                                    (:exports . "both")
                                                    (:eval . "never-export"))

        ;; copy jupyter-apl settings for `dyalog' blocks - which are really
        ;; jupyter-apl blocks with `dyalog' syntax hilighting
        org-babel-default-header-args:dyalog '((:kernel . "dyalog-kernel")
                                               (:session . "*new*")
                                               (:exports . "both")
                                               (:eval . "never-export"))))
  • As for using dyalog-apl-input, I just enable that manually for now using set-input-method

  • If you can't see dyalog-apl-input, just call load-library or require it in your config

Result

  • Here's what you should see when you create dyalog src-blocks in your .org files now:

  • To be clear, you need to enter:

#+begin_src: dyalog
<insane APL stuff>
#+end_src
  • The fancy hiding/presentation is from org-modern (here) and org-modern-indent (here), thank you to Daniel Mendler (minad) and jdtsmith for those wonderful packages

  • Also thanks to Joakim HÃ¥rsman for dyalog-mode, Dyalog company for dyalog-jupyter-kernel and to all the excellent people working on org-mode and emacs

Conclusion

  • I've been struggling with creating a comfortable environment for hacking on APL, but I think it's finally here

  • Of course we could just save all this time and these years of yak-shaving by simply using Jupyter, but where's the fun in that?