見出し画像

macOSとVSCodeでLispするための備忘録

Lispって凄いなと思うわけだが、昔からLispを使ってみようにも実用的な使い方に辿り着かなかった。Lispも使えないくせにハッカーとは何事だと怒られそうでビクビクする今日この頃。

いろんな人にプログラミングを説明するときに、実はLispが一番いいんじゃないかと思った。だって(+ 1 2)で1+2になるっていう法則さえわかれば、Lispってなんでもできるんだぜ。for文とかwhile文とか面倒な制御構造がないので説明しやすいのではないかと思った。そもそも、a=a+1が理解できないというプログラミングの初心者つまづきポイントあるあるが回避できるし。

ところがLispは世界で二番目に古いプログラミング言語なので、命令がC++やJavaScriptに慣れた人だと難しい。

やはりちょっと自分でも触ってみるかと人生で10回目くらいに思い立ったので、VisualStudio CodeでLispしてみる。

まず、Homebrewとxcodeが必要なのでそれは自分でインストールしてくれ

まあコマンド一発でインストールできる

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

次に、xcodeはコマンドラインツールが必要になるのと、ライセンス認証が必要。といってもコマンドでこれを入力するだけ

 xcode-select --install
sudo xcodebuild -license accept

そのあと、homebrewでsbclというCommon Lisp処理系をインストールする

brew install sbcl

これでCommonLispはOK
VisualStudioCodeもダウンロードしておく

これでうまくいくと思いきや、少し罠があるので、まだコマンドラインを使う

curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp

これでsbclのREPLが立ち上がる。
ここから、いろいろ必要なツールをインストールする必要がある。
入力するコマンドだけ羅列する。一行ずつREPLに入れること

(quicklisp-quickstart:install)
(ql:add-to-init-file)
(ql:quickload :usocket)
(ql:quickload :alive-lsp)
(ql:quickload :bordeaux-threads)
(ql:quickload :flexi-streams)

その上で、AliveをVScodeにインストールする

これでなんとか.lispというファイルを作れば自動的にLisp環境が立ち上がる

わーい

あとはLispの本読みながら遊ぶだけ!
Option+shift+リターンでREPLにコードを送り込んだりできるし、Option+shift+Eでカーソル位置だけ評価したりできる。

ただ、Lispの本は、Lisperという変わった人たちが書いているので基本的によくわからないし難しい。

しかし、とほほのLispならタダだ!

Lispの何が良いかというと、まずプログラムもデータもともに「リスト」という単一の形式で扱われること。

このリストは、()で囲まれていて、常にリストの先頭要素が命令(関数)の名前で、それに続く要素が命令に渡すパラメータというルールしかないということ。

これだけで全ての制御構造が表現できるし、プログラム自体をプログラムの中で作り出すこともできる。昔はLispでプログラムを生成するプログラムを自分で書いたり動かしたりしていた(遺伝的プログラミングというやつだ)ので、LispはAI言語であるといわれたりしていたが、実際には超強力なプログラミング言語であるというだけにすぎない。

Webサーバーも書けるしゲームも書ける。例えばFinalFantasyVIIとクラッシュバンディクーはLispを最大限活用して作られたゲームだ。1990年代の日テレの3D天気予報はわずか三日でLispで書かれている。OpenAIのサム・アルトマンがCEOをやっていたYコンビネーターの創始者、ポール・グレアムもLispハッカーだ(Yコンビネータという名前そのものがLisp用語)

LispによるWebサービスの作り方は以下の記事が面白かった。
特にLispはホットデプロイといって、実行中のプログラムに関数を流し込むことができたり、異常停止した関数を再実行したりできて面白い。

みんなLispやろう。嗜み程度に

(16:31 追記)

なんか上のページのままだと動かなかったのでいろいろ試行錯誤した。

(ql:quickload '(:ningle :clack))
(defvar *app* (make-instance 'ningle:app))

(setf (ningle:route *app* "/")
      "Welcome to ningle!")

(setf (ningle:route *app* "/login" :method :POST)
      #'(lambda (params)
          (if (authorize (cdr (assoc "username" params :test #'string=))
                         (cdr (assoc "password" params :test #'string=)))
              "Authorized!"
              "Failed...Try again.")))
(print "hoge")
(clack:clackup *app* :port 5001)

これなら動く・・・・が、なぜかAlive上での実行がうまく行ったりいかなかったりする。

sbclで実行するとこんな感じで動いた

 % curl -s http://localhost:5001/
Welcome to ningle!%             

sbcl上で関数を書き換えね、オンザフライ!ホットデプロイ

(setf (ningle:route *app* "/")
      "Welcome to Lisp!")

 試してみる

curl -s http://localhost:5001/
Welcome to Lisp!%               

うわーい!できた
楽しい!
しかしこれをREPLでやらないと意味ないんだよなあ
結局Emacsにするしかないのか・・・それは少し避けたいと思っていたのだが