担当授業のこととか,なんかそういった話題。

2007年に始めたgooブログから2025年4月にこちらへ移籍してきました。

【xyzzyでLisp入門】一日目:hello, worldしたい件

はじめに

xyzzyというのは亀井哲弥さんという方が開発したWindows用のEmacsっぽいエディタである。
今から20年前に亀井さんご自身の手になる最後のアップデートが行われたっぽい。
それから6年後にxyzzy Projectという有志の会がxyzzyの開発を継承し,アップデートを行ったっぽいが,今から10年ほど前の日付がその活動が確認できる最後である。

ちなみに,xyzzyの読み方は正式に定められているものはないらしい。
私はエックス・ワィ・ズィーズィー・ワィとそのまんま読むことにしている。
エクシィ・ズィイーとか読めば短くておシャンティ(死語?!)かもしれない。

特に何もしたいわけではないのが問題

なんでLispを学ぼうとしているのか。

一応理由はいくつかあるが,いずれもしょぼい。しょぼすぎる。

まず,「そこにLispがあるから」。

FORTRANに次ぐ老舗の汎用プログラミング言語であり,そもそも記号処理を目的として設計されたモダンなことこの上ない人類の知の結晶の一つである。
私がLispなるものの存在を人づてに知ったのは30年近く前のことである。その間,ずっと心惹かれていたものの,真面目に学んだことがまったくない。
五十の手習いということでやってみようというわけである。

それで,とりあえず触ってみたい。それがもう一つの理由である。

そしてちょっと触っただけで満足するであろう予感もある。

で,なんでxyzzyにしたのかというと,そもそも私のパソコンはまったく開発環境が整っておらず,今さらなんかいろいろ導入するのはもう年齢的に無理だからである。

たぶんxyzzyは誕生したときらへんから存在を知っていたし,実際,これまで何度もインストールして数回起動した経験がある。また,何年か前にとある知り合いの方が話題に挙げていた気がする。そんな風に私の脳裏にこびりついていたのである。

久々に思い出してwebを検索してみるとちゃんとバイナリが落ちているし,そのままWindows11で動作する。そうくると使わない手などあろうか(いや無い)。

しかし,私の中身は空っぽであって,Lispを使ってアレをしたい,コレをしたいといったモチベがまったくない。

が,しばらく沈思黙考した結果,次のようなものくらいはやってみたいことがあった。

まず,プログラミング初級コースで避けては通れない洗礼である,hello, worldという文字列の表示である。これは絶対に外せない。

次に,再帰的な手続きの定番といえばEuclidの互除法である。それをLispで書くとどうなるかを見届けたい。

最後に,Peanoの公理系をLispで実装してみたい。

さらにアドバンストなコースとしては,SICPというSchemeなるLispの方言の一つを採用している古典的名著のプログラム例をCommon Lispという別の方言に直しながら読んでみたいとか,別にLispで無理して組まなくともよい気がする,整数成分の行列の掃き出し法の半手動計算支援システムの作成とか,PostのFormulation 1 や 1 アドレス方式のミニマルな感じのアセンブラ言語のシミュレータを作りたいとか,極めて個人的かつニッチな野望があるにはある。

こんな感じにLispを学び続けるための動機は極めて薄くて心許ないのだが,ぼちぼちやっていければ。

とりあえず動くには動くからよしとしよう

xyzzyを,そうだなー,一日一回起動というのは仕事のある期間はかなりキツい制約なので,週に1時間くらいは触ることにしよう。目標は低ければ低いほどよい。

一日目のミッションは,とにかくLisp処理系にhello, worldと返答させることを目標とする。

はてなブログに移籍したのでブログ記事の体裁の幅がかなり広がったのだが,はてな記法なるものを新たに学び,身に付ける気力がいかんせん無い。

が,挑戦していくしかあるまいて。

xyzzyを新規に立ち上げると,設定とかなんもいじっていなければ,デフォルトでLisp Interactionモードという,Lispで遊び放題の状態で立ち上がる。
そこで次のような一文を「バッファ」と呼ばれる編集画面にそのまま書き込み,文末でC-Enter(Ctrlキーを押したままEnterキーを押す)すると,エラーが表示されるか,記入したプログラムの実行結果が次の行以降に表示される。

