SlideShare a Scribd company logo
括弧への異常な愛情 または私は如何にして心配するのを止めて Common Lisp  を愛するようになったか Shibuya.lisp  テクニカル・トーク #7 アリエル・ネットワーク株式会社 松山朋洋
アジェンダ 1.  自己紹介 2. Lisp  に対する懐疑 3. Lisp  を始めた経緯 4. Lisp  との闘い 5.  なぜ  Lisp  なのか 6. Lisper's Delight
1.  自己紹介 松山 朋洋 アリエル・ネットワーク株式会社 @m 2ym  http://cx4a.org/ 好きなエディタ GNU Emacs 作ったもの auto-complete.el, popwin.el, popup.el, mongo.el, rsense, gccsense, xkeyremap, etc
1.  自己紹介 プログラミング言語遍歴 2002 年〜 C 2003 年 Visual Basic 6 2003 年〜 2008 年 C++ 2006 年〜 GNU Emacs 2007 年〜 2010 年 Java 2007 年〜 Emacs Lisp 2009 年〜 Ruby 2010 年〜 OCaml, Haskell, Common Lisp パラダイム 手続き型・オブジェクト指向型に触れた期間が長く、関数型 や  Lisp  に触れた期間は短い。
2. Lisp  に対する懐疑
2. Lisp  に対する懐疑 腑に落ちない啓蒙文書 Beating the Averages (Paul Graham), Revenge of the Nerds (Paul Graham), How to Become a Hacker (Eric Raymond), Let Over Lambda (Doug Hoyte), etc
2. Lisp  に対する懐疑 キラーアプリケーションの少なさ それほど”パワフル”な言語なのに、キラーアプリケーションが少ない
2. Lisp  に対する懐疑 コミュニティの小ささ それほど”魅力的”な言語なのに、そのコミュニティは小さい
2. Lisp  に対する懐疑 標準化の停滞 それほど”人気”な言語なのに、なぜ標準化作業が停滞 ( Common Lisp )したり、遅々として進まない( Scheme )のか
2. Lisp  に対する懐疑 Lisp  の専売特許 ガベージコレクションやラムダ式、マクロの大部分はもはや  Lisp  の専売特許ではない
2. Lisp  に対する懐疑 Emacs Lisp  のひどさ ” 括弧だらけの C” 。これがあの ” Lisp”  か?
3. Lisp  を始めた経緯
3. Lisp  を始めた経緯 会社で立ちあがった、あるプロジェクト 当初は  Ruby on Rails  か  Pylons  の二択で考えていた。 ところが、  Common Lisp  はどうかと同僚の深町さんに勧誘され、とんとん拍子で決まってしまった。 これが悪夢の始まりであった。
4. Lisp  との闘い
4. Lisp  との闘い パッケージ パッケージの名前空間はグローバル。パッケージはモノシリックに設計するのが一般的。パッケージには以下の問題がある。 a.  名前衝突 b.  ニックネーム c.  不本意な  intern d.  面倒な  export
4. Lisp  との闘い a.  名前衝突 安易に  use-package  すると名前の衝突に弱くなるどころか、不可解なバグに悩まされる可能性がある。とはいっても一々  import  するのも面倒。 (defpackage foobar (:use :cl :alexandria)) (defpackage foobar (:use :cl) (:import-from :alexandria ...))
4. Lisp  との闘い b.  ニックネーム パッケージにニックネーム(あるいは)を付ける合理的な権限を持つのは、パッケージ作成者のみ。  Haskell, OCaml, Python  のように、パッケージに一時的に別名を与える手段がない。 -- Haskell -  可能 import qualified Data.Map as M ;; Common Lisp -  不可能 (defpackage foobar (:use :cl) (:rename :alexandria :alex))
4. Lisp  との闘い b.  ニックネーム また、パッケージを一時的に  use-package  することもで きない。 (* OCaml –  可能  *) let open List in rev (map (fun x -> succ x) [1; 2; 3]) ;; Common Lisp –  不可能 (with-use-package :alexandria (plist-alist (remove-from-plist '(:a 1 :b 2) :a))
4. Lisp  との闘い c.  不本意な  intern defpackage  中に不本意な  intern  が発生す る。 ;; *package* = cl-user  と仮定 (defpackage foobar (:use *my-varaible* :my-function)) cl-user  パッケージに  foobar  と  *my-variable*  、  keyword  パッケージに  my-function  が  intern  される。気にしたら負け。 (defpackage #:foobar  ;  潔癖症 (:use #:*my-varaible* #:my-function))
4. Lisp  との闘い d.  面倒な  export export  するのが結構面倒臭い。 ;;  いちいち  :export  に追加 (defpackage foobar (:use :cl) (:export :foo :bar ...)) Clojure  の  defn/defn-  に相当するものを用意するとか、  Go  のようにシンボルが大文字で始まる場合にリーダーがそのシンボルを  export  するなど、手段は色々。
4. Lisp  との闘い d.  面倒な  export 一つの解決策として  cl-annot  を開発した。  @  に続く二つのフォームをリストで包んで返す簡単なリーダーマクロ。 CL-USER> '@1+ 2 (1+ 2) CL-USER> '@export (defun foo () ...) (progn (export 'foo) (defun foo () ...))
4. Lisp  との闘い CLOS スロットアクセサの名前をどうするかは実は難しい問題。パッケージシステムに関連する問題でもある。 of  派、  prefix  派、  keyword  派があり、それぞれ一長一短。
4. Lisp  との闘い CLOS ;; of  派 (defclass person () ((name :accessor name-of) (age  :accessor age-of))) (name-of bob) => “Bob” (age-of bob) => 42 アクセサが総称関数であることのメリットを生かせるが、名前衝突しやすい。
4. Lisp  との闘い CLOS ;; prefix  派 (defclass person () ((name :accessor person-name) (age  :accessor person-age))) (person-name bob) => “Bob” (person-age bob) => 42 名前衝突の危険性は少ないが、冗長。また、継承したクラスのインスタンスに使う場合に、少し違和感がある。
4. Lisp  との闘い CLOS ;; keyword  派 (defclass person () ((name :accessor :name) (age  :accessor :age))) (:name bob) => “Bob” (:age bob) => 42 keyword  パッケージをグローバル名前空間に見立てるテクニック。使い勝手としてはダックタイピングに近くなるが、慣習として定着しなければ、さまざまな危険性を伴う。
4. Lisp  との闘い multiple-value-bind ネストした  multiple-value-bind  をもっと簡単に書きたい。 (multiple-value-bind (a b) (values 1 2) (multiple-value-bind (c d) (values 3 4) (+ a b c d)))
4. Lisp  との闘い multiple-value-bind マクロを自作したが、後に   metabang-bind  がまさにそれだと知った。 (metabang-bind:bind ((values a b) (values 1 2)) (values c d) (values 3 4))) (+ a b c d)) しかし全く使ってない。
4. Lisp  との闘い パターンマッチング metabang-bind  や  cl-pattern  でも可能だが、より高速な  ML  風のパターンマッチングが欲しかったため、  cl-pattern (後に  cl-adt  に統合)を開発した。 (match '(“Bob” 42) ((list “Alice” 30) :alice-30) ((list “Alice” 40) :alice-40) ((list “Bob”  30) :bob-30) ((list “Bob”  42) :bob-42)) しかし全く使ってない。
4. Lisp  との闘い loop 痒いところに手が届かない  loop  。特に、返り値に対して任意の変換を行えないことに不満を感じ、  cl-loop-plus  を開発した。 (defun vectorize (seq &optional (element-type '*)) (coerce seq `(vector ,element-type))) (loop for i from 0 below 100 by 2 collect i transform #'vectorize) 全く使わなかったため、廃棄。パーサー部分は  cl-ast  にマージ。複雑な  loop  は  iterate  で。
4. Lisp  との闘い 無名関数 一々、ラムダ式を書くのが面倒。 (find-if (lambda (x) (= (length x) 2)) seq) Clojure  のような無名関数シンタックスが欲しい。そこで  cl-anonfun  を開発した。 (find-if #%(= (length %) 2) seq) 全く使ってない。
4. Lisp  との闘い 安易なマクロ (defview index () (markup (:html (:body (:h1 “Hello, World”)))) このコードの本当の意味を理解するには、 defview  マクロの正確な定義を知っていなければならない。この手のマクロを安易に書いてしまうことが多々ある。
4. Lisp  との闘い 安易なマクロ 図らずも  cl-annot  が良い解決策を与えた。 @view (defun index () ...) アノテーションは、物事に新しい側面(アスペクト)を追加する。その意味で、マクロとは本質的に別物。 ;;  参考: caveman @url GET “/” (defun index (params) ...)
4. Lisp  との闘い キャッシュ 特定の関数をキャッシュ( memoize )する仕組みがなかった。そこで  clache  を開発した。  load-time-value  と  cl-annot  のおかげで非常にシンプルな設計となった。 ;;  宝石 (defmacro with-cache (key &body body) (once-only (key) (with-gensyms (cache) `(let ((,cache (load-time-value (make-hash-table :test 'equal)))) (or (gethash ,key ,cache) (setf (gethash ,key ,cache) (locally ,@body)))))))
4. Lisp  との闘い キャッシュ (defun fact (x) (with-cache x (if (<= x 1) 1 (* x (fact (1- x)))))) @cache (x) (defun fact (x) (if (<= x 1) 1 (* x (fact (1- x)))))
4. Lisp  との闘い リストの型指定子 リストといっても、  proper list, improper list, association list, property list  があって、  proper list  にも  heterogeneous proper list  と  homogeneous proper list  がある。それらを全て単に  list  と呼ぶには無理がある。 (defun f (l) (declare (type list l)) ;; l  の詳しい型が読み手にもコンパイラにも伝わらない ...)
4. Lisp  との闘い リストの型指定子 そこで  trivial-types  を開発した。 (declare (type proper-list l)) (declare (type (proper-list fixnum) l)) (declare (type (asscoation-list string fixnum) l)) (declare (type (property-list fixnum) l)) 積極的に利用している。
4. Lisp  との闘い Web  フレームワーク UnCommon Web ドキュメント皆無、瀕死 Weblocks ドキュメント皆無、瀕死 SymbolicWeb ドキュメント皆無、死亡
4. Lisp  との闘い Web  フレームワーク どれもこれもイマイチ。結局、  Hunchentoot  ( HTTP  サーバー)を直接操作することになった。 その裏で、深町さんが  Clack&Caveman  プロジェクトを始動させる。 ;;  当時のコード (defview index () (markup (:html (:body (:h1 “Hello, World”)))) (defroutes map (GET “/” index))
4. Lisp  との闘い データベース 多数のライブラリが存在する。理想は  AllegroCache  のようなオブジェクトキャッシュデータベース。 オープンソースで現実的な選択肢は、 Elephant, CLSQL, Postmodern  の三つ。結局、 CLSQL  を選択。 その裏で、  Rucksack  のハックと、  CLSQL  を使った  ORM  の開発を始める。最終的には、どちらも頓挫。
4. Lisp  との闘い CLSQL  の問題点 1 リーダーマクロに強く依存。 (select [name] :from [employee] :where [> [salary] 1000]) ;;  上と同じ (select (sql-expression :attribute 'name) :from (sql-expression :attribute 'employee) :where (sql-operation '> (sql-expression :attribute 'salary) 1000))
4. Lisp  との闘い CLSQL  の問題点 1 SBCL+SLIME  の環境では、  CLSQL  のリーダーマクロを有効にする以下のコードが正しく動作しない。 (clsql:enable-sql-reader-syntax) そもそも、  Common Lisp  にはリーダーマクロをうまく管理する手段がなかった。そこで  cl-syntax  を開発した。 (use-syntax :clsql)  ; CLSQL  のリーダーマクロを有効にする (use-syntax :cl-interpol) ; CL-INTERPOL  の〃
4. Lisp  との闘い CLSQL  の問題点 2 SQL  生成、データベースアクセス、簡易的な  ORM  、キャッシュ機構など、多数のレイヤーがモノシリックに組み込まれている。そのくせ、カラムの追加といった  DDL  の基本的な操作が定義されていない。 そこで  clsql-ddl  を開発した。新たな  DDL  は  clsql  パッケージに挿入される。 (clsql:rename-table [foo] [bar])  ; FOO  を  BAR  に改名 (clsql:add-column [person] '([age] fixnum)) ; PERSON  に  AGE  を追加
4. Lisp  との闘い 要点 1 Common Lisp  には、よほどのコストを掛けない限り、どうしようもない問題がいくつも存在する(パッケージシステム、 CLOS 等)。言わば「言語とユーザーとの溝」。それらを改善するには、処理系の実装あるいは仕様の策定を待たなければならない。
4. Lisp  との闘い 要点 2 便利系マクロは使わなくなることが多い( cl-loop-plus, metabang-bind, cl-pattern, cl-anonfun )。 恒久的価値を持つその他のマクロとの違い。 ;;  参考:  Why I D on't Like EVAL-ALWAYS -- Nikodemus Siivola (defmacro eval-always (&body body) `(eval-when (:compile-toplevel :load-toplevel :execute) ,@body))
4. Lisp  との闘い 要点 3 抽象化が非常にうまくいくこともある( clache )。全ての歯車がぴったり一致し、その上に新たな基盤が作られる。
4. Lisp  との闘い 要点 4 マンパワーが分散しやすく、途切れやすい( Web フレームワーク、データベース)。開発者一人一人の好みが多様。皆、カウボーイプログラマー。  MIT/Stanford  スタイルの弊害?
5.  なぜ  Lisp  なのか
5.  なぜ  Lisp  なのか 標準化されているから? 部分的には  Yes. HyperSpec, CLtL2  は人類の宝。そこから得る価値は多大。ただ、要点 1 で示したように、古くなった標準は時に足枷となるし、標準だからと言って、必ずしも正しいとは限らない。
5.  なぜ  Lisp  なのか マクロがあるから? 部分的には  Yes.  要点 3 で示したように、抽象化が非常にうまくいくケースもある。ただ、要点 2 で示したように、マクロがあるからといって、プログラミングがうまくいくとは限らない。マクロは単なる手段であり、その先にあるもっと本質的なものに注目したほうがよい。
5.  なぜ  Lisp  なのか “ パワフル”だから? No.  そんな幻想はとっとと捨てるべき。例えば  Common Lisp  と  Haskell  をとってみて、どちらが”パワフル”か言えるだろうか?
5.  なぜ  Lisp  なのか ライブラリがたくさんあるから? No.  結論 4 で示したとおり。
5.  なぜ  Lisp  なのか “ Growing a Language” “ (プログラミング)言語は成長可能でなくてはならない”と主張する  Guy Steele  の論文および講演動画。 心の中で全ての問題が解決した気がした。
5.  なぜ  Lisp  なのか 本当の理由 Lisp  は真の意味で最も”言語”に近いプログラミング言語であるから。 プログラミング言語が成長可能であることに比べれば、括弧の数が多いとか、”パワフル”であるとか、ライブラリがしょぼいとか、その他諸々は些細な問題である。 実は皆、無意識に本当の理由を理解しているのではないか。
6. Lisper's Delight 私の経験 Common Lisp  をひとしきり書いたあとで、試しに  Emacs Lisp  を書いてみると、以前より捗るどころか、出来あがるソースコードが、なんとも美しい。 auto-complete.el  と  mongo.el  を比較。
6. Lisper's Delight 私の経験 汚ないソースコードを綺麗にリファクタリングできたときや、うまい抽象化によって、物事をより直感的に表現できたときの喜び、また、それらを達成できないときの苦痛。 Lisp  を書いているとき、人は自由になれる。他のプログラミング言語では、どこか囚われてしまう。
6. Lisper's Delight 手段と目的 手段と目的を、あえて取り違えてみよう。  Lisp  でプログラミングすることは目的であり、ソフトウェアを開発することは手段でしかない。
6. Lisper's Delight 気分は小説家 小説家になった気分でプログラミングしてみよう。  Lisp  は言語であり、あなたは  Lisp  で物事を考え、  Lisp  で表現することができる。 他人の作品をよんでインスピレーションを得たり、世間が驚く表現方法を発明したりして、互いを切磋琢磨し、より充実した  Lisp  の文化を築きましょう。
ありがとうございました

More Related Content

What's hot (20)

Pythonが動く仕組み(の概要)
Pythonが動く仕組み(の概要)Pythonが動く仕組み(の概要)
Pythonが動く仕組み(の概要)
Yoshiaki Shibutani
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
Preferred Networks
 
動的計画法を極める!
動的計画法を極める!動的計画法を極める!
動的計画法を極める!
HCPC: 北海道大学競技プログラミングサークル
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについて
mametter
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
 
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモAnaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
ayohe
 
zshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用するzshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用する
Hideaki Miyake
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
 
CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料
SECCON Beginners
 
Guide To AGPL
Guide To AGPLGuide To AGPL
Guide To AGPL
Mikiya Okuno
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
 
Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)
Masahiro Sakai
 
Pcapngを読んでみる
Pcapngを読んでみるPcapngを読んでみる
Pcapngを読んでみる
Yagi Shinnosuke
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門
masayoshi takahashi
 
研究室紹介スライド
研究室紹介スライド研究室紹介スライド
研究室紹介スライド
08fi134
 
PostgreSQLコミュニティに飛び込もう
PostgreSQLコミュニティに飛び込もうPostgreSQLコミュニティに飛び込もう
PostgreSQLコミュニティに飛び込もう
NTT DATA OSS Professional Services
 
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Hideki Takase
 
4章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 34章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 3
mao999
 
第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える
chonaso
 
Pythonが動く仕組み(の概要)
Pythonが動く仕組み(の概要)Pythonが動く仕組み(の概要)
Pythonが動く仕組み(の概要)
Yoshiaki Shibutani
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
Preferred Networks
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについて
mametter
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
 
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモAnaconda navigatorのアップデートが終わらないときの対処方法メモ
Anaconda navigatorのアップデートが終わらないときの対処方法メモ
ayohe
 
zshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用するzshでコマンドライン履歴を活用する
zshでコマンドライン履歴を活用する
Hideaki Miyake
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
 
CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料CTF for ビギナーズ ネットワーク講習資料
CTF for ビギナーズ ネットワーク講習資料
SECCON Beginners
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
 
Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)Introduction to Categorical Programming (Revised)
Introduction to Categorical Programming (Revised)
Masahiro Sakai
 
Pcapngを読んでみる
Pcapngを読んでみるPcapngを読んでみる
Pcapngを読んでみる
Yagi Shinnosuke
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門
masayoshi takahashi
 
研究室紹介スライド
研究室紹介スライド研究室紹介スライド
研究室紹介スライド
08fi134
 
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Hideki Takase
 
4章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 34章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 3
mao999
 
第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える
chonaso
 

Similar to 括弧への異常な愛情 または私は如何にして心配するのを止めてCommon Lispを愛するようになったか (20)

Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
Ransui Iso
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
Ransui Iso
 
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した
t-sin
 
cl-waffe2 実装
cl-waffe2 実装cl-waffe2 実装
cl-waffe2 実装
hiketteinya
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lisp
irix_jp
 
Proof and Emacs
Proof and EmacsProof and Emacs
Proof and Emacs
dico_leque
 
Scheme to x86コンパイラ
Scheme to x86コンパイラScheme to x86コンパイラ
Scheme to x86コンパイラ
Nobutaka Takushima
 
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
infinite_loop
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
dynamis
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
Ransui Iso
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Satoshi imai
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
mitim
 
安全なプログラムの作り方
安全なプログラムの作り方安全なプログラムの作り方
安全なプログラムの作り方
Kazuhiro Nishiyama
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISP
Masaomi CHIBA
 
Lisperはじめました
LisperはじめましたLisperはじめました
Lisperはじめました
Nobutada Matsubara
 
ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)
ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)
ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)
Fumiyuki Yoshida
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
Hiromi Ishii
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
Kent Ohashi
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)
Yoshifumi Yamaguchi
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
Ransui Iso
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
Ransui Iso
 
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した
t-sin
 
cl-waffe2 実装
cl-waffe2 実装cl-waffe2 実装
cl-waffe2 実装
hiketteinya
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lisp
irix_jp
 
Proof and Emacs
Proof and EmacsProof and Emacs
Proof and Emacs
dico_leque
 
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
infinite_loop
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
dynamis
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
Ransui Iso
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Satoshi imai
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
mitim
 
安全なプログラムの作り方
安全なプログラムの作り方安全なプログラムの作り方
安全なプログラムの作り方
Kazuhiro Nishiyama
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISP
Masaomi CHIBA
 
ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)
ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)
ちょっとOverlayfsの実装、読んでみました(A brief report of overlayfs source code reading)
Fumiyuki Yoshida
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
Hiromi Ishii
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
Kent Ohashi
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)
Yoshifumi Yamaguchi
 

Recently uploaded (13)

【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究
【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究
【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究
harmonylab
 
ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...
ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...
ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...
Industrial Technology Research Institute (ITRI)(工業技術研究院, 工研院)
 
【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究
【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究
【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究
harmonylab
 
Matching_Program_for_Quantum_Challenge_Overview.pdf
Matching_Program_for_Quantum_Challenge_Overview.pdfMatching_Program_for_Quantum_Challenge_Overview.pdf
Matching_Program_for_Quantum_Challenge_Overview.pdf
hirokiokuda2
 
2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長
2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長
2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長
CRI Japan, Inc.
 
PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...
PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...
PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...
NTT DATA Technology & Innovation
 
ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]
ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]
ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]
kota usuha
 
Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...
Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...
Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...
NTT DATA Technology & Innovation
 
ドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptx
ドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptxドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptx
ドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptx
ssuserfcafd1
 
IoT Devices Compliant with JC-STAR Using Linux as a Container OS
IoT Devices Compliant with JC-STAR Using Linux as a Container OSIoT Devices Compliant with JC-STAR Using Linux as a Container OS
IoT Devices Compliant with JC-STAR Using Linux as a Container OS
Tomohiro Saneyoshi
 
ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料
ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料
ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料
周 小渕
 
第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)
第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)
第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)
Matsushita Laboratory
 
実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)
実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)
実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)
NTT DATA Technology & Innovation
 
【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究
【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究
【卒業論文】LLMを用いたMulti-Agent-Debateにおける反論の効果に関する研究
harmonylab
 
ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...
ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...
ラズパイを使って作品を作ったらラズパイコンテストでKSY賞を貰って、さらに、文化庁メディア芸術祭で審査員推薦作品に選ばれてしまった件〜自作チップでラズパイ...
Industrial Technology Research Institute (ITRI)(工業技術研究院, 工研院)
 
【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究
【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究
【卒業論文】深層学習によるログ異常検知モデルを用いたサイバー攻撃検知に関する研究
harmonylab
 
Matching_Program_for_Quantum_Challenge_Overview.pdf
Matching_Program_for_Quantum_Challenge_Overview.pdfMatching_Program_for_Quantum_Challenge_Overview.pdf
Matching_Program_for_Quantum_Challenge_Overview.pdf
hirokiokuda2
 
