SchemeのコードもCと同じようにエディタで編集します。ファイルの拡張子は「.scm」としてください。
Cでは、コードを書いても実行するにはコンパイルが必要でした。通常、Schemeのコードは、Cのようにコンパイルを経ずに、処理系の中で実行されます。処理系とは、プログラムコードを読み込んで実行し、その結果を表示するプログラムのことです。処理系を使う場合、コンパイルの必要はなく、コードは逐次的に実行され、最適化などはあまり行われません。
この演習では、Guileという処理系を使用します。ターミナルでGuileを使うには、以下のコマンドを実行します。
guile
これで、Schemeの処理系が起動しました。ここで、Schemeの式を入力してReturnキーを押すと、式がGuile内で実行されます。コンパイルなしに式がすぐに実行されるという点と、出力の命令がなくても実行結果が自動的に表示される点が処理系の特徴です。例えば、次の式を入力してみましょう。計算結果がすぐに表示されるのが分かります。「100」と表示されれば成功です。
(+ (- (* (* 1 2) 3) (* 4 5)) (+ (* 6 7) (* 8 9)))
Schemeでは、プログラマはCのように明示的にメモリ管理をすることはできませんが、プログラム中で不要になったメモリ領域は処理系が勝手に再利用してくれます。このような仕組みをGC(garbage collection)と呼びます。
処理系が動いている間は、何度でも式を入力することができます。定義した変数は、処理系が止まるまで有効です。処理系を終了するには、処理系内で以下の式を実行します。(実は、EOFを入力しても同様の効果があります。)
(exit)
一度処理系を終了してしまうと、それまで処理系に入力した内容は忘れられてしまいます。もう一度Guileを起動しても、過去に定義した変数を使うことはできません。長時間の使用で処理系の挙動がおかしくなったら、一度リセットする意味で処理系を再起動するのも悪くはありません。
Guileが反応しなくなったと感じたら、controlを押しながらdを押してみてください。(連打するとシェルまで終了してしまうかも知れませんが。)それでも反応がなかったら、閉じ括弧「)」を何個か入力してからreturnを押してください。それでもダメならTAを呼びましょう。
Guileはデフォルトでは入力の履歴を保持しない設定になっています。試しにguileを実行して上矢印キーを押してみると前回入力した行が補完されるわけではなく、単に「^[[A」という謎の文字列が表示されてしまいます。シェルと同じようにGuileに履歴を保持させるには、シェルで以下のコマンドを入力します。その後、Guileを動かすと、履歴が使えるようになっています。
echo '(use-modules (ice-9 readline)) (activate-readline)' > ~/.guile
コマンドの意味が分かる人には自明ですが、このコマンドはマシンごとに1度の実行で十分です。ECCSでは、どこかのマシンで1度実行しておけば、以後どのマシンでログインしても自動的に有効になります。
ただし、履歴機能が有効になると補完機能も自動的に有効になります。補完はタブを入力すると行われるので、タブの入ったコードをペーストで入力する場合にも補完機能が働いてしまいます。コードの編集はエディタで行っているので、この挙動は不便です。補完機能を無効にするには、以下のコマンドをシェルで実行します。(元々、inputrcを使っている人は「>」の代わりに「>>」にする方が無難です。inputrcはbashにも影響があるかも知れません。)
echo '$if Guile' > ~/.inputrc
echo 'set disable-completion on' >> ~/.inputrc
echo '$endif' >> ~/.inputrc
ターミナルに移動せずに、Emacs内でScheme処理系を使うことも可能です。そのためには、Emacsの設定ファイル「~/.emacs.d/init.el」を編集して以下の行を追加する必要があります。「~/.emacs.d/init.el」が存在しない場合は新たに作成してください。
;;; Scheme処理系の設定。
(setq scheme-program-name "/usr/local/brew/bin/guile")
;;; Scheme処理系の起動時に、自動的にウィンドウを分割する。
(defadvice run-scheme (before split-window activate)
(if (= (count-windows) 1) (split-window))
(other-window 1))
2022.11.04追記) Scheme処理系の設定のパスを修正しました。
Emacsを起動し直してから、『\M-x run-scheme [Return]』と入力すると、「*scheme*」という名前のバッファができます。そこでは既に処理系が起動しているので、後はターミナルと同様に扱うことができます。Emacs内では『\M-p』で、入力の履歴を遡ることができます。(「\M-」というのは、altキーを押しながらという意味です。また、以後「\C-」はcontrolキーを押しながらを意味します。)
Emacs内で処理系を起動することのメリットとして、『\C-x \C-e』を挙げることができます。Schemeのコードを編集している最中に『\C-x \C-e』を押すと、カーソルの直前にあるShcemeの式が自動的に処理系で実行されます。もし処理系のバッファが見えていれば、カーソルを移動しなくてもそのバッファに計算結果が表示されます。この機能を使うと、コードを書く作業と動作確認を効率よく並列に行うことができます。
Guileの補完機能を有効にしている場合、Emacs内の自動送り機能を使っても補完が行われてしまいます。補完をオフにするには、上のシェルコマンドを参照してください。そもそもコードを書くときにタブを使わなければよいという話でもあるので、そうしたい場合はEmacsの設定ファイルに以下のように書いてください。
;;; インデントを埋めるときにタブではなくスペースを使う。
(setq-default indent-tabs-mode nil)
余談ですが、Emacsの設定ファイルに書かれた内容はSchemeのコードとよく似ています。実は、Emacs内で使われているのは、Emacs-Lispまたはelispと呼ばれるプログラミング言語です。Schemeやその他多くのLisp系言語と共通点があります。「*scratch*」という名前のバッファはEmacs-Lispの処理系です。『\C-j』で任意のコードを実行できます。(試しに、先程のSchemeの例文を入力してみてもよいでしょう。)