Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2010-12-31

2010年を振り返る

| 18:02 | 2010年を振り返る - わだばLisperになる を含むブックマーク はてなブックマーク - 2010年を振り返る - わだばLisperになる

今年もだらだらと、まとめエントリーを書いてみたいと思います。

1月

2009年の12月からLISP365を開始した影響で毎日のようにKMRCLを眺める記事が載っています。

今年一年KMRCLのお蔭でエントリーを量産できました…。

Shibuya.lispのコードバトンにも参加していました。

2月

ほぼKMRCLを読んでるだけの月のようです。

3月

Shibuya.lisp TT#5開催

この月もほぼKMRCLを読んでるだけのようです。

4月

さすがにKMRCLばかりではまずいと思ったのか、CiNiiなどのLISP関係の論文を読み漁り始めていたようです。

80年代後半の論文には、知らなかったCLの処理系が結構載っていたりして発見が多かったです。

5月

どうやら発掘熱が高まっていた月のようです。

6月

7月

8月にTAO/ELIS復活祭があるので、TAO/ELISの論文を中心に読んでいたようです。

8月

東京から電車で片道5時間。JAISTまでELISが実働する様を目にしてまいりました。

復活祭では、Tachyon CLや、ELISの開発の方々とお話させて頂く機会があり、これが縁で大野さんには、Shibuya.lisp TT#6でお話頂くこととなりました。

Tachyon CLや、TAO/ELISでもちらほら動きがあるとかないとか、今後が楽しみです。

いつもアイデアを頂いているSmiley Hackathonですが、#9の会場が素晴らしく、この流れで、Shibuya.lisp Hackathon #1が企画されることとなりました。

Planet Common Lisp 日本 超手抜き版は恐らく自分が一番愛用していますが、質/量ともに充実しつつある気がしています。まあ、勝手に自分が集めて眺めて、にやにやしてるんですが…。

9月

KMRCLを眺めるのも段々行き詰まってきた頃だったと思います。

10月

先1年に渡り、繰り返しの構文は、Seriesを使う、ということに決めたため、Seriesの話題が多くなっているようです。

11月

Shibuya.lisp TT#6も無事開催されました。

  • 2日間まるごとLISPセミナー 2010 1/2日目参加

この月は、Seriesについてが多いです。

ちなみに、LAMBDAを使うなスタイル(2)が書かれていませんが、本質的な問題としては、繰り返しが最適化されるかどうかというより、関数として渡されたLAMBDA式のオーバーヘッドが最適化によって無くなるかどうかを調べないといけないですよねw

12月

KMRCLにつづいて、com.informatimago.common-lispを眺め始めたりしています。

また、CLAPにも参加してみました。

まとめ

ふりかえってみると、KMRCLまみれな一年でした。

全然関連した話題ではないですが、この3、4年位で眺めたところでは、今年は、新しくCommon Lispを始める人が増える傾向にあると思いました。

純粋関数型言語の擡頭で関数型言語を学ぶためにCommon Lisp/Schemeを選択する、という人は減っているとは思いますが、どういう理由でか地味に増えている気がします。

来年は、初心に返って誰得度の高い一年にしたいと思っています。

また、積み残しが沢山あるので、これらもこなせると良いなと思ったりしています。

来年も続けるであろうこと

  • Shibuya.lisp 運営
  • 逆引きCL運営
  • cddddr.org (みんなのLISPサーバ)運用
  • common-lisp-users.jp 運用

やりたいと思ってずっと積み残っているもの

  • 家の積読LISP本完読
  • Symbolicsのマニュアル読破
  • JLUGサイト改善
  • みんなでLISPを勉強するブログ
  • オンライン勉強会復活
  • L-99完遂
  • Getting Started in *Lisp (*Lispのチュートリアル)完遂
  • CLで学ぶ「プログラミングGauche」 完遂
  • AMOPの勉強
  • ObjectLispがANSI CLで動くようにする
  • CommonObjectsがANSI CLで動くようにする
  • INTERLISPで遊ぶ

2010-09-24