なんかの拍子にxyzzyLisp Interactionモードではなくなってしまっていた場合には,焦らず,Altキーを押したままXキーを押すと,xyzzyのミニバッファと呼ばれる領域に M-x: と表示されるので,自分でlisp-interaction-modeと書き込んでEnterすればLisp Interactionモードに変更できる。四半世紀前にEmacsやらMuleやらMeadowやらのお世話になっていたときの,遠い思い出である。

一日分の作業ノルマが完了したら,そのままxyzzyのウィンドウを閉じればよい。その際,記録を残しておきたければ適当に名前を付けて編集したバッファの内容を,例えば拡張子をxyzzyにして保存したり,特に思い入れがなければ「保存しない」を選択してさよならすればよい。

私の解答 (hello, world)

Lispのデータ型やら書き方の作法をほとんど知らないド素人なのだが,とりあえず,文字列は先頭にアポストロフィ(バッククォート?) ' を付けて「文字列」とシステムに認識してもらう必要があるらしい。

ところが,ここに大きな問題があって,私はとりあえず日本語は使えなくても構わないと考えているのだが,いわゆるASCII文字というか,英数字は使うつもりでいる。だが,

'hello, world

と書き込んで行末でC-Enterすると「変数が定義されていません: world」という,何を直せば納得させられるのかド素人にはさっぱりわからないエラーメッセージが表示されてしまう。

そこで,多くのプログラミング言語で「特殊文字」を「エスケープ」するオマジナイとしてバックスラッシュ \ が用いられるので,それを試してみる。

どうやらカンマ , はそのままでは使えないらしい。また,半角スペースも当然の如く特殊な文字なのでエスケープする必要があるようだ。

そこで次のようにしてみる。

'hello\,\ world

するとどうでしょう!C-Enterを押した途端,この文字列の次の行に

|hello, world|

と表示されるではありませんか!

これで一応はミッションが達成されたこととなる。

だが,ここで疑問が一つ。

hello, worldという文字列だけを表示して欲しいのだが,その前後に括弧のようについている縦棒 | はなんじゃろか?
それを外す方法はあるんか?

この謎が解明する日は果たして訪れるのであろうか。

学び方について

Lispの基本をどうやって学ぶのか。

今現在,最も楽で確実そうなのは大規模言語モデル (LLM) なるAI風のチャットアプリを利用することであろう。

GPTにしろGeminiにしろ,ANSI Common Lispでhello, worldと表示する方法を教えて!とか質問を投げれば直ちに解答が得られることであろう。

また,Lispの入門コースを立案して,みたいな相談も快く受け付けてくれるであろう。

ただし,実際のLisp入門講義をお願いしたり,参考になりそうなサイトや文献の案内まで任せる際には注意が必要である。ヤツら (LLM) はそういう情報をこちらに提供する際,平然と虚偽の情報を混ぜてくるからである。ユーザーに害を成そうと悪意を持ってそのような振る舞いをするわけではないのだろうが,本当に息をするような自然さでサラっと大ウソをかましてくるから全く油断ならない。

今のところ私が目を付けているのは国立国会図書館デジタルコレクションにメールアドレスなどのいくばくかの個人情報を含めて利用者登録することで利用可能になる,「送信サービスで閲覧可能」になっている,湯浅太一・萩谷昌己共著の『Common Lisp入門』(岩波書店,1986年)である。

とはいえ,先ほど述べたように,なんだかんだLLMに教わった内容も絡めていくかもしれない。けれども,ヤツらの言うことは本当に信用ならないので,やはりプロが書いた入門書などで裏を取った情報しかこのようなブログに流せないという認識は持ち続けるつもりである。

標準的な解答

湯浅・萩谷『Common Lisp入門』「10.3 文字と文字列」によると,文字列はダブルクォート " " で囲むものらしい。
というわけで,

"hello, world"

