Common Lispに1年間入門して思ったこと

この記事はLisp Advent Calendar 2016の1日目の記事です。

Lisperの皆さん、どうもこんにちは、こんばんは、おはようございます。
Lisp Advent Calendar初日ということで、この場を借りて僕のCL生活1年目を振り返らせていただきます。

これからCommon Lispを始める方の道標になれば幸いです。

## 始めたワケ  
僕がCommon Lispを始めようと思った理由です。
[ブログの最初の記事](http://progn.hateblo.jp/entry/20151016/1444924753)にも書きましたが、やはり深町さんの影響が大きく、特に刺激を受けたのが以下の記事です。シビレますね B-)

[Common LispがWeb業界を駆逐するとき – Revenge of Lisp in Web | ありえるえりあ](http://dev.ariel-networks.com/wp/archives/303)

この記事のポストからおよそ6年が経ちましたが、今とこの当時を比べるとかなり状況が変わったように感じられます。
Lisp自体への注目は多くありませんが、現代のプロダクト開発のための地盤は整ってきたのではないでしょうか。
[サムライト株式会社](http://somewrite.com/)さんもLisp×Webで大きな成功を収めているようです。

また、僕が影響を受けたのは深町さんだけではありません。
同じくサムライトの成功に大きく貢献したであろう河西さんもその１人です。

[好きなCommon Lispで新しいWeb開発を～京大中退、22歳のサムライトCTOが取り組んだシステム再構築 - エンジニアtype](https://type.jp/et/log/article/somewrite_cto)

先日Kaizen Platformを退職されて、現在は[SEEED](https://thepedia.co/article/1769/)というインキュベーションプロジェクトに携わっているそうです。
今後の活躍が期待されますね。

彼らに刺激を受け、僕はLisperへの道を踏み出したのでした。

## ハウツー  
入門するにあたって、特に参考になったのが以下のページです。

[Common Lisp 入門 - M.Hiroi's Home Page](http://www.geocities.jp/m_hiroi/xyzzy_lisp.html)
[逆引きCommon Lisp](http://tips.cddddr.org/common-lisp/)
[ファイヤープロジェクト - Common Lisp](http://www.fireproject.jp/feature/common-lisp/)
[Common Lisp HyperSpec (TM)](http://clhs.lisp.se/Front/index.htm)

HyperSpecは直接開くよりもGoogleとかで「hyperspec ○○」と検索した方がアクセスが良いかもしれません。  

情報が見当たらない質問は[スタックオーバーフロー](http://ja.stackoverflow.com/)ですることをオススメします。
結構早く回答がもらえるので駆け出しにはありがたいです。

国内のLisp情報を集めている[reddit](https://www.reddit.com/r/lisp_ja/)もあるので、情報収集やモチベーション維持に役立っています。

## これまでの歩み  
[Myブログアーカイブス](http://progn.hateblo.jp/archive)をお読み下さい :-D

## Common Lispを始めてよかったこと
#### プログラミングの世界が広がった
Lispに限らず、これは他の言語にも波及しました。
やはり関数型言語としての知名度が高いということもあり、他の様々な関数型言語を書いてみるキッカケになりました。
Common Lispは比較的緩い関数型なので、関数型言語への入口となるでしょう。  

また[CLOS](https://ja.wikipedia.org/wiki/Common_Lisp_Object_System)を見て、オブジェクト指向を見直すキッカケにもなりました。
Lispを学び始めると言語仕様を調べる癖が付きますね :)

そして抽象化という概念を掴むことが出来ました。
Common Lispは強力なマクロとCLOSによって高度な抽象化を可能にしています。
特にマクロは十八番とも呼べる存在で、「同じ記述を繰り返したくない」とか「もっと読みやすく書きたい」という場合に有用です。
このようなマクロで抽象化されたライブラリは簡潔なAPIを提供しているため、既存のLispコードに違和感なく溶け込んで、自然な形で書くことが可能です。

あと、他人の書いたLispコードを読むのが楽しく感じます。
これは他の言語では感じられなかった気がします。

#### カッコが脅威に感じなくなった
Lispと言うと連なる大量の丸括弧に目を回す人がいますね。
僕なんかは特に学び始めはカッコの数をいちいち数えていたりしました。

しかし慣れというのは恐ろしいもので、コードを書きながらネストの深さを無意識にカウントするようになってしまいました。
これでハイライトが無いエディタでもLispが書けますね。

というか、C言語とかみたいに複数種類の括弧を使い分けるよりも、Lispみたいに丸括弧だけの方が分かりやすくないですか？

## Common Lispを始めてよくなかったこと
#### 定期的に書かないとイライラしてくる
ネタだと思ってるでしょうけれど、半分ぐらい本当です。
とても形容しがたいんですが、丸括弧だけで囲まれた空間に１つのアルゴリズムを押し込められた時が快感なんです。
中毒性が高い言語かもしれません。

## 分かりにくいと思ったこと  
パッケージの定義方法と具体的な扱い方を知るのに結構時間がかかりました。
以下の記事に参考URLと共にまとめられているので読みましょう。

[どうせ・だから: CommonLispでpackageとか名前空間とか コロン(:) について知ったこと ](http://migi-ni-naname-ue.blogspot.jp/2015/11/commonlisppackage.html)

管理システムについてはκeenさんがまとめてくださった記事が分かりやすかったです。

[require, ASDF, quicklispを正しく使う | κeenのHappy Hacκing Blog](http://keens.github.io/blog/2014/11/30/quicklisp/)

これらの記事を参考に、最低限抑えておけば良さそうなことをまとめたメモを書きました。
[パッケージについて](https://github.com/tamamu/survey/tree/master/cl-package)
[ASDFの使い方](https://github.com/tamamu/survey/tree/master/cl-asdf)

あと、最近の言語でありがちなプロジェクトの作成についてもまとめてみました。
[プロジェクト作成の方法](https://github.com/tamamu/survey/tree/master/cl-project)

その他。
[クラスの作り方・使い方](https://github.com/tamamu/survey/tree/master/cl-class)
[CFFIに関する備忘録](https://github.com/tamamu/survey/tree/master/cl-cffi)

## 便利だと思うこと
#### マクロが怖くない
最近だと構文木をいじるタイプのマクロが書ける言語が増えていますが、どれも書き方がイカツイです。
それに比べてCommon Lispのマクロは、引数を受け取ってリストを返すだけ！普通の関数と同じ感覚で書けるんです。
流石にリードマクロはちょっと難しいですけどね。

#### SLIMEが優秀
[the Superior Lisp Interaction Mode for Emacs](https://common-lisp.net/project/slime/)のことです。
僕はどちらかというとVimmerなので[slimv](https://github.com/kovisoft/slimv)を使っていますが。

これを使うとエディタとREPLが繋がって、動いてるREPL上にエディタからLispコードを送ってコンパイル・実行したり出来るんです。
GUIとかサーバみたいに別プロセスで動作するやつだと、その場で動いてる関数を書き換えられたりもします。
いわゆるライブコーディングも出来ちゃったり。

もちろんそれだけじゃなくて、関数の定義位置を教えてくれたり、ソースコードを補完してくれたりします。
詳しくは以下のページをご覧ください。

[モダンCommon Lisp第3回: SLIMEの使い方 基礎編 | ありえるえりあ](http://dev.ariel-networks.com/wp/archives/462)
[Modern Common Lisp: 第5回 SLIMEの使い方 開発サイクルについて ](http://modern-cl.blogspot.jp/2011/07/5-slime.html)

#### プロファイリング・最適化がしやすい
全てREPL上で完結するので、別なツールを立ち上げる必要がありません。
`(time (hoge))`とすればhoge関数の実行時間やメモリ使用率などを知ることが出来ますし、SBCLにはプロファイラが付いています。  
詳しくは以下の記事を。
[Cより高速なCommon Lispコードを書く - 八発白中](http://blog.8arrow.org/entry/2014/10/23/063044)

## 他の言語と比較してみて
#### 枯れてる？
別に枯れてないです。
"枯れた技術"って意味では確かにそうなんですが、古めかしさというものをあまり感じません。
最近流行りのGo言語のオブジェクト指向の部分を見てみると、なんとなくCLOSに近いものを感じたりもします。
古いながらも、現代のプログラミング言語に劣らない言語です。

#### 弱い部分
GUI系が弱いなと感じました。
というのも、Lispで書かれたGUIアプリケーションをほとんど見ないからです。
やはりGUIはLispより他の言語の方が書きやすいでしょうか？

それに比べるとゲーム系はまだ活発に感じますね。
Lisp-onlyのGame Jamも行われているみたいです。

[Spring 2016 Lisp Game Jam | itch.io](https://itch.io/jam/spring-2016-lisp-game-jam)

#### コミュニティが限られている
Rubyとかだとほぼ全国区でコミュニティが存在しますが……。

[Common LISP users jp - コミュニティ](http://cl.cddddr.org/index.cgi?%A5%B3%A5%DF%A5%E5%A5%CB%A5%C6%A5%A3)

ここを見た感じだと、主要都市にしか存在しないみたいですね。
そして注目していただきたいのが東日本、Shibuya.lispしか無いじゃないですか！
※現Shibuya.lispは残りあと2回で終了で、来年2月以降は引き継ぎとなるそうです。もしかしたら名前が変わるかもしれません。

どうか東北にもLispコミュを…誰か仙台か盛岡辺りで、やりませんか？

## 今後への期待
よりモダンな言語仕様を。
古めかしさを感じないとは言っても、現状に不満が無いわけではありません。
書き方に関してだと、配列の参照・メソッドの実行とか、もう少しスマートに書けないかなーと思う時が結構あります。
それと、局所的に中置記法で書けるとうれしいかな。あと引数の順番が気になる関数も少なくないです。
Clojureのletの変数束縛部分の書き方はネストが深くならなくて羨ましい！

まあ、全部リーダマクロで何とかなるんでしょうけれどね……。
この"何とかなってしまう"ところが言語自体の進化の妨げになっている気がしないでもないです。

モダンな言語仕様と言えば、cl21は面白い試みだと思います。
パフォーマンスは変わらないの？とか心配なところもややありますが、スマートに書けそうな印象。

[Github - cl21/cl21: Common Lisp in the 21st Century.](https://github.com/cl21/cl21)

というわけで、1日目はこんな感じで。
2日目は@tk_ripleさんの記事です。