大文字でコードを書くようになって丸1年経過しました

| 00:39 | 大文字でコードを書くようになって丸1年経過しました - わだばLisperになる を含むブックマーク はてなブックマーク - 大文字でコードを書くようになって丸1年経過しました - わだばLisperになる

私が大文字でコードを書くようになったのは、ZmacsのElectric Shift LockモードがEmacsで再現されているのを発見したときからで、そのエントリーをブログに書いてから1年経過しました。

大文字で一年書いてみて発見できた長所ですが、Lが大文字だと他の文字と区別が付きやすい

(defun fool1 (l)
  (if (null l)
      1
      (list l)))
;; vs

(DEFUN FOOL1 (L)
  (IF (NULL L)
      1
      (LIST L)))

という1点のみでした。

あとは、コードの見た目が逞しくなる、昔の大文字で書かれたコードを読んでもなんの違和感がない等のメリットがあるでしょうか。

デメリットとしては、ブログの例にあるコードが読み難いという声を頂くことがあり、d:id:miyamuko さんには、自前で小文字版のRSSフィードを作って読んでいると教えて頂きました。

ありがとうございますw

また、小文字に戻そうかなあとも思いますが、せっかく大文字で書くのに馴れたので、ちょっと寂しいですし、今度は、混在スタイルや、先頭は大文字にするスタイルを試してみようかなあと思っています。

;; 混在スタイル
(defun FOO (N)
  ...)

;; 先頭大文字スタイル
(Defun Foo (N)
  ...)

そういえば、先日の数理システムのセミナーで竹内先生が、黒田さんのno titleを読んで、CLの大文字小文字を区別しないのが良いというところにこだわりがあるのに感心した、というお話を思い出しました。

TAOでも大文字小文字を区別しないようですが、出力は、小文字にしているそうです。大文字で出力されると読みにくくて嫌とのことでした。

2010-09-23

KEYで再帰的に自分を呼ぶ

| 20:34 | KEYで再帰的に自分を呼ぶ - わだばLisperになる を含むブックマーク はてなブックマーク - KEYで再帰的に自分を呼ぶ - わだばLisperになる