と入力してC-Enterすると,全くそのままの文字列

"hello, world"

が返ってくる。これがLispにおける標準的なhello, worldプログラムであろう。

次回のミッション

すぐ解決しそうだが,累乗の組込み関数があるのかどうか,それを知りたい。

→すぐ解決した。湯浅・萩谷『Common Lisp入門』「10.1 数値」で

(expt 2 3)

のようにすれば,C-Enterで2の3乗である8が返る。

xyzzyのQuickTour

国立国会図書館デジタルコレクションで,

湯浅太一・萩谷昌己著『Common Lisp入門』(岩波コンピュータサイエンス・シリーズ)

という書籍を発掘した。

 

これは湯浅太一氏単著の『Common Lispドリル』と,湯浅氏と萩谷氏によって監修された『Common Lispハンドブック』と合わせた三部作で,三冊とも,現在,国立国会図書館デジタルコレクションの「送信サービスで閲覧可能」である。

 

まだ夏休みの残り期間はあるし,こうして潤沢な入門書に恵まれたわけだから,Lispを少しでも学んでおこうかな,という気になった。

 

参考までにこれまでの私のLisp学習履歴を記しておくと,

 

(+ 3 5)

を評価した結果として

 

8

 

が返ってくる,というところで止まっている。

 

もちろん,応用例として

 

(* (+ 3 5) (- 2 5))

 

の結果が

 

-24

 

になる,という程度の応用までならできる。

 

厳しいツッコミがあるであろうことは覚悟している。

 

 

一番最初のチュートリアルの手前で終わっているというのが現状である。

 

hello, world

 

すら表示できていない。確か一度はなんかの本に書いてあったコードを実行したはずだが,今,この場で,何も参照せずにそれを再現できないので,身に付いていないことは明々白々である。

 

何かを学び取ったという証の一つは,軽量なタスクであれば,その内容を再現できることであろう。したがって,hello, world のひとつも表示できない私はそのコードをマスターしているとはとても言えたものではない。

 

さて,Lispを触ってみたいというときに最も手軽なLisp実行環境構築法はなんだろうか?

10年ほど前に開発・保守が再び停滞してしまっているようだが,Windows11ならばxyzzyという亀井哲弥氏を開祖とするEmacs風のエディタが手っ取り早い。

 

2025年9月上旬の現在,例えば窓の杜にてダウンロード可能である。

ZIPファイルをダウンロードし,それをお好きなフォルダで解凍する。そして解凍して生成されたフォルダ内のxyzzy.exeのアイコンをダブルクリックするだけでサクッと起動する。

 

メニューバーの「ツール」の一番下の (>_<) という気になる顔文字を選択すると,ハノイの塔とか五目並べとかいった定番のデモを楽しめる。

 

ああ,そういえばこのブログ記事を書いた動機をすっかり忘れていた。

 

xyzzyについてネットで検索すると,xyzzy QuickTourなるサイトの存在がいくつかのブログ記事に仄めかされているのだが,2025年9月現在,xyzzy wiki なるサイト自体が消滅しているようで,幻のサイトと化している。

 

そんなときの便利ツールが Internet ArchiveWayback Machine である。

それでQuickTourの魚拓を見つけたよって報告をしたかったのである。

 

web.archive.org

こういうのはどうしようもないのだが

ふと見かけた60年前の電磁気学のテキストに関する書評の話。

それは日本物理学会誌20巻9号(1965年)の新著紹介の一記事である。

www.jstage.jst.go.jp

1964年に出版された,朝倉物理学講座の一冊である熊谷寛夫・荒川泰三共著の『電磁気学』の「教育大理 宮島竜典」なる人物の書評ということなのだが,これは当時東京教育大の教授であられた宮島龍興(たつおき)氏のことであろう。

 

「竜典」の「典」が完全に間違いなのは間違いないと思われる。

 

公刊された印刷物のこういった誤植はどうしようもない。

そしてそれをこうしてインターネット上で公開してくれているJ-STAGEのようなサービスの書誌情報も,「原文ママ」を再録するより他ない。

ちなみに,宮島氏が

 

