Rおじさん、Lisperへの道 (Common Lisp環境設定編)
はじめに
Twitter上でこんなやりとりがあって、Lispをちゃんと勉強しようかなと思った次第。これまでEmacsを使って設定ファイルも(汚いけど)それなりに書いてきたので基礎を知ってるくらいなので、ここは一つCommon Lispをちゃんとやっておきたいなというのが主な動機です。
最近、 @igjit さんの影響からからLisp熱が再発してる。もともとEmacs使ってるってのもあるけど。
— matsumura (@y__mattu) 2019年4月17日
RおじさんからLisperに進化できるだろうか...
ところで、このブログは「データ解析周りを中心に、プログラミング全般について書く」と明言してるわけですがこれからやるCommon Lispがどのくらい役に立つかは未知数。
Common Lisp の環境設定
PCはMacのMojaveを使ってます。
Roswellで処理系としてはSBCLを使い、EmacsでSLIMEの環境を作るところまでを目指します。
用語整理
Common Lispについて調べているといくつか混同しそうなワードが出てきたので整理。
SBCL
,CLISP
,Clozure CL
: Common Lispの処理系。Common Lispは、一つの公式の実装が存在するわけではなく、ANSIで規定された規格で規定された機能を実装したものはすべてCommon Lispを名乗ることがきるらしい。Roswell
: Common Lisp処理系マネージャ。Pythonでいうところのpyenv的なやつQuicklisp
: パッケージマネジャ。Pythonでいうところのpipみたいなやつ。SLIME
: エディタをIDEっぽくするやつ。
Roswell
このあたりを参考に。 Homebrewで簡単に。と思いきや後のSBCLのインストールで詰まったので注意です。
ここを参考に
brew install --HEAD roswell
のように最新バージョンをきちんと明示してやらないとだめでした(私の環境では。)
Roswellはそれ自身、コア以外の部分にCommon Lisp処理系を必要とします。以下のコマンドを叩くことで、Common Lisp処理系を取得し、roswellの設定の初期化やパッケージマネージャ (quicklisp) のインストールが行われ、完全に機能するようになります。
ros setup
Quicklisp
この項は必要なし(コメント参照)
curl -O https://beta.quicklisp.org/quicklisp.lisp ros run
(load "./quicklisp.lisp") (quicklisp-quickstart:install)
Emacs×SLIME
Emacsの設定。
ターミナルで
ros install slime
sbcl を起動し(ros runコマンド)、
この処理は必要なし(コメント参照)
(ql:quickload :quicklisp-slime-helper)
続いてEmacsを起動し、
M-x package-install
で以下を入れる
- slime
- slime-company
~/.emacs.d/init.el
に以下を記述
;; 拡張子関連 (add-to-list 'auto-mode-alist '("\\.lsp$" . lisp-mode)) (add-to-list 'auto-mode-alist '("\\.lisp$" . lisp-mode)) (load (expand-file-name "~/.roswell/helper.el")) ;; SLIMEのロード ;; 以下3行は(load (expand-file-name "~/.roswell/helper.el"))の時点で設定される ;; (require 'slime) ;; (require 'slime-autoloads) ;; (slime-setup '(slime-repl slime-fancy slime-banner)) ;; SLIMEからの入力をUTF-8に設定 (setq slime-net-coding-system 'utf-8-unix) (eval-after-load "slime" '(slime-setup '(slime-fancy slime-banner))) (global-set-key "\C-cs" 'slime-selector) ;; M-x my-slime: 分割したウィンドウでslime起動 ;; C-c C-r: 選択範囲をslime-replへ送って評価 (defun my-slime (&optional command coding-system) "Run slime and split window." (interactive) (if (< (count-windows) 2) (split-window-vertically) ) (slime command coding-system) (other-window 1) ) (defun slime-repl-send-region (start end) "Send region to slime-repl." (interactive "r") (let ((buf-name (buffer-name (current-buffer))) (sbcl-buf (get-buffer "*slime-repl sbcl*"))) (cond (sbcl-buf (copy-region-as-kill start end) (switch-to-buffer-other-window sbcl-buf) (yank) (slime-repl-send-input "\n") (switch-to-buffer-other-window buf-name)) (t (message "Not exist *slime-repl sbcl* buffer!"))) )) (global-set-key "\C-c\C-r" 'slime-repl-send-region) ;; LISPモードで新しくファイルを開いたらウィンドウが上下に分割して下にREPL (add-hook 'lisp-mode-hook (lambda () (global-set-key "\C-cH" 'hyperspec-lookup) (cond ((not (featurep 'slime)) (require 'slime) (normal-mode))) (my-slime)))
SLIME周りの設定 - もうカツ丼はいいよな を参考にしました。