2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長
2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長
2025フードテックWeek大阪展示会 - LoRaWANを使った複数ポイント温度管理 by AVNET玉井部長
CRI Japan, Inc.
 
PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...
PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...
PostgreSQL最新動向 ~カラムナストアから生成AI連携まで~ (Open Source Conference 2025 Tokyo/Spring ...
NTT DATA Technology & Innovation
 
ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]
ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]
ElasticsearchでSPLADEする [Search Engineering Tech Talk 2025 Winter]
kota usuha
 
Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...
Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...
Apache Sparkに対するKubernetesのNUMAノードを意識したリソース割り当ての性能効果 (Open Source Conference ...
NTT DATA Technology & Innovation
 
ドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptx
ドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptxドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptx
ドメインモデリング基本編①~全体の流れ2025_02_27社内向け開催.pptx
ssuserfcafd1
 
IoT Devices Compliant with JC-STAR Using Linux as a Container OS
IoT Devices Compliant with JC-STAR Using Linux as a Container OSIoT Devices Compliant with JC-STAR Using Linux as a Container OS
IoT Devices Compliant with JC-STAR Using Linux as a Container OS
Tomohiro Saneyoshi
 
ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料
ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料
ビットコインテストネットでの送金体験付きビットコイン・ブロックチェーン勉強会資料
周 小渕
 
第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)
第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)
第1回日本理学療法推論学会学術大会での発表資料(2025年3月2日 高橋可奈恵)
Matsushita Laboratory
 