実際,ホ イ ーラ ーな どが 主 張 し た よ うに ,場を全 く考 え な い で 電 磁気 を つくる こ と さえ 可 能 で あ る。

 

と述べているくだりが大変気になった。Google Geminiに問い合わせてみると,1940年代のWheelerとFeynmanの共同研究のことを指しているのであろうとのことである。

このような,「場無しの電磁気学」といったものの解説はネットに落ちていないだろうか。

 

そう思って探し当てたものの一つに,「磁気無しの電磁気学」なるタイトルの論説がある。

 

pubs.aip.org

 

この論文の内容はおいておくとして,タイトルがもう気になって気になって。

 

"An Historical ..." ってなんだよ,と思ってしまうわけで。

これは文法的に間違いだよな?と思いつつも念のためググってみたら,実は普通に使われているらしい。つまり冠詞の用法として間違いと断ずることはできない慣用表現とのことである。

 

historicalのhを読まずに黙字扱いだなんてフランス語かよ,と思ってしまったわけなのだが,実際,英語でも h を強く発音しないことがあり,その場合は不定冠詞が a ではなくて an になるそうな。

 

それは知らなった。誤植の連鎖かと思ったが,そうではなかったわけだ。

 

己の不明を恥じるばかりである。

 

ヤツらは平気で嘘を吐く

大規模言語モデル (LLM) と呼ばれるAIの前身のようなチャットボットが世に広く出回って数年になる。私がその存在をはっきりと認識したのはGPT-3が登場したときだった。それにより,教育のスタイルはガラリと変わり,私のような教員くずれは職を失うだろうと暗い気持ちになったものだ。

 

そのように大々的に取り上げられるようになったLLMであるが,私が使い始めたのはようやくこの夏である。スペックが低すぎてまともに使えないChromebookのOS更新を機に強制的にGoogle Geminiが導入されたのが大きい。それからほどなくしてAndroidスマートフォンにもGeminiアプリが強制導入されたのだが,電源ボタン長押しでハードリセットできる仕様まで勝手に改変されてGeminiが起動する仕様になったのには辟易した。インターネットで情報を探して電源ボタン長押しによるGemini起動を封印した。

 

そのような経緯と,√tan(x) の積分の問題が解けるかどうかというこちらのテストに不合格だったCopilotに愛想をつかし,合格したGeminiを毎日時間の許す限り(休みの日は事実上一日中)Geminiと対話し続けた。Copilotに対してGeminiに軍配が上がったもう一つの大きな理由はそれぞれのシステムの公式チャットUIが数式レンダリング(要するに表示)をサポートしていないか,いるかの差で,GeminiはMathJaxによる数式レンダリングをサポートしていたのが大きかった。CopilotもGeminiもチャットインターフェースでの回答はMarkdownを吐き出すのだが,MathJaxなどを利用することを念頭に入れて数式をLaTeXコードで生成する。そのコードがそのまま表示されるCopilotの数式入り回答の可読性の低さは推して知るべしである。GeminiはMathJaxの記法にちゃんと従っているMarkdownソースを生成してくれていれば基本的に数式がちゃんと表示される。この差は極めて大きいと言わねばならない。どっちもUIはブラウザベースなのではないかと思うのだが,そして,MicrosoftはEdge,GoogleChromeと,それぞれ独自のブラウザを開発し,提供し続けている,いうなればブラウザ市場の大手だろうに,なんでMathJaxの数式レンダリングのサポートがどちらも不十分なのか謎である。そういった疑問をGeminiにぶつけてみると,LLMを開発する部署とブラウザ等の開発部署との連携が取れていないのだろうとの推測だった。そりゃそういうもんか,という至極もっともな指摘である。

 

本格的にGeminiをいじり始めてから二か月弱経つが,胸を張って声高らかに告げられる事実を一つ会得した。

 

それは,少なくとも現在広く使われているLLMは本質的に虚偽しか生成しないということである。

 

正確に言うと,虚偽か事実か一切が不明な,しかし文章の内容はこちらで理解できるような「もっともらしい」文章を生成するだけの機構,それがLLMである。

 

