プログラミング
PDP-1 Lisp (1960)を探る
Exploring PDP-1 Lisp (1960) (obsolescence.dev)
要約
この記事は、PDP-1 Lispの導入ガイドであり、1960年に14歳のピーター・ドイツによってPDP-1向けに実装された、Lispの初期のバージョンを紹介しています。Lispが対話型プログラミング環境とREPLの概念をどのように開拓し、当時のプログラミングに革命をもたらしたかを説明しています。記事では、PDP-1 Lispを起動し、基本的な操作を行い、紙テープからプログラムをロード・保存する方法を実践的に解説しています。
全文翻訳
DEC PDP-1でLISPをプログラミング:実践的な入門
目次
PDP-1 Lisp:はじめに
Lispの起動
ロードと保存
DDTのロードとLispプログラムへのアセンブリの混在
PDP-1 LispのためのAIチューター
作業中、PDP-1 LISPを私自身が学ぶにつれて修正されます。しかし、うまくいけば、これで始めることができるでしょう。Googleグループでのフィードバックは大歓迎です:-)
PDP-1 Lisp:はじめに
Lispは1958年にMITのジョン・マッカーシーによって開発されました。それはAI研究のために設計された、高水準でシンボリックなプログラミング言語を開拓しました。初期のLispは、再帰、シンボリック式、自動ストレージ管理などの重要な概念を導入しました。PDP-1版は1960年に、MIT教授の息子であるピーター・ドイツによって、当時14歳の高校生でありながら実装されました。それは、小さなPDP-1に適した、非常にミニマリストで効率的なLispです。特に、彼は読み込み-評価-印刷ループ(REPL、Pythonで私たちに有名)のアイデアをその過程で発明しました。つまり、これは史上初の対話型プログラミング環境であり、主要な革新であり、今日までLispの中心です。
PDP-1 Lispは、Lispを理論的なパンチカード読み込み言語から実用的で対話型のツールへと進化させました。それ自体がコンピューティングのマイルストーンです!このページでは、PDP-1 Lispのクイックスタート手順のみを提供します。Lispの知識は必要ありません。これはLispがPDP-1でどのように機能するかを示すだけです。Lispの世界への入り口として役立ち、Lisp自体についてもっと学びたくない場合でも興味深いものです。詳細に深く入り込む際には、2つのマニュアルが不可欠になります。1つ目はPDP-1 Lispマニュアル(リンク)、2つ目は、ドイツが彼のターゲットとして使用したIBM 7090用のオリジナルのフル機能Lisp 1.5プログラマーマニュアル(リンク)です。IBM Lisp 1.5マニュアルはLisp 1.5全般の優れた概要を提供し、PDP-1 LispマニュアルはPDP-1版の使用方法、実践的な操作、言語の違いを説明しています。更新:PiDP-1のGoogleグループでさらに2冊の本が推奨されました。最初の本はPDP-1でのLispを本当に開拓します:『The Programming Language LISP: Its Operation and Applications』。このページで実践的な事柄を「軌道に乗せた」後、最初に参照すべきものです。次に、『Anatomy of Lisp』と、その著者であるジョン・アレンと初期のLispに関する背景情報です。PDP-1 Lispは、私が最初に考えていたよりもはるかに魅力的です…しかし、まず、PDP-1 Lispの実践をざっと見てみましょう。
Lispの起動
Extendスイッチを設定します。
他のPDP-1プログラムのためにExtendスイッチを必ず下に戻してください。このスイッチが設定されていると、通常のPDP-1プログラムではREAD INが失敗し、忘れると大きな混乱の原因になります。
lisp.rimテープをマウントします。READ INを押します。
Lispストレージの上位メモリアドレスを定義するためにTWスイッチを7750に設定し、CONTINUEを押します。
プッシュダウンリストの長さを定義するためにTWスイッチを400に設定し、CONTINUEを押します。
タイプライター入力を有効にするためにSense Switch 5を設定します。3回目にCONTINUEを押します。
SS5が設定されていない場合、入力は新しく挿入された紙テープから行われます。したがって、Lisp関数が書かれた紙テープをマウントし、SS5を設定せずにContinueを押すこともできます。これについては後で説明します。これで、PDP-1のBasic Lispで作業できます!続行する前に知っておくべきこといくつか:
この時点で、常にAddress Switchesを0004に設定してください。Lispプログラムを実行した後、STARTとCONTINUEを押すだけでLispに戻れるからです。また、タイプミスやエラーがあるとLispは停止します。これは正常です。たとえば、「nil[space]」の代わりに「nix[space]」と入力します。このような状況では、STARTを押してからCONTINUEを押すだけです。ただし、Addressスイッチが開始位置の4を指していることを確認してください。
行はEnterキーではなく、閉じスペースを追加することで入力されます。したがって、定義されているアトミックシンボルを確認するには、「oblist [Space]」と入力します。入力する前に、Lispがまだ実行されているかどうかを確認することは常に役立ちます!「nil」と入力します。これはLispが実行されていなくても常にタイプアウトされます。しかし、Lispは新しい行に2番目の「nil」で応答するはずです。そうでない場合は:START、次にCONTINUE。おそらく、PDP-1 Lispで新しい何かを入力する前に、すばやく「nil」チェックをする習慣ができるでしょう。これは新しい行から始める最良の方法でもあります...
(plus 1 2)と入力すると3が出力されます。「+」ではなく「plus」であることに注意してください!(times 4 4)は正しく20を出力します。なぜなら、20八進数は十進数で16だからです...
次に、小さなプログラムを入力してみましょう(プログラムを入力するときは[Return]キーと[tab]キーを使用してください)。
```lisp
(prog (a b)
(setq a 4)
(setq b 4)
(plus a b)
(return (plus a b)))
```
...そして[space]で閉じます。これは10を返します。なぜなら、確かに4+4は八進数で10だからです:-)
ロードと保存
**紙テープ入力**
新しく作成したコードを紙テープに実際に保存するLisp関数は、Basic Lispに組み込まれていないため、最初にそのような関数を紙テープからロードする必要があります。これは、Lispでコードをロードする通常のやり方でもあります。
* 英数字テープlisp-defs.ptをマウントします。
* SS5を下げると、すぐにテープが読み込まれます。
* タイプライター出力に新しくロードされた関数が表示されます:`zerop pdef count`
* タイプライター入力に戻すため、SS5を上げます。
* STARTを押し、次にCONTINUEを押します。そして、Addressスイッチが確かに4に設定されていることを確認します。
これが、Lispコードをロードする一般的な方法です。関数が書かれた英数字テープをマウントし、SS5を設定すると、それらが読み込まれるのが見えます。
**独自の関数を読み込むためのテストテープを作成する**
まず、小さなテストテープを準備します。これをtest.lispというファイルにあなたのラップトップに貼り付けます。
```lisp
(rplacd (quote tt) (quote (expr (lambda () (prog () (print (quote hello)) (terpri) (return 5)))))) [space]
```
コードの最後の行にスペースがあることを確認して、関数を終了させます。次に、このテキストファイルから紙テープイメージを作成し、PDP-1に読み込みます。
```bash
encode_fiodec test.lisp test.pt
```
* 英数字テープtest.ptをマウントします。
* SS5を下げると、テープが読み込まれます。
* 次の出力が表示されます:`tt hello 5`
* タイプライター入力に戻すため、SS5を上げます。
* STARTを押し、次にCONTINUEを押します。そして、Addressスイッチが確かに4に設定されていることを確認します。
これで、今ロードされたプログラムを見ることができます。
```lisp
(print (cdr (quote tt)))
```
lisp-defs紙テープの内容:
```lisp
(rplacd (quote zerop) (quote (expr (lambda (n) (eq n 0)))))
(rplacd (quote pdef) (quote (fexpr (lambda (x a) (list (quote r placd) (list (quote quote) (car x)) (list (quote quote) (cdr (ca r x))))))))
(rplacd (quote count) (quote (expr (lambda (n) (prog (u) (setq u n) (cond ((zerop u) (return nil))) (print u) (setq u (plus u ( minus 1))) (go a))))))
```
**紙テープ出力**
(print (cdr (quote tt)))はプログラムの本体を表示しますが、関数定義は出力しません!言い換えれば、(rplacd (quote tt) (quoteは出力されません。しかし、実際のプログラム定義を紙テープに保存して、次回ロードできるようにしたいので、(print (cdr (quote tt)))をパンチするだけでは不十分です。解決策は、lisp-pdefsテープからロードした関数pdefです。
* タイプライターの代わりにパンチに送る出力をするためにSense Switch 3を上げます。
* (pdef tt)と入力し、いつものように末尾のスペース文字で終了すると、関数がテープにパンチアウトされるのが見えます。
* Sense Switch 3を下げてタイプライター入力に戻し、将来使用するために紙テープを保存します。
**結びの言葉...**
もちろん、PDP-1はコアメモリを使用しており、コアメモリは不揮発性です。したがって、P(i)DP-1をシャットダウンしても、次回電源を入れたときにすべてがメモリに残っています。紙テープからLispを再び起動する必要はありません。アドレススイッチを4に設定してSTARTを押し、次にCONTINUEを押すだけです。
脚注:より広範なlispFunctionsファイルはhttps://bitsavers.org/bits/DEC/pdp1/papertapeImages/20031216/lisp/lispFunctions.binにあります。まだテストされていませんが、多くの便利な関数が含まれています。
**DDTのロードとLispプログラムへのアセンブリの混在**
これについては、PDP-1 Lispマニュアル(リンク)を参照してください。Lispのトップアドレスを低く設定することで、DDTが配置される余地がトップにできます。そして、フロントパネルのSTARTスイッチを使用して、LispからDDTにジャンプできます。
**PDP-1 LispのためのAIチューター**
私たちは、ChatGPT、Claude Code、またはその他のAIにPDP-1 Lispについて学習し、あなたのプログラミングアシスタントになるように指示する、そのまま貼り付け可能な.mdテキストファイルを作成しました。試してみてください。