SlideShare uma empresa Scribd logo
1 de 58
括弧への異常な愛情 または私は如何にして心配するのを止めて 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  の文化を築きましょう。
ありがとうございました

Mais conteúdo relacionado

Mais procurados

Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境Satoshi imai
 
フィルタドライバ入門
フィルタドライバ入門フィルタドライバ入門
フィルタドライバ入門firewood
 
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記心 谷本
 
とある診断員とSQLインジェクション
とある診断員とSQLインジェクションとある診断員とSQLインジェクション
とある診断員とSQLインジェクションzaki4649
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
PHPの今とこれから2022
PHPの今とこれから2022PHPの今とこれから2022
PHPの今とこれから2022Rui Hirokawa
 
PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会
PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会
PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会Shigeru Hanada
 
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門Hirotaka Kawata
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニングyoku0825
 
名は体を表していますか
名は体を表していますか名は体を表していますか
名は体を表していますかinfinite_loop
 
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015Masahiro Nagano
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達zaki4649
 
脱RESTful API設計の提案
脱RESTful API設計の提案脱RESTful API設計の提案
脱RESTful API設計の提案樽八 仲川
 
react-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのかreact-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのか暁 三宅
 
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-Saki Homma
 
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニックinfinite_loop
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについてTomoya Kawanishi
 
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題
ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題
ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題Hiroshi Tokumaru
 

Mais procurados (20)

Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境Portacle : Common Lispのオールインワン開発環境
Portacle : Common Lispのオールインワン開発環境
 
フィルタドライバ入門
フィルタドライバ入門フィルタドライバ入門
フィルタドライバ入門
 
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
 
とある診断員とSQLインジェクション
とある診断員とSQLインジェクションとある診断員とSQLインジェクション
とある診断員とSQLインジェクション
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
PHPの今とこれから2022
PHPの今とこれから2022PHPの今とこれから2022
PHPの今とこれから2022
 
PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会
PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会
PostgreSQLのトラブルシューティング@第5回中国地方DB勉強会
 
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
 
名は体を表していますか
名は体を表していますか名は体を表していますか
名は体を表していますか
 
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015ISUCONの勝ち方 YAPC::Asia Tokyo 2015
ISUCONの勝ち方 YAPC::Asia Tokyo 2015
 
とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達とある診断員と色々厄介な脆弱性達
とある診断員と色々厄介な脆弱性達
 
脱RESTful API設計の提案
脱RESTful API設計の提案脱RESTful API設計の提案
脱RESTful API設計の提案
 
react-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのかreact-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのか
 
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
はじめてのAzure Web App for Containers! -コンテナの基礎から DevOps 環境の構築まで-
 
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
 
入門 シェル実装
入門 シェル実装入門 シェル実装
入門 シェル実装
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについて
 
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
 
ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題
ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題
ウェブ・セキュリティ基礎試験(徳丸基礎試験)の模擬試験問題
 

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

Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Ransui Iso
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Ransui Iso
 
cl-waffe2 実装
cl-waffe2 実装cl-waffe2 実装
cl-waffe2 実装hiketteinya
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lispirix_jp
 
Proof and Emacs
Proof and EmacsProof and Emacs
Proof and Emacsdico_leque
 
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~infinite_loop
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Nextdynamis
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめSatoshi imai
 
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフトobjc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフトTaketo Sano
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Rubymitim
 
安全なプログラムの作り方
安全なプログラムの作り方安全なプログラムの作り方
安全なプログラムの作り方Kazuhiro Nishiyama
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISPMasaomi CHIBA
 
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 ClojureKent Ohashi
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)Yoshifumi Yamaguchi
 

Semelhante a 括弧への異常な愛情 または私は如何にして心配するのを止めて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
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
cl-waffe2 実装
cl-waffe2 実装cl-waffe2 実装
cl-waffe2 実装
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lisp
 
Proof and Emacs
Proof and EmacsProof and Emacs
Proof and Emacs
 
Scheme to x86コンパイラ
Scheme to x86コンパイラScheme to x86コンパイラ
Scheme to x86コンパイラ
 
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
大規模ソーシャルゲームを支える技術~PHP+MySQLを使った高負荷対策~
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
 
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフトobjc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
objc2swift 〜 Objective-C から Swift への「コード&パラダイム」シフト
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
安全なプログラムの作り方
安全なプログラムの作り方安全なプログラムの作り方
安全なプログラムの作り方
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISP
 
Lisperはじめました
LisperはじめましたLisperはじめました
Lisperはじめました
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
 
20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)20130228 Goノススメ(BPStudy #66)
20130228 Goノススメ(BPStudy #66)
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 

Último

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 

Último (8)

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 

括弧への異常な愛情 または私は如何にして心配するのを止めて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 の文化を築きましょう。