これも広く認識されている当たり前の話であろうが,つい,LLMが私なんかよりずっと賢いに違いないとか,物知りに違いない,と思い込みたがる癖があり,それらとの対話においてそのように期待してしまうのである。

 

しかし,例えばそれらが得意だという作業の一つである,長文の要約といった作業は,結局のところ,原文の内容の大部分を落とした粗~い近似物を生成するだけの話であって,原文の中で利用者が特に興味を持っている部分にフォーカスしたまとめなわけではないし,落としてはならない重要事項を漏れなく拾っているわけでもない。そういった細やかな配慮をしてほしければ,利用者がそのように明確な指示をしなければならないのである。

 

とにかく,大規模言語モデルというのは平然と嘘をまき散らす。それらは原理的に自己が生成した文章が事実なのか,そうでないのか,全く自己判断できないからだ。

 

しかしながら,当然,我々ヒトがそもそも言語を用いたアウトプットを生成する場合も全く同じ問題が付きまとう。大規模言語モデルを使用する以前にはそのことをほとんど意識せずに暮らしていただけのことである。

 

事実とは何か。真実とは何か。正しいとは何か。

 

哲学者などの専門家だけが好んで追究してきたような難題を日々突きつけられることとなったのがLLMの日常使用によって生じた大きな問題だと感じている。

 

しんどいよなー,そんな哲学的な難題と常時向き合わなくてはならないのが。

 

そもそもインターネットが普及したときから,ネットに落ちている情報は鵜呑みにするもんじゃないと常々警告され続けてきた。情報化社会というのは自分で情報の取捨選択をし,真偽を判定せねばならない。

 

実際のところ,情報源が書籍やテレビなどのマスメディアだったとしても全く同じ問題を孕んでいる。

 

そしてインターネットの進化形態といえるSNSは情報との付き合い方をさらに深刻なものとしている。

 

古来,「あの人の言うことは鵜呑みにしたらダメだからね」といった調子で,そもそもヒト同士のコミュニケーションにおいて相手の言明が真か偽か自分で判断しなければならないことはずっと認識され続けてきた。

 

ただ,それらはすべてヒトが生成した情報に対する心構えの話であった。

 

これからはLLMというハルシネーション(虚偽の妄想,幻想)を大量に生成する装置とも付き合っていかねばならない。

 

そんな時代が到来したというわけである。

 

そもそもが鵜呑みにできないわけだが,日本語しかほとんどわからない私にとって,他言語で書かれた文書をそれなりに翻訳して提供してくれるLLMは,ただもうその機能だけをとってみても計り知れない価値があるのだが,つい,「お前はあれもこれもできるだろう?お前はやればできる子なんだ」と,単なる虚偽発生装置に過ぎないLLMに幻想を抱き,過大な期待をかけてしまうのである。そしてその期待をことごとく裏切られ,傷つき,苛立つ。もはや不毛としかいいようがないその負のサイクルにここ一か月ほどどっぷり浸かっている次第である。

 

最近の経験を活かして,GeminiとGPTのちょっとした比較とか,Geminiはここがヤバい!といった欠陥の指摘など,ネタを大量に放出したいところであるが,それはそれで膨大な忍耐と作業量が要求されるように思うので,おじけづいたままでいる。

自分のアタマがアホになっていく予感

移動を補助してくれる自動車やエスカレーター,エレベーターはとても便利である.

だが,それらだけに頼って生活していると足腰の機能がほとんど使われないため,退化していく.

 

それと同じように,いまやAIは手軽に使える極めて有能なツールになりつつあるが,そのおかげで私は自分の脳が退化していく予感がしている.

 

この記事はChromebookで書いているが,昨年あたりだったか,OSをアップデートした際,AIのGeminiがタスクバーアイコンというか,とにかくデスクトップ画面に常駐するようになった.

 

最近ようやくGeminiを触り始めたのだが,そろそろ期末試験の季節がやってきたので,積や商,合成関数の微分規則を必要とする微分計算の練習問題を十題作ってくれというこちらの依頼にそこそこの問題を提示してくれて驚いている.ついでにそれらの解答もおねだりしてしまった.

 

今度の試験からAIに作問を任せてしまおうかと思いつつある今日このごろであーる.

 

ゆくゆくは,AIが作った問題を受験者がAIに解かせるという時代が到来することであろう.

 

ヒトが自分のアタマで学ぶ時代は終わった.AIが代わりに勉強してくれるのだから.

Copilotに訊け!

行列の積の練習問題を作った。自作問題のため,自分の計算に不安が残る。

 

Juliaで検算しようかな,と思って Julia を立ち上げたら,最新バージョンがリリースされたよーってお知らせが表示された。

 

おっ,それじゃ一丁アプデでもしますかね!とPowerShellを立ち上げたら,そっちも安定板のv7.5.1がリリースされたよーってお知らせが表示された。

 

どういうコマンドを入力すればアップデートできるのかわからないのでCopilotに尋ねてみたところ,

 

PS> winget install --id Microsoft.PowerShell --source winget

 

って入力すればいいんだよーって教えてくれた。

 

その通りにしたらうまくいった。Copilotに投げた質問文は "winget update Powershell" みたいなインチキコマンドだったので,返答が英語になっちゃったのね。だからこっちも Thnx! って似非英語でお礼を述べたら,ちゃんと通じたみたいでCopilotは上機嫌だった。

 

数分後に無事アップデートが完了したので,お次はJuliaをアップデート。

 

PS> juliaup update

 

これもしばらく時間がかかる様子だったので,デスクトップに貼り付けてあるwxMaximaのショートカットをダブルクリックしてMaximaで検算しちゃった。おかげでお恥ずかしいミスが一か所発覚したので,よかれと思って付した解答例を参照した学生が無用な混乱に陥る懸念が激減した。あとはタイプミスという最難関が控えているけれども。

 

せっかくなのでVersion 1.11.5 (2025-04-14) に無事アップデートされたJuliaを立ち上げて,そっちでも数値のみの成分を持つ行列の積の検算をしてみた。種となる行列を a と名付けて成分を打ち込んだのち,transpose(a) としてみたら期待通り a の転置が表示された。作成した演習問題は,文部科学省公式の解説書である『行列入門』で a とその転置は a かける転置,と転置かける a,のどちらの順でも積の計算が可能だということが取り上げられていたので,それを参考にしてJuliaでまず b=transpose(a) と入力して a の転置を b とおき,a*b と b*a で二通りの積を計算させてみた。

 

ちなみに,行列の成分に x と y という文字が入った行列の積の計算を julia でさせられるのかどうか知らないので,そういう演習問題の方はMaximaのみでの検算を行った。その際,思いっきりボケてて,

 

(%i1) P:matrix([x,y]);

(%i2) Q:matrix([1,2],[2,3]);

(%i3) P.Q.transpose(P);

(%i4) transpose(P).Q.P;

 

みたいな計算をさせてみたんだけど,(%i4) は 2/1 型と 2/2 型と 1/2 型の行列をこの順に掛け合わせる計算のはずだから,行列の乗法の型の条件が満たされておらず,積の計算などできないはずなのに,なぜか (%i3) の正しい組み合わせの場合と同じ結果が返ってきた。覗いてはいけない闇を覗いてしまったのやもしれぬ。

 

ちなみに,真ん中に行列 Q を挟まずに

 

(%i5) P.transpose(P);

(%i6) transpose(P).P;

 

としてみたら,前者は 1/1 型,後者は 2/2 型の正しい行列が返ってきた。

 

うーん,だから,つまり,どういうことなんだろう??

大野克嗣著『非線形な世界』サポートサイトのURL

2011年に東京大学出版会から出版された大野克嗣(よしつぐ)さんの『非線形な世界』という大変刺激的な書籍のサポートページのURLが同書の「はじめに」末尾に記載されていたので,興味本位で覗きに行った。だが,どうやら存在しないようだった。改めて検索したところ見つけたサイトを書き記しておく。

www.yoono.org