(MYSUM '(1 (2 ((3) 4)) (5 6 7) 8 9 0))
;⇒ 45

こういうのを考える場合に、FLATTENして、(APPLY #'+)かなとも思うのですが、

(DEFUN MYSUM (TREE)
  (REDUCE #'+ TREE :KEY (LAMBDA (X)
                          (IF (CONSP X) (MYSUM X) X))))

こういうのはどうでしょう。

もっと汎用的にして、

(DEFUN KEY* (FN)
  (LAMBDA (X)
    (IF (CONSP X) (FUNCALL FN X) X)))

(DEFUN MYSUM (TREE)
  (REDUCE #'+ TREE :KEY (KEY* #'MYSUM)))

という風にしたら、REDUCE以外にも使えて便利!!

…と思ったのですが、そうでもありませんでした。

2010-09-19

Common Lispメモ

| 22:43 | Common Lispメモ - わだばLisperになる を含むブックマーク はてなブックマーク - Common Lispメモ - わだばLisperになる

そういえば、こういう書き方もできるのか

(TYPECASE 3
  ((SATISFIES EVENP) 'EVEN)
  ((SATISFIES ODDP) 'ODD))
;⇒ ODD

2009-12-31

2009年を振り返る

| 23:36 | 2009年を振り返る - わだばLisperになる を含むブックマーク はてなブックマーク - 2009年を振り返る - わだばLisperになる

今年もまとめエントリーを書いてみたいと思います。

1月

  • みんなでLISPを勉強するブログ に参加
  • CL勉強会を30回目にして一旦終了としました。

しかし、また、オンライン勉強会やりたいです

2月

  • Shibuya.lisp TT#2
  • 第4回 Smiley hackathonに参加

LISP以外のコミュニティに初参加してみましたが、色々な視点が全然違うので非常に面白かったです。

3月

  • ひきこもり資金が尽きたため社会復帰
  • ILC2009のDavid Moon氏のPLOT発表に興奮していました。

今ではすっかり忘れていますw

  • Smiley HackathonにインスパイアされたSlimy Hackathonをオンラインで2日間/48時間開催しました

まったく期待してなかったのに何故か成果物が多かったです。不思議なものです。

4月

社会復帰直後のため、更新が滞っていました

その割には、Let Over Lambda読書会等には参加していたようです

5月

  • Lingr->Chatonへの移行記念に、CL勉強会をちょっと復活させてみようと思いましたが、企画倒れに終りました

私の気合いが足りなかったようですw

  • Common Lispの本はどれだけ日本で出版されているのかを適当に纒めてみましたが、何故か好評でした

6月

CiNiiでLISP系の論文を探して読んでそれをネタにエントリーを書いたりしていました

7月

  • 第5回Smiley Hackathon 参加
  • Shibuya.lisp TT#3

オンライン参加ではどういうことになるのか体験してみたり

8月

夏バテのためかエントリー激減

  • 第6回Smiley Hackathon 参加

9月

何故か、オレオレ構文を作る熱が復活し、妙な構文を量産しはじめていたようです。

10月

  • KMRCLを読み始めました
  • 日常のちょっとした作業を諦めずCLで書くように心掛けはじめました

11月

延々とKMRCLのエントリーが続きます

  • Shibuya.lisp TT#5
  • 数理システム LISPセミナー

LISPセミナーはまとめ記事を書こう書こうと思っていましたが、結局まとれられていません…。

12月

先月に引き続き延々とKMRCLのエントリーです。

  • LISP365とかいう毎日LISPの話題をお届けるという企画を実行することにしました

参加者のみなさんの面白いエントリーが読めたので良かったかなと思います。

まとめ

今年1年と、2年前(2007)の自分のブログを比べて眺めてみると、昔の方が今のエントリーより内容が偏っていて自分自身では面白いと感じます。

また、きちんとアイデアを纒めて書ききれてないせいか、書いたことを忘れてしまい、それを再発見してまたエントリーにしていることも多くなって来た気がしました。

来年は、もうちょっと偏った内容にできたら良いなあと思っています。

また、この2、3年で蓄積した情報がをまとめ切れていなかったり、立ち上げたもの中途半端になっているものが多くあるので来年は纒める年にしたいなとも思いました。

2009-10-19

悲しいけど、これで間にあっちゃったのよね…

| 22:36 | 悲しいけど、これで間にあっちゃったのよね… - わだばLisperになる を含むブックマーク はてなブックマーク - 悲しいけど、これで間にあっちゃったのよね… - わだばLisperになる

なんらかの入力を二つに分けて文字列のリストにしたいという場面に遭遇したのですが、汚ないなーと思いながらも

; "0123456789...." ⇒
(LET (ANS)
  (PUSH
   (WITH-OUTPUT-TO-STRING (A-OUT)
     (PUSH
      (WITH-OUTPUT-TO-STRING (B-OUT)
        ...
        (PRINC I (IF PRED A-OUT B-OUT)))
        ...
      ANS))
   ANS))
;⇒ ("02468..." "13579...")

のように書いて間に合わせてしまいまいした。

(WITH-OUTPUT-TO-STRINGS (A-OUT B-OUT)
  ...
  (PRINC I (IF (EVENP I) A-OUT B-OUT))
  ...
  ))

みたいなマクロを定義するのも、そんなに遭遇するパターンでもないし面倒臭かったんですが、こういうのをすっきり書ける方法ありますでしょうか('-'*)

SERIESかな?

2009-10-08

謎のこだわり 'Tと()

| 00:22 | 謎のこだわり 'Tと() - わだばLisperになる を含むブックマーク はてなブックマーク - 謎のこだわり 'Tと() - わだばLisperになる

全く誰も興味がない話題だと思うのですが、MacLISPのソースコードを眺めているとどういう訳か、NILという表記が少なく、()と書かれている割合が多いようです。

そして、Tは、クォートされて'Tと書かれていることが多い気がします。

どんな感じかというと

(DEFUN CHMP1 (X)                                ;"CHOMP" one function
       (SETQ DATA (GETL X '(EXPR FEXPR)) CFVFL () LAPLL () )
       (COMPILE X (CAR DATA) (CADR DATA) () () )
       (LAP-A-LIST (SETQ LAPLL (NREVERSE LAPLL)))
       (AND (COND ((SYSP X) 
                   (AND (SETQ DATA (GETL X '(EXPR FEXPR SUBR FSUBR LSUBR)))
                        (MEMQ (CAR DATA) '(EXPR FEXPR))
                        (SETQ DATA '(SUBR FSUBR LSUBR))))
                  ('T (AND (SETQ DATA (GETL X '(*EXPR *FEXPR *LEXPR SUBR FSUBR LSUBR)))
                           (MEMQ (CAR DATA) '(SUBR FSUBR LSUBR))
                           (SETQ DATA '(*EXPR *FEXPR *LEXPR)))))
            (SETQ DATA (CAR (GETL X DATA)))
            (PUTPROP X (CAR (REMPROP X DATA)) DATA)))

のような感じなのですが、condのelse節に'Tが使われていて、nilと書きそうなところも()です。

どうもMacLISPのメインメンテナだったJonL White氏が触ったところは、こういう風にNIL ⇒ ()、T ⇒ 'Tのスタイルで書かれているんじゃないかと思われ、全体として()の割合が多くなっている気がするのですが、一体どういう理由でこうなのかが謎です。

ちょろっとある更新記録にも

;;; 01/29/81 jonl - flushed (STATUS FEATURE MACAID) and NIL --> () 
;;;                 added special declaration for GRIND-MACROEXPANDED
;;; 05/25/78 jonl - Had GRINDEF and SPRINTER lambda-bind variable LINEL, and 
;;;                 removed all references to CONNIVER and PLANNER stuff.
;;;                 Flush "SGPLOSES" and NOARGS calls; flush GBREAK.
;;;                 Change "NIL" into "()".

などと書かれています。そんなに()が好きなのか。もしくは、NILが嫌いなのか。GRINDEFのファイルだけにプリティプリンタの挙動か。それとも単なる偶然か。

MacLISPのソースは、

にありますので、興味のある方は覗いてみて下さい。

また、真相をご存知の方は是非教えて下さい!

ちなみに、Tにクォートを付けるのは真似してやってみたら割と癖になってしまい、自分がLISPを書き始めた頃から大体これで書くようになってしまいました。CONDのelse節に使うと目立つのが気に入ってますが、他に良いことは別にないです。あえて言うなら、クォートを付けると私の中ではブール値っぽさが増します。NILも全部()で書いてみたら何か発見があるのかもしれない…。

2009-10-03

Common Lispで日常のちょっとした仕事

| 23:37 | Common Lispで日常のちょっとした仕事 - わだばLisperになる を含むブックマーク はてなブックマーク - Common Lispで日常のちょっとした仕事 - わだばLisperになる

昔のブログのエントリーを新しくWordPressに移行するためにデータの中のURLを書き換える、というちょっとした仕事があったのですが、最初sedでやってみました。

一緒に仕事をしているWebデザイナーさんに

「やっぱりLISPでやったんですか?」と訊かれたんですが、

「いや、これは別の言語でやりました」

と答えたのが妙に心残りだったのでCLで書いてみました(笑)

やりたいことは、

MovableType形式のバックアップデータのエントリー中の画像リンクのURLの変換です。

"http://example.com/imgs/1/2/3/abcd.jpg"という形式なのですが、

"http://new.example.com/wp-content/uploads/imgs/1_2_3_abcd.jpg"という風に直します。

いざ、書いてみると、sed並に簡単に書けたりするので割と悪くないなと思います。

ただ、ちょっとしたものを書くにはwith-open-fileは長いので、Arc風にw/outfileなどのマクロを定義して置くともっと手軽に書き捨てられるかと。

…というか多少面倒でもCLで書いて行こうと誓いました(笑)

どういう作業形態になるかというと、下記のようなものをSlime上のバッファに書いて、適当に評価するという感じになります。

Emacsのスクラッチと大体似た感覚で、UNIXのシェルで色々やるのとは、ちょっと違った感じですが、慣れるとこれはこれで良い感じです。

;; ファイルを文字列のリストとしてとりこむ
(DEFVAR *OLD-BLOG* (KMRCL:READ-FILE-TO-STRINGS "/home/mc/Desktop/blog-backup.txt"))

;; CL-PPCRE:REGEX-REPLACE-ALLで使う関数("/"を"_"に変換する)
(DEFUN /->_ (MATCH 1ST 2ND)
  (DECLARE (IGNORE MATCH 1ST))
  (FORMAT NIL "~A" (SUBSTITUTE #\_ #\/ 2ND)))

;; これを評価
(LET ((SCANNER (PPCRE:CREATE-SCANNER "\"\\s*http://(image.)*example.com/imgs/([^\"]*)\""))
      (REPLACE (LIST "\"/wp-content/uploads/imgs/" #'/->_ "\"")))
  (WITH-OPEN-FILE (OUT "/tmp/result.txt" :DIRECTION :OUTPUT :IF-EXISTS :SUPERSEDE)
    (DOLIST (LINE *OLD-BLOG*)
      (FORMAT OUT 
              "~A~%"
              (PPCRE:REGEX-REPLACE-ALL SCANNER LINE REPLACE :SIMPLE-CALLS 'T)))))

2009-09-29

CLでClojureのキーワードが関数(マクロ)になってる風(2)

| 23:20 | CLでClojureのキーワードが関数(マクロ)になってる風(2) - わだばLisperになる を含むブックマーク はてなブックマーク - CLでClojureのキーワードが関数(マクロ)になってる風(2) - わだばLisperになる

前回のエントリーのコメント欄で、ローカルのsetf関数は普通にfletで書けることをquekさんに教えて頂きました。

自分も試したつもりだったのですが、どうも入れ子にする括弧の数か引数の取り方を間違えていたようです…。

HyperSpecにもちゃんと書いてあるしちゃんと確認すれば良かったなと('-'*)

滅多に使わなそうですが、ローカルのsetf関数は書けるんですねー。

(FLET (((SETF HELLO) (VAL &OPTIONAL VAR)
         (LIST 'HELLO VAL)))
  (SETF (HELLO) 'WORLD))
;⇒ (HELLO WORLD)

(LABELS (((SETF HELLO) (VAL &OPTIONAL VAR)
           (LIST 'HELLO VAL)))
  (SETF (HELLO) 'WORLD))
;⇒ (HELLO WORLD)

ということで関数版も書いてみました。

(IMPORT 'KMRCL:FLATTEN)

(DEFMACRO WITH-KEYWORD-FUNCTION (&BODY BODY)
  (LET ((KEYS (COLLECT-KEYWORD-SYMBOL BODY)))
    `(FLET (,@(MAPCAN (LAMBDA (K)
                        (COPY-LIST
                         `((,K (HASH-TABLE &OPTIONAL DEFAULT)
                               (GETHASH ,K HASH-TABLE DEFAULT))
                           ((SETF ,K) (NEW-VALUE HASH-TABLE)
                            (SETF (GETHASH ,K HASH-TABLE) NEW-VALUE)))))
                      KEYS))
       ,@BODY)))

(DEFUN COLLECT-KEYWORD-SYMBOL (LIST)
  (REMOVE-DUPLICATES
   (REMOVE-IF-NOT #'KEYWORDP (FLATTEN LIST))))
  • 動作
(LET ((TAB (MAKE-HASH-TABLE)))
  (SETF (GETHASH :FOO TAB) 0
        (GETHASH :BAR TAB) 0
        (GETHASH :BAZ TAB) 0)
  (WITH-KEYWORD-FUNCTION
    ;; 値を再度設定
    (SETF (:FOO TAB) 11
          (:BAR TAB) 22
          (:BAZ TAB) 33)
    ;; 値を確認
    (LIST (:FOO TAB)
          (:BAR TAB)
          (:BAZ TAB))))
;⇒ (11 22 33)

CLでClojureのキーワードが関数(マクロ)になってる風

| 00:10 | CLでClojureのキーワードが関数(マクロ)になってる風 - わだばLisperになる を含むブックマーク はてなブックマーク - CLでClojureのキーワードが関数(マクロ)になってる風 - わだばLisperになる

Clojureでは、ハッシュのキーが値を取り出す関数のような振舞いをするのが便利ですが、仕事帰りの電車でぼーっとしていたら、そういう感じに書けるようなマクロが思い浮かんだので書いてみました。

大雑把に、見付けたキーワードには全部関数を詰めています。

できれば、fletでローカル関数にしたかったのですが、setfで便利に展開してくれるのでmacroletにしときました。

ローカルのsetf関数を書く方法ってあったりするんでしょうか。

(IMPORT 'KMRCL:FLATTEN)

(DEFMACRO WITH-KEYWORD-FUNCTION (&BODY BODY)
  (LET ((KEYS (COLLECT-KEYWORD-SYMBOL BODY)))
    `(MACROLET (,@(MAPCAR (LAMBDA (K)
                             `(,K (HASH-TABLE &OPTIONAL DEFAULT)
                                 `(GETHASH ,',K ,HASH-TABLE ,DEFAULT)))
                          KEYS))
       ,@BODY)))

(DEFUN COLLECT-KEYWORD-SYMBOL (LIST)
  (REMOVE-DUPLICATES
   (REMOVE-IF-NOT #'KEYWORDP (FLATTEN LIST))))
  • 動作
(LET ((TAB (MAKE-HASH-TABLE)))
  (SETF (GETHASH :FOO TAB) 0
        (GETHASH :BAR TAB) 0
        (GETHASH :BAZ TAB) 0)
  (WITH-KEYWORD-FUNCTION
    ;; 値を再度設定
    (SETF (:FOO TAB) 66
          (:BAR TAB) 77
          (:BAZ TAB) 88)
    ;; 値を確認
    (LIST (:FOO TAB)
          (:BAR TAB)
          (:BAZ TAB))))
;⇒ (66 77 88)

2009-09-28

Smalltalkのブロック風

| 01:01 | Smalltalkのブロック風 - わだばLisperになる を含むブックマーク はてなブックマーク - Smalltalkのブロック風 - わだばLisperになる

Smalltalkの

[:x | x + 1]

のようなブロックを見て、ふとマクロを思い付いたので書いてみました。

(DEFMACRO BIND (&BODY BODY)
  (DO ((BODY BODY (CDDR BODY))
       (BINDS () (DESTRUCTURING-BIND (VAR VAL &REST IGNORE) BODY
                   (DECLARE (IGNORE IGNORE))
                   (PUSH `(,(INTERN (SYMBOL-NAME VAR)) ,VAL) 
                         BINDS))))
      ((NOT (KEYWORDP (CAR BODY)))
       `(LET (,@(NREVERSE BINDS))
          ,@BODY))))
(BIND :X 10 :Y 20 :Z NIL
  (LIST X Y Z))
;⇒ (10 20 NIL)

ただ単に、変数束縛部とボディを分けるのにシンボルの種類の違いで分けられるなという思い付きでございました。

リーダーマクロを使って [:x (+ 1 x)] ⇒ (lambda (x) (+ 1 x))というのもありかもしれません。

というかこのエントリーのタイトルからするとこっちが本筋ですね…。

2009-09-27

map-accum

| 20:12 | map-accum - わだばLisperになる を含むブックマーク はてなブックマーク - map-accum - わだばLisperになる

map-accumって何者だということで、動作を理解すべくmap-accumを作ってみました。

名前そのまんまで説明になってないですが、mapにアキュムレータが付いたものなんですね。

たまに使いたくなる時がありそう。

ちなみにここ数日、electric-shift-lockモードを導入してコードを大文字で書いてみています。

大文字で書くと何か面白い発見があるかと思いましたが、今のところ何の発見もありません…。

;; 再帰でLIST版
(DEFUN MAP-ACCUM (F SEED &REST LISTS)
  (LABELS ((FROB (F SEED ANS LISTS)
             (IF (SOME #'ENDP LISTS)
                 (VALUES ANS SEED)
                 (MULTIPLE-VALUE-BIND (A ACC)
                     (APPLY F (APPEND (MAPCAR #'CAR LISTS) (LIST SEED)))
                   (MULTIPLE-VALUE-BIND (RES ACC) 
                       (FROB F ACC (APPEND ANS (LIST A)) (MAPCAR #'CDR LISTS))
                     (VALUES RES ACC))))))
    (FROB F SEED () LISTS)))
;; 総称関数版
(DEFGENERIC MAP-ACCUM (F SEED SEQUENCE &REST REST))
(DEFMETHOD MAP-ACCUM ((F FUNCTION) SEED (SEQUENCE SEQUENCE) &REST REST)
  (LET ((MIN-LEN (APPLY #'MIN (LENGTH SEQUENCE) (MAPCAR #'LENGTH REST))))
    (DO ((ACC SEED)
         TEM
         (IDX 0 (1+ IDX))
         (SEQS (CONS SEQUENCE REST))
         (RES (MAKE-SEQUENCE (CLASS-OF SEQUENCE) MIN-LEN)))
        ((= IDX MIN-LEN) (VALUES RES ACC))
      (SETF (VALUES TEM ACC)
            (APPLY F (NCONC (MAPCAR (LAMBDA (A) (ELT A IDX))
                                    SEQS)
                            (LIST ACC))))
      (SETF (ELT RES IDX) TEM))))
(MAP-ACCUM (LAMBDA (X Y Z ACC) 
             (VALUES (LIST ACC X Y Z) (1+ ACC)))
           0
           '(A B C E E)
           '(F G H I)
           '(J K L))
;⇒ ((0 A F J) (1 B G K) (2 C H L)),
;   3

(MAP-ACCUM (LAMBDA (X Y ACC) 
             (VALUES (IF (CHAR< X Y) X Y)
                     (1+ ACC)))
           0
           "abCd"
           "ABcD")
;⇒ "ABCD",
;   4

2009-09-25

バリューセルにも関数

| 23:32 | バリューセルにも関数 - わだばLisperになる を含むブックマーク はてなブックマーク - バリューセルにも関数 - わだばLisperになる

「#'とか付けるのだるい」「美しくない」という声を良く聞くのですが、目的のシンボルのバリューセルに関数を詰めれば、#'を付けなくても、まあ、大体似たことはできるんですよね。

ということで、fvletというfletでローカル関数を定義しつつ、関数のシンボルのバリューセルにも関数を詰めるというマクロを書いてみました。

「ああ、なんかバリューセルが潰れて損した気がする」と思った貴方は、心の底からLISP2の人です。

(DEFMACRO FVLET ((&REST SPECS) &BODY BODY)
  (LET ((SYMS (MAPCAR #'CAR SPECS)))
    `(FLET (,@SPECS)
       (LET (,@(MAPCAR (LAMBDA (X) `(,X (FUNCTION ,X)))
                       SYMS))
         ,@BODY))))
(IMPORT 'KMRCL:COMPOSE)

(FVLET ((FOO (X) (* 2 X))
        (BAR (X) (LIST X X)))
  (MAPCAR (COMPOSE BAR FOO) 
          '(1 2 3 4)))
;=> ((2 2) (4 4) (6 6) (8 8))

※追記

正確にはバリューセルを使うにはletの変数をスペシャルにしないといけないとzicさんより指摘がありました。

まったくその通りで、上記fvletの中でfooやbarをsymbol-valueするとどういうことかが分かります。

上記のコードだとletで作ったレキシカル環境を操作することになります。

2009-09-21

electric-shift-lock-mode

| 23:52 | electric-shift-lock-mode - わだばLisperになる を含むブックマーク はてなブックマーク - electric-shift-lock-mode - わだばLisperになる

70年代後半位までLISPのソースは大文字で書かれているものが多いのですが、70年代後半に登場したLispマシンのエディタ(ZWEI/Zmacs)にも、そんな時代を反映した、Electric Shift Lockという機能があります。

これは、CAPSキーをオンにしてくれるようなモードで、Shiftを押さない状態が大文字、逆にShiftを押すと小文字というモードです。

気が効いているのは、文字列やコメント等、大文字と小文字を区別する必要がある場所では、通常通りShift押下で大文字になるというところ。

;; foo
(DEFUN FOO (N)
  "foo"
  (LIST N))

こんな感じのがすらすら簡単に書けます。

以前からEmacs上で自作してみたかったのですが、連休中にちょっと挑戦してみようと思いたちました。

しかし、既に前に同じものがあったら嫌だなあと思い、念の為ググってみたら、ずばりを見付けてしまいました(笑)

John Paul Wallingtonさんが、去年の5月に作られていたようです。こんなニッチすぎるところに目をつけるとは…。世界は狭い。

しかし、どうもWallingtonさん作の挙動は、Shiftを押しても小文字は出ず、全部大文字になるようです。

連休中は、ぼーっとこの辺りをLispマシン風の挙動に変えてみたいです。

いまどき大文字でコードを書くということも少ないですが、気分を変えて大文字ベースで書いてみるのも一興かもしれません。

SQLでなんとなくこのモードが使えるかと思ったりもしますが、微妙な気もします。

2009-09-20

LISP処理系のTwitterアカウント

| 22:05 | LISP処理系のTwitterアカウント - わだばLisperになる を含むブックマーク はてなブックマーク - LISP処理系のTwitterアカウント - わだばLisperになる

ふと、Franz社のページを久し振りに見たところFranz社のTwitterのアカウントが付いていました。

なるほど、広報活動もTwitterを活用する時代。

LispWorks等もやってないかと探しましたが、今のところ無いようです。

適当に探したら、Franz以外には、Clojure、CLISP等がみつかりました。

clojure(@clojure)さん | Twitter

Franz Inc.(@Franzinc)さん | Twitter

Common Lisp CLISP(@clisp)さん | Twitter

Franz以外は、発言数も少ないようです。

ちなみに、Shibuya.lispは、こちらです。

Shibuya.lisp(@shibuya_lisp)さん | Twitter

2009-09-11

続・lisp-modeと表示の畳み込み

| 00:09 | 続・lisp-modeと表示の畳み込み - わだばLisperになる を含むブックマーク はてなブックマーク - 続・lisp-modeと表示の畳み込み - わだばLisperになる

前回、outline-modeについてつらつらと書いたところ、

Chaton CL部屋でd:id:lequeさんに

S 式の折り畳みなんですが hs-minor-mode はどうでしょう

とhs-minor-modeを教えてもらいました。

hs-minor-modeは畳み込み専用のモードらしく、色々カスタマイズもできるようです。

これは良さそうな予感!

早速、minor-modeなので、slimeと共存させてみます。

(defun foo ()
 :foo)

というところで、

M-x hs-toggle-hiding

すると、

...

となります。

…あれ、

(defun foo ...

みたいになるということでしたが…。

ちょっとググってみたところでは、この現象は、自分が利用しているEmacs 23.50.1のバグらしいことが判明しました。

ということで、最新のCVS版をインストールして試してみたところ

(defun foo ()...)

という風に良い感じに表示されるようになりました。

これより以前のhs-minor-modeでは、

(defun foo ...

と表示されていたということなので、今回のバグフィックスのついでに改善されたのかもしれません。

また、

というものも見つけたので、これも併用。

左端に折り畳める印が出て、これをマウスでクリックすると折り畳みを開閉できます。

  • 開いた状態

http://gyazo.com/16cafe3296882bc0f82656cbf043f797.png

  • ポチッと閉じる

http://gyazo.com/2db10ec9d97703711d04c226109b37c6.png