実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)
実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)
実はアナタの身近にある!? Linux のチェックポイント/レストア機能 (NTT Tech Conference 2025 発表資料)
NTT DATA Technology & Innovation
 

括弧への異常な愛情 または私は如何にして心配するのを止めてCommon Lispを愛するようになったか

  • 1. 括弧への異常な愛情 または私は如何にして心配するのを止めて Common Lisp を愛するようになったか Shibuya.lisp テクニカル・トーク #7 アリエル・ネットワーク株式会社 松山朋洋
  • 2. アジェンダ 1. 自己紹介 2. Lisp に対する懐疑 3. Lisp を始めた経緯 4. Lisp との闘い 5. なぜ Lisp なのか 6. Lisper's Delight
  • 3. 1. 自己紹介 松山 朋洋 アリエル・ネットワーク株式会社 @m 2ym http://cx4a.org/ 好きなエディタ GNU Emacs 作ったもの auto-complete.el, popwin.el, popup.el, mongo.el, rsense, gccsense, xkeyremap, etc
  • 4. 1. 自己紹介 プログラミング言語遍歴 2002 年〜 C 2003 年 Visual Basic 6 2003 年〜 2008 年 C++ 2006 年〜 GNU Emacs 2007 年〜 2010 年 Java 2007 年〜 Emacs Lisp 2009 年〜 Ruby 2010 年〜 OCaml, Haskell, Common Lisp パラダイム 手続き型・オブジェクト指向型に触れた期間が長く、関数型 や Lisp に触れた期間は短い。
  • 5. 2. Lisp に対する懐疑
  • 6. 2. Lisp に対する懐疑 腑に落ちない啓蒙文書 Beating the Averages (Paul Graham), Revenge of the Nerds (Paul Graham), How to Become a Hacker (Eric Raymond), Let Over Lambda (Doug Hoyte), etc
  • 7. 2. Lisp に対する懐疑 キラーアプリケーションの少なさ それほど”パワフル”な言語なのに、キラーアプリケーションが少ない
  • 8. 2. Lisp に対する懐疑 コミュニティの小ささ それほど”魅力的”な言語なのに、そのコミュニティは小さい
  • 9. 2. Lisp に対する懐疑 標準化の停滞 それほど”人気”な言語なのに、なぜ標準化作業が停滞 ( Common Lisp )したり、遅々として進まない( Scheme )のか
  • 10. 2. Lisp に対する懐疑 Lisp の専売特許 ガベージコレクションやラムダ式、マクロの大部分はもはや Lisp の専売特許ではない
  • 11. 2. Lisp に対する懐疑 Emacs Lisp のひどさ ” 括弧だらけの C” 。これがあの ” Lisp” か?
  • 12. 3. Lisp を始めた経緯
  • 13. 3. Lisp を始めた経緯 会社で立ちあがった、あるプロジェクト 当初は Ruby on Rails か Pylons の二択で考えていた。 ところが、 Common Lisp はどうかと同僚の深町さんに勧誘され、とんとん拍子で決まってしまった。 これが悪夢の始まりであった。
  • 14. 4. Lisp との闘い
  • 15. 4. Lisp との闘い パッケージ パッケージの名前空間はグローバル。パッケージはモノシリックに設計するのが一般的。パッケージには以下の問題がある。 a. 名前衝突 b. ニックネーム c. 不本意な intern d. 面倒な export
  • 16. 4. Lisp との闘い a. 名前衝突 安易に use-package すると名前の衝突に弱くなるどころか、不可解なバグに悩まされる可能性がある。とはいっても一々 import するのも面倒。 (defpackage foobar (:use :cl :alexandria)) (defpackage foobar (:use :cl) (:import-from :alexandria ...))
  • 17. 4. Lisp との闘い b. ニックネーム パッケージにニックネーム(あるいは)を付ける合理的な権限を持つのは、パッケージ作成者のみ。 Haskell, OCaml, Python のように、パッケージに一時的に別名を与える手段がない。 -- Haskell - 可能 import qualified Data.Map as M ;; Common Lisp - 不可能 (defpackage foobar (:use :cl) (:rename :alexandria :alex))
  • 18. 4. Lisp との闘い b. ニックネーム また、パッケージを一時的に use-package することもで きない。 (* OCaml – 可能 *) let open List in rev (map (fun x -> succ x) [1; 2; 3]) ;; Common Lisp – 不可能 (with-use-package :alexandria (plist-alist (remove-from-plist '(:a 1 :b 2) :a))
  • 19. 4. Lisp との闘い c. 不本意な intern defpackage 中に不本意な intern が発生す る。 ;; *package* = cl-user と仮定 (defpackage foobar (:use *my-varaible* :my-function)) cl-user パッケージに foobar と *my-variable* 、 keyword パッケージに my-function が intern される。気にしたら負け。 (defpackage #:foobar ; 潔癖症 (:use #:*my-varaible* #:my-function))
  • 20. 4. Lisp との闘い d. 面倒な export export するのが結構面倒臭い。 ;; いちいち :export に追加 (defpackage foobar (:use :cl) (:export :foo :bar ...)) Clojure の defn/defn- に相当するものを用意するとか、 Go のようにシンボルが大文字で始まる場合にリーダーがそのシンボルを export するなど、手段は色々。
  • 21. 4. Lisp との闘い d. 面倒な export 一つの解決策として cl-annot を開発した。 @ に続く二つのフォームをリストで包んで返す簡単なリーダーマクロ。 CL-USER> '@1+ 2 (1+ 2) CL-USER> '@export (defun foo () ...) (progn (export 'foo) (defun foo () ...))
  • 22. 4. Lisp との闘い CLOS スロットアクセサの名前をどうするかは実は難しい問題。パッケージシステムに関連する問題でもある。 of 派、 prefix 派、 keyword 派があり、それぞれ一長一短。
  • 23. 4. Lisp との闘い CLOS ;; of 派 (defclass person () ((name :accessor name-of) (age :accessor age-of))) (name-of bob) => “Bob” (age-of bob) => 42 アクセサが総称関数であることのメリットを生かせるが、名前衝突しやすい。
  • 24. 4. Lisp との闘い CLOS ;; prefix 派 (defclass person () ((name :accessor person-name) (age :accessor person-age))) (person-name bob) => “Bob” (person-age bob) => 42 名前衝突の危険性は少ないが、冗長。また、継承したクラスのインスタンスに使う場合に、少し違和感がある。
  • 25. 4. Lisp との闘い CLOS ;; keyword 派 (defclass person () ((name :accessor :name) (age :accessor :age))) (:name bob) => “Bob” (:age bob) => 42 keyword パッケージをグローバル名前空間に見立てるテクニック。使い勝手としてはダックタイピングに近くなるが、慣習として定着しなければ、さまざまな危険性を伴う。
  • 26. 4. Lisp との闘い multiple-value-bind ネストした multiple-value-bind をもっと簡単に書きたい。 (multiple-value-bind (a b) (values 1 2) (multiple-value-bind (c d) (values 3 4) (+ a b c d)))
  • 27. 4. Lisp との闘い multiple-value-bind マクロを自作したが、後に metabang-bind がまさにそれだと知った。 (metabang-bind:bind ((values a b) (values 1 2)) (values c d) (values 3 4))) (+ a b c d)) しかし全く使ってない。
  • 28. 4. Lisp との闘い パターンマッチング metabang-bind や cl-pattern でも可能だが、より高速な ML 風のパターンマッチングが欲しかったため、 cl-pattern (後に cl-adt に統合)を開発した。 (match '(“Bob” 42) ((list “Alice” 30) :alice-30) ((list “Alice” 40) :alice-40) ((list “Bob” 30) :bob-30) ((list “Bob” 42) :bob-42)) しかし全く使ってない。
  • 29. 4. Lisp との闘い loop 痒いところに手が届かない loop 。特に、返り値に対して任意の変換を行えないことに不満を感じ、 cl-loop-plus を開発した。 (defun vectorize (seq &optional (element-type '*)) (coerce seq `(vector ,element-type))) (loop for i from 0 below 100 by 2 collect i transform #'vectorize) 全く使わなかったため、廃棄。パーサー部分は cl-ast にマージ。複雑な loop は iterate で。
  • 30. 4. Lisp との闘い 無名関数 一々、ラムダ式を書くのが面倒。 (find-if (lambda (x) (= (length x) 2)) seq) Clojure のような無名関数シンタックスが欲しい。そこで cl-anonfun を開発した。 (find-if #%(= (length %) 2) seq) 全く使ってない。
  • 31. 4. Lisp との闘い 安易なマクロ (defview index () (markup (:html (:body (:h1 “Hello, World”)))) このコードの本当の意味を理解するには、 defview マクロの正確な定義を知っていなければならない。この手のマクロを安易に書いてしまうことが多々ある。
  • 32. 4. Lisp との闘い 安易なマクロ 図らずも cl-annot が良い解決策を与えた。 @view (defun index () ...) アノテーションは、物事に新しい側面(アスペクト)を追加する。その意味で、マクロとは本質的に別物。 ;; 参考: caveman @url GET “/” (defun index (params) ...)
  • 33. 4. Lisp との闘い キャッシュ 特定の関数をキャッシュ( memoize )する仕組みがなかった。そこで clache を開発した。 load-time-value と cl-annot のおかげで非常にシンプルな設計となった。 ;; 宝石 (defmacro with-cache (key &body body) (once-only (key) (with-gensyms (cache) `(let ((,cache (load-time-value (make-hash-table :test 'equal)))) (or (gethash ,key ,cache) (setf (gethash ,key ,cache) (locally ,@body)))))))
  • 34. 4. Lisp との闘い キャッシュ (defun fact (x) (with-cache x (if (<= x 1) 1 (* x (fact (1- x)))))) @cache (x) (defun fact (x) (if (<= x 1) 1 (* x (fact (1- x)))))
  • 35. 4. Lisp との闘い リストの型指定子 リストといっても、 proper list, improper list, association list, property list があって、 proper list にも heterogeneous proper list と homogeneous proper list がある。それらを全て単に list と呼ぶには無理がある。 (defun f (l) (declare (type list l)) ;; l の詳しい型が読み手にもコンパイラにも伝わらない ...)
  • 36. 4. Lisp との闘い リストの型指定子 そこで trivial-types を開発した。 (declare (type proper-list l)) (declare (type (proper-list fixnum) l)) (declare (type (asscoation-list string fixnum) l)) (declare (type (property-list fixnum) l)) 積極的に利用している。
  • 37. 4. Lisp との闘い Web フレームワーク UnCommon Web ドキュメント皆無、瀕死 Weblocks ドキュメント皆無、瀕死 SymbolicWeb ドキュメント皆無、死亡
  • 38. 4. Lisp との闘い Web フレームワーク どれもこれもイマイチ。結局、 Hunchentoot ( HTTP サーバー)を直接操作することになった。 その裏で、深町さんが Clack&Caveman プロジェクトを始動させる。 ;; 当時のコード (defview index () (markup (:html (:body (:h1 “Hello, World”)))) (defroutes map (GET “/” index))
  • 39. 4. Lisp との闘い データベース 多数のライブラリが存在する。理想は AllegroCache のようなオブジェクトキャッシュデータベース。 オープンソースで現実的な選択肢は、 Elephant, CLSQL, Postmodern の三つ。結局、 CLSQL を選択。 その裏で、 Rucksack のハックと、 CLSQL を使った ORM の開発を始める。最終的には、どちらも頓挫。
  • 40. 4. Lisp との闘い CLSQL の問題点 1 リーダーマクロに強く依存。 (select [name] :from [employee] :where [> [salary] 1000]) ;; 上と同じ (select (sql-expression :attribute 'name) :from (sql-expression :attribute 'employee) :where (sql-operation '> (sql-expression :attribute 'salary) 1000))
  • 41. 4. Lisp との闘い CLSQL の問題点 1 SBCL+SLIME の環境では、 CLSQL のリーダーマクロを有効にする以下のコードが正しく動作しない。 (clsql:enable-sql-reader-syntax) そもそも、 Common Lisp にはリーダーマクロをうまく管理する手段がなかった。そこで cl-syntax を開発した。 (use-syntax :clsql) ; CLSQL のリーダーマクロを有効にする (use-syntax :cl-interpol) ; CL-INTERPOL の〃
  • 42. 4. Lisp との闘い CLSQL の問題点 2 SQL 生成、データベースアクセス、簡易的な ORM 、キャッシュ機構など、多数のレイヤーがモノシリックに組み込まれている。そのくせ、カラムの追加といった DDL の基本的な操作が定義されていない。 そこで clsql-ddl を開発した。新たな DDL は clsql パッケージに挿入される。 (clsql:rename-table [foo] [bar]) ; FOO を BAR に改名 (clsql:add-column [person] '([age] fixnum)) ; PERSON に AGE を追加
  • 43. 4. Lisp との闘い 要点 1 Common Lisp には、よほどのコストを掛けない限り、どうしようもない問題がいくつも存在する(パッケージシステム、 CLOS 等)。言わば「言語とユーザーとの溝」。それらを改善するには、処理系の実装あるいは仕様の策定を待たなければならない。
  • 44. 4. Lisp との闘い 要点 2 便利系マクロは使わなくなることが多い( cl-loop-plus, metabang-bind, cl-pattern, cl-anonfun )。 恒久的価値を持つその他のマクロとの違い。 ;; 参考: Why I D on't Like EVAL-ALWAYS -- Nikodemus Siivola (defmacro eval-always (&body body) `(eval-when (:compile-toplevel :load-toplevel :execute) ,@body))
  • 45. 4. Lisp との闘い 要点 3 抽象化が非常にうまくいくこともある( clache )。全ての歯車がぴったり一致し、その上に新たな基盤が作られる。
  • 46. 4. Lisp との闘い 要点 4 マンパワーが分散しやすく、途切れやすい( Web フレームワーク、データベース)。開発者一人一人の好みが多様。皆、カウボーイプログラマー。 MIT/Stanford スタイルの弊害?
  • 47. 5. なぜ Lisp なのか
  • 48. 5. なぜ Lisp なのか 標準化されているから? 部分的には Yes. HyperSpec, CLtL2 は人類の宝。そこから得る価値は多大。ただ、要点 1 で示したように、古くなった標準は時に足枷となるし、標準だからと言って、必ずしも正しいとは限らない。
  • 49. 5. なぜ Lisp なのか マクロがあるから? 部分的には Yes. 要点 3 で示したように、抽象化が非常にうまくいくケースもある。ただ、要点 2 で示したように、マクロがあるからといって、プログラミングがうまくいくとは限らない。マクロは単なる手段であり、その先にあるもっと本質的なものに注目したほうがよい。
  • 50. 5. なぜ Lisp なのか “ パワフル”だから? No. そんな幻想はとっとと捨てるべき。例えば Common Lisp と Haskell をとってみて、どちらが”パワフル”か言えるだろうか?
  • 51. 5. なぜ Lisp なのか ライブラリがたくさんあるから? No. 結論 4 で示したとおり。
  • 52. 5. なぜ Lisp なのか “ Growing a Language” “ (プログラミング)言語は成長可能でなくてはならない”と主張する Guy Steele の論文および講演動画。 心の中で全ての問題が解決した気がした。
  • 53. 5. なぜ Lisp なのか 本当の理由 Lisp は真の意味で最も”言語”に近いプログラミング言語であるから。 プログラミング言語が成長可能であることに比べれば、括弧の数が多いとか、”パワフル”であるとか、ライブラリがしょぼいとか、その他諸々は些細な問題である。 実は皆、無意識に本当の理由を理解しているのではないか。
  • 54. 6. Lisper's Delight 私の経験 Common Lisp をひとしきり書いたあとで、試しに Emacs Lisp を書いてみると、以前より捗るどころか、出来あがるソースコードが、なんとも美しい。 auto-complete.el と mongo.el を比較。
  • 55. 6. Lisper's Delight 私の経験 汚ないソースコードを綺麗にリファクタリングできたときや、うまい抽象化によって、物事をより直感的に表現できたときの喜び、また、それらを達成できないときの苦痛。 Lisp を書いているとき、人は自由になれる。他のプログラミング言語では、どこか囚われてしまう。
  • 56. 6. Lisper's Delight 手段と目的 手段と目的を、あえて取り違えてみよう。 Lisp でプログラミングすることは目的であり、ソフトウェアを開発することは手段でしかない。
  • 57. 6. Lisper's Delight 気分は小説家 小説家になった気分でプログラミングしてみよう。 Lisp は言語であり、あなたは Lisp で物事を考え、 Lisp で表現することができる。 他人の作品をよんでインスピレーションを得たり、世間が驚く表現方法を発明したりして、互いを切磋琢磨し、より充実した Lisp の文化を築きましょう。