Icon for VAX OpenVMS 7.3

Icon for VAX OpenVMS 7.3

My VAXstations now have Icon: the University of Arizona’s Icon 9.0, the interpreter, the compiler and the program library, as a kit for OpenVMS VAX 7.3. Icon is the language in which an expression can produce a sequence of results and the system goes back to try the next one when a later part fails. There are no loops to write for a search, no regular expressions to learn for string work (strings are taken apart by scanning), and a short program usually does what a long one does elsewhere. The kit is a BACKUP saveset with a DCL installer and a DCL uninstaller; it needs nothing on the target but the tools every VMS has. Icon is in the public domain.

Claude Code assisted, which is to say, did much of the hard work. (As usual, lately.)

Downloads, with SHA-256 sums in SHA256SUMS.TXT:

Which Icon

Icon came out of the University of Arizona in the late 1970s, designed by Ralph Griswold, who had designed SNOBOL4 at Bell Labs with David Farber and Ivan Polonsky; it is the same family, with goal-directed evaluation in place of patterns. It has been in the public domain from the start. The DECUS tapes have the Icon Project’s VMS distributions of several versions; this kit is Version 9.0 for VMS of July 1994, “built and tested under VMS 6.0, and VAX C version 3.2” (its STATUS file), which I found on the DECUS LT94B tape. It is the last version in the archives that has VMS build procedures: Version 9.3 (1996/97) is there too, but for UNIX only, and I did not port it. Version 9.0 is also the version with the compiler (ICONC, which makes C) next to the interpreter.

The distribution’s prebuilt images need the DECwindows X library, because it was built with Icon’s graphics facilities; on a VAX with no DECwindows running the shipped ICONX.EXE stops with %SYSTEM-F-PROTINSTALL. So this kit is built from the sources without graphics (the Icon Project’s own instruction for that case, IPD250 step 3), natively, with Compaq C V6.4. I haven’t set up any GUI situation with my VAXen since I mostly use them remotely and via textual interface (sometimes with a real VT240, VT320, VT420, VT520 or VT525 even).

The licence is the Icon Project’s, and it is short enough to quote:

This material is in the public domain. You may use and copy this material freely. This privilege extends to modifications, although any modified version of this system given to a third party should clearly identify your modifications as well as the original source.

My changes are one deleted line (the graphics switch), four small changes to existing files and one new file, listed in SOURCES.TXT of the kit and as diffs in the source kit; they are mine, not the Icon Project’s.

What you get

$ @SYS$COMMON:[SYSLIB.ICON]ICON_SETUP
Icon 9.0 is ready: ICONT ICONX ICONC; HELP ICONT
$ iconx queens
4 queens:   2 solutions
5 queens:  10 solutions
6 queens:   4 solutions
7 queens:  40 solutions
8 queens:  92 solutions
first: 1 5 8 6 3 7 2 4
  • ICONT, the translator, and ICONX, the interpreter: ICONT hello makes HELLO.ICX, ICONX hello runs it; ICONT -x hello does both.
  • ICONC, the compiler: Icon to C, then the C compiler and the linker make a native .EXE (a compiled QUEENS is 139 blocks). It uses Compaq C, so the machine must have it; the interpreter needs nothing.
  • The Icon program library, 574 procedures and programs from the Icon Project’s contributors, translated, with IPATH set so that link numbers, strings finds them, plus their sources and data.
  • The distribution’s documents (the language report IPD236, the VMS notes IPD250 and IPD251, the compiler IPD237) and its help library: HELP ICONT, HELP ICONX, HELP ICONC.
  • callout() functions for VMS, the one addition (below).
  • The sources of all of it, as built.

ICON_SETUP.COM defines the commands and logical names for the process (ICON_BIN, ICON_IPL, ICONT, ICONX, ICONC, IPATH, the help library); nothing is system-wide, nothing in SYSUAF, STARLET or the startup files. ICON_UNINSTALL.COM removes exactly the files the install manifest records, and only if they still have the size and date recorded.

Installing

You need OpenVMS VAX 7.3, SYSTEM (or SYSPRV), and about 70,000 free blocks on the system disk while installing. No compiler (except for ICONC).

  1. Put the saveset and the two .COM files into one directory on the VAX. Transfer modes matter: the .BCK in binary, the .COM files in ASCII.

  2. A binary transfer loses the saveset’s record attributes; the installer puts them back itself:

     $ SET FILE/ATTRIBUTE=(RFM:FIX,LRL:32256,MRS:32256,RAT:NONE) -
           ICON_VAX_20261011.BCK
    
  3. As SYSTEM:

     $ @ICON_INSTALL
    

    It took 79 to 88 seconds on the simulator and 3 minutes 8 seconds on the VAXstation 4000/96, for 1,698 files.

  4. Each user, at the prompt or in LOGIN.COM:

     $ @SYS$COMMON:[SYSLIB.ICON]ICON_SETUP
    

@ICON_UNINSTALL CHECK says what an uninstall would remove, and @ICON_UNINSTALL does it.

Programs

Eleven programs, each with a DCL test; @RUN_TESTS translates, runs and checks them (PASS 13 of 13, with the compiler and library tests; 8 seconds on the simulator, 29 on the VAXstation 4000/96). The expected output of every program is computed in Python, independently, not copied from Icon; that found one real bug in one of our own programs (which is to say, one of Claude’s programs).

  • QUEENS: every solution of the n-queens problem, 4 to 8 (92 for 8), as one recursive generator: suspend (c := 1 to n) & safe(placed, k, c) & queens(n, k+1, put(copy(placed), c)). That is the whole backtracking search; the picture at the top of this post is its output.
  • WORDFREQ: word counts with a table and string scanning.
  • CALC: a recursive-descent calculator written by scanning, with arbitrary-precision integers (2 ^ 100, fact(30), a 20-digit product).
  • SUDOKU: a solver that always fills the cell with the fewest candidates; 52 search nodes for the Wikipedia puzzle, and the Python solver agrees.
  • COEXPR: co-expressions, the part of Icon that needs machine-specific code (a stack switch, in VAX MACRO, RSWITCH): pipelines, merging, producer and consumer.
  • LABNET: Dijkstra’s algorithm over the lab’s own machines.
  • RMSFILE: RMS files: write, append, read, sort, rename, delete.
  • VMSINFO and VMSCALL: VMS from Icon. VMSINFO asks DCL through pipes (open("WRITE SYS$OUTPUT F$GETSYI(...)", "rp")); VMSCALL calls $GETJPIW, $GETSYIW, $TRNLNM, $GETTIM/$ASCTIM and $GETMSG directly with callout("vms_getjpi", "USERNAME") and the like. Both are checked against DCL’s own lexical functions.
  • IPLTEST: library procedures (commas, roman, spell, rotate…).

VMSCALL uses the hook the interpreter has for external C functions: callout(name, args...) calls extcall(), which the distribution leaves as a stub that fails every call. The 250 lines of vmscall.c fill it in for VMS. The compiler does not have the hook.

Issues

  1. The saveset does not restore where IPD250 says. It holds directories nine levels deep, and the VMS BACKUP command refuses more than eight under a deep home directory (%BACKUP-I-INVDEEPDIR ... try rooted logical). Restore through a concealed root.
  2. Compaq C is not VAX C. It needs /STANDARD=VAXC for this 1994 code and then three things: <time.h> declares struct tms itself; the C library has its own getopt, optarg, optopt, popen and pclose (the link says multiply defined, and a write to the library’s read-only OPTOPT is an access violation); and one needs a compile flag that renames Icon’s.
  3. The shipped no-graphics link has a typo (XRGFSYS for XRGFXSYS), so the build IPD250 recommends for machines without DECwindows could not have worked.
  4. An undefined symbol had been in every build: init.r looks up a MAXMEM logical name through a variable that the configuration leaves out. It was harmless until somebody defined MAXMEM.
  5. A pipe started with open(cmd, "rp") inherits SYS$OUTPUT. If the test harness redirects it with DEFINE/USER, the subprocess’s output and the program’s own go into the same file. Icon’s own ">file" argument avoids it.
  6. system() returns the VMS status, 196609 (%X30001) for a success, not 1.
  7. Co-expressions nest only so far: a chain of 50 co-expressions, each activating the next, works; 75 ends in an access violation. The limit is the co-expression stack, COEXPSIZE, 2000 words by default; 8000 is good for at least 100.
  8. loadfunc() is UNIX only (dlopen); there is no dynamic loading of C functions on VMS in 9.0. callout() is the substitute.
  9. HELP ICON is the system’s ICONV help, not Icon’s: the kit’s help library answers HELP ICONT, HELP ICONX and HELP ICONC.

What I did not check

  • Real hardware, mostly. The kit was built and tested on a simulated MicroVAX 3900 (SIMH) running OpenVMS VAX V7.3. I then installed it system-wide on one real machine, my VAXstation 4000/96, and RUN_TESTS passed 13 of 13 there as an ordinary user. I have not run it on my 4000/60 or any other VAX. Simulator times say nothing about a real VAX except ratios (the install took about 2 times and the tests 3.6 times as long on the real machine as on the simulator; I did not investigate).
  • Graphics (the X Window facilities) are not built.
  • Speed: no benchmarks were run (IPD241 has the Icon Project’s benchmark procedure).
  • The compiler needs Compaq C (or VAX C) on the machine; compiling a program prints a harmless %CC-W-RESTRICTNOP warning from the run-time header. I compiled and ran one program with it, QUEENS.
  • The program library was translated and its test (IPLTEST) passes, but I did not run the Icon Project’s own tests ([V9.TESTS], “about 20 minutes for ICONT” in IPD250).

Rebuilding

REBUILD.md in the source kit has every command, in order, from the DECUS zip (hash given) to a tested kit. On the simulator: restoring the saveset 65 s; the interpreter, run-time library and compiler 7 min 30 s; the program library (574 translations and links) 2 min 7 s; the kit 36 s; the lifecycle test (install, refuse a second install, check, uninstall that keeps changed files, REPLACE, reinstall) 21 of 21 in 5 minutes. You need a VAX or SIMH with OpenVMS 7.3 and Compaq C; the only host-side tool is vmsbackup, optional, to look inside the saveset.

How this was done

As with Emacs, Perl and Poplog: Claude sessions with written briefs, on a VAXstation and a simulator, with the rule that nothing counts until a test shows it, and the transcripts kept. Every number above comes from one of those transcripts.

References

  • DECUS LT94B, icon/vms_icon_v9.zip (4-AUG-1994), via the Digiater mirror; also LT97A icon_v9_0_vms.zip.
  • IPD250 “Installing Version 9.0 of Icon under VMS” and IPD251 “Using Version 9.0 of Icon under VMS” (Gregg M. Townsend and Sandra L. Miller), IPD236 “Version 9.0 of the Icon Programming Language” (Griswold, Jeffery, Townsend), TR 90-8 “Icon-C interfaces” (the callout convention).
  • Ralph E. Griswold and Madge T. Griswold, The Icon Programming Language, 3rd edition, Peer-to-Peer Communications, 1996.
  • The Icon Project: https://www2.cs.arizona.edu/icon/ (not consulted for this work; the sources were local).

Credits: Ralph E. Griswold, Clinton L. Jeffery, Gregg M. Townsend, Sandra L. Miller and the Icon Project at the University of Arizona, who made Icon and put it in the public domain; the DECUS library, which kept the VMS distribution; and Claude Code (Anthropic’s Claude models) for much of the building, debugging, testing and writing.