#:g1: 1960年の処理系 元祖LISP 1.5 を試してみる

Posted 2019-07-14 16:41:02 GMT

先日、LISP 1.5をお題にした、n月刊ラムダノート Vol.1, No.2(2019) / LISP 1.5の風景(川合史朗)が刊行されましたが、この稀にしか来ないLISP 1.5の波に乗らざるを得ない!!ということで、レトロコンピューティング好きの私は、十二年前に書いたLISP 1.5のエミュレータの記事をアップデートすることにしました。
(そういえばそもそも私はレトロコンピューター熱が高じてLispを始めたのでした)

上記記事ではエミュレータ関係のリンク切れ等が多くて、記事の内容を再現できない状態だったので、その辺りを修正しました。

なお、「LISP 1.5の風景」では、Gauche上にMeta*LISPというLISP 1.5の処理系を実装しつつLISPの原初を紐解いていくという内容なので、とてもお勧めです。

1960年の処理系 元祖LISP 1.5 を試してみる

先日は、PDP-1のエミュレータで、PDP-1 Lispを動かしてみましたが、やっぱり元祖である、LISP 1.5も動かしてみたいところ。
でも、さすがに、50年前のIBM7094の環境はかなり厳しいだろうと思いつつ、調べてみたら、なんとこれも簡単に動かせるようにまとめている方がいました。
約60年前の環境が再現できるというのは色々な意味で凄い。まず、データが保存されていて、今日のコンピュータで読めるってのが凄い。

lisp 1.5の環境がまとめられたファイルがあるのでダウンロードし、simhのibm7094で実行できるようにすればOKです。

手短にまとめると、準備するものとしては、

が必要です。

simhのi7094は、Debian GNU/Linuxや、Ubuntuであれば、

$ sudo apt install simh

でインストール可能です。

次にLISP 1.5環境の準備ですが、

$ tar xvf lisp15.tar.gz
$ cd lisp15
$ tar xvf utils-1.1.8.tar.gz
$ cd utils && make

とし、lisptape.ini! txt2bcd -s %1 scratch/lisp.job.mtというのを、! utils/txt2bcd -s %1 scratch/lisp.job.mtに書き換えます。
(txt2bcdをパスの通った所に設置しても良いですが)

上記のファイルを揃えて設定すれば、IBM 7094でLISP 1.5のバッチジョブを流せます。
しかし、若干面倒なので、Emacsのcompileを使って、バッチ処理のシェルスクリプトを起動させてみることにしました。
とはいえ、適当なでっち上げなので、試したい方は各自作成されると良いと思います。
自分の環境では、lisp1.5:loadというcompileをラップした関数と、シェルスクリプトの組み合わせで*compilation*バッファに結果が表示されるようにしてみました。

バッチ用シェルスクリプト(load-lisp1.5)

#!/bin/sh

INFILE=$1 EMUDIR=/l/lisp-1.5 # lisp 1.5セットのディレクトリを指定 TEM=cur.job

cd $EMUDIR pwd [ -f sys.log ] && rm sys.log printf " TEST FOO\n\n" > $TEM cat $INFILE >> $TEM printf "\n\nSTOP))) ))) ))) )))\n FIN END OF LISP RUN\n" >> $TEM i7094 lisptape.ini $TEM cat sys.log

Emacsのcompile関数をラップしたバッチ処理を呼び出す関数

(defun lisp1.5:load ()
  (interactive)
  (let ((compile-command (concat "~/bin/load-lisp1.5 " (buffer-file-name))))
    (compile compile-command)))

これで若干対話的にコードが書けるようになったので、適当に試してみます。

reverseとmapcarを作ってみる

define ((
(r1 (lambda (m l)
      (cond ((null l) m)
        ((quote t) (r1 (cons (car l) m) (cdr l))))))

(reverse (lambda (u) (r1 () u)))

(mapcar (lambda (lst fn) (prog (l res) (setq l lst) again (cond ((null l) (return (reverse res)))) (setq res (cons (fn (car l)) res)) (setq l (cdr l)) (go again)))) ))

mapcar((1 2 3 4) (quote (lambda (x) (plus 10 x))))

cond(((quote t) (print (quote hello))))

今日からみると色々変ったところが多いのですが、まず、トップレベルで関数に外側の括弧が付いてなかったりします。
これは、evalquoteと呼ばれるらしいですが、evalで評価するか、applyで評価するかと考えれば良い、と The Evolution of Lisp に書いてました。ちなみにInterlispでは、evalquoteの形式でコーディングできます。
それで、マニュアルを見る限りではreverseは標準で付いてくるっぽいのですが、見付からないので作ってみました。
mapcarの引数の順番が関数とリストとで逆ですが、元々は、リスト→関数の順番だったようです。これまたInterlisp系では、伝統に則ってCommon Lisp(Maclisp系)とは逆です。

結果

MTA: unit is read only
LPT: creating new file

HALT instruction, PC: 10524 (TRA 10523) Goodbye TAPE SYSTMP,B3

B3 IS NOW LISP SYSTMP. TAPE SYSTAP,A4

A4 IS NOW LISP SYSTAP. TAPE SYSPOT,A3

A3 IS NOW LISP SYSPOT. TAPE SYSPPT,A7

A7 IS NOW LISP SYSPPT. TEST WHATEVER

THE TIME ( 0/ 0 000.0) HAS COME, THE WALRUS SAID, TO TALK OF MANY THI NGS ..... -LEWIS CARROLL- EVALQUOTE OPERATOR AS OF 1 MARCH 1961. INPUT LISTS NOW BEING READ.

THE TIME ( 0/ 0 000.0) HAS COME, THE WALRUS SAID, TO TALK OF MANY THI NGS ..... -LEWIS CARROLL- FUNCTION EVALQUOTE HAS BEEN ENTERED, ARGUMENTS.. DEFINE

(((R1 (LAMBDA (M L) (COND ((NULL L) M) ((QUOTE T) (R1 (CONS (CAR L) M) (CDR L)))))) (REVERSE (LAMBDA (U) (R1 NIL U))) ( MAPCAR (LAMBDA (LST FN) (PROG (L RES) (SETQ L LST) AGAIN (COND ((NULL L ) (RETURN (REVERSE RES)))) (SETQ RES (CONS (FN ( CAR L)) RES)) (SETQ L (CDR L)) (GO AGAIN))))))

END OF EVALQUOTE, VALUE IS .. *TRUE*

FUNCTION EVALQUOTE HAS BEEN ENTERED, ARGUMENTS.. MAPCAR

((1 2 3 4) (QUOTE (LAMBDA (X) (PLUS 10 X))))

END OF EVALQUOTE, VALUE IS .. (11 12 13 14)

FUNCTION EVALQUOTE HAS BEEN ENTERED, ARGUMENTS.. COND

(((QUOTE T) (PRINT (QUOTE HELLO))))

HELLO

END OF EVALQUOTE, VALUE IS .. HELLO

THE TIME ( 0/ 0 000.0) HAS COME, THE WALRUS SAID, TO TALK OF MANY THI NGS ..... -LEWIS CARROLL- END OF EVALQUOTE OPERATOR FIN END OF LISP RUN

なんでか知りませんが、ルイス・キャロルの文言が引用されてたりします。
若干わかりづらいですが、END OF EVALQUOTE, VALUE IS ..の後が評価結果です。なんとなく良い味を醸し出しています。
やっぱり手近に処理系があって手軽に試せるというのは良い!

PDFのマニュアルもあるので、これを見ながらLISP 1.5を探索してみるのも面白いと思います。


HTML generated by 3bmd in LispWorks 7.0.0

comments powered by Disqus