Monday, May 19, 2008

SML hacking tip: installing on Ubuntu x86_64 by manual transfer from i386

Note: Narrowly targeted Google-food. Skip if you do not program in Standard ML.

Update 2010-05-05: As of Lucid, SML/NJ is now available on 64-bit. So you should probably just upgrade.

Ubuntu x86_64 does not have smlnj (the Standard ML of New Jersey (SML/NJ) distribution); nor does SML/NJ currently build out-of-the-box on Ubuntu x86_64. I elide here a long, dull story about trying to build it --- using 32-bit libraries, etc. --- and cut to the chase: ultimately, I installed it on a 32-bit Ubuntu box, and then manually transferred the files over.

In general, I almost never install software on my Linux box unless it's either (a) completely managed by my packaging system or (b) can be removed by simply rm -Rf /some/directory. Fortunately, SML/NJ more or less satisfies (b).

Assuming you have both a 32-bit Ubuntu install and a 64-bit Ubuntu install available, the transfer process is straightforward. The only trickiness is that there's no simple way to get all SML/NJ packages and libraries at once, so you'll have to apt-get several times if you want a "batteries included" installation.

Steps (unless otherwise noted, perform all these commands on your 32-bit machine):

  • sudo apt-get install smlnj
  • Optionally, do apt-cache search smlnj and install as many of the resulting lib*-smlnj libraries as you want.
  • Optionally, install the following extra packages:
    • ml-lpt ("language processing tools"; includes ml-ulex and ml-antlr)
    • ml-yacc (ML-Yacc)
    These are particularly of interest because probably 90% of ML programmers are also programming language hackers of one stripe or another. (Note that, annoyingly, these packages do not have smlnj as a substring of the package name. And, of course, apt-cache search ml yields a huge fusillade of results because "ml" is a common substring. Couldn't they at least use sml-* or better yet standard-ml-*? Blech.)
  • cd /usr/lib
  • tar -czvf smlnj.tar.gz smlnj
  • Copy the tarball smlnj.tar.gz to your target machine of choice and untar it under /usr/lib
  • pushd /usr/bin && tar -czvf ~/smlnj-scripts.tar.gz `dpkg -L smlnj smlnj-runtime ml-lpt ml-yacc |cut -b 10-` && popd
  • Copy the tarball smlnj-scripts.tar.gz to your target machine, and untar it under a binary directory on your PATH. (I have $HOME/bin in my PATH for user-local executables, so I put it there.)

As far as I can tell, everything works.

Saturday, May 17, 2008

SML hacking tip: fix uncaught exception BadAnchor

Note: Narrowly targeted Google-food. Skip if you do not program in Standard ML.

If you use the Standard ML of New Jersey (smlnj) compilation manager (CM), then you will sometimes get error messages like this:

[bad plugin name: anchor $y-ext.cm not defined]

uncaught exception BadAnchor
  raised at: ../cm/paths/srcpath.sml:436.16-436.25
             ../cm/util/safeio.sml:41.55
             ../cm/util/safeio.sml:41.55
             ../cm/util/safeio.sml:41.55
             ../cm/parse/parse.sml:502.47
/usr/lib/smlnj/bin/sml: Fatal error -- Uncaught exception BadAnchor with 0
 raised at ../cm/paths/srcpath.sml:436.16-436.25

make: *** [default] Error 1

This is CM's way of telling you that it encountered a line in your *.cm that has an extension that it does not understand. In this case, it's a file with a .y extension.

The fix is to correct the file extension (if it was a typo), or perhaps to update to a version of CM that understands the file extension you're using.

In my case, I had been hacking with an ages-old version of SML/NJ, and recently updated to the version in Ubuntu 8.04 (a.k.a. Hardy). Apparently non-ancient versions of SML/NJ expect ML-Yacc files to be named with the extension .grm instead of .y. I renamed my Yacc file, updated sources.cm, and all was well.