#:g1

YTools: Backquoteの紹介

Posted 2014-12-30 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の365日目です。

YTools: Backquoteとはなにか

 YTools: Backquoteは、Drew McDermott氏のユーティリティであるYtoolsの中で定義されている独自のバッククォート式です。

パッケージ情報

パッケージ名YTools: Backquote
Quicklisp×
プロジェクトページHome page for Drew McDermott
CLiKiCLiki: YTools

インストール方法

 上記プロジェクトページからダウンロードしてきて適当に導入します。

試してみる

 Common Lispのバッククォートの問題点として、McDermott氏は、バッククォートは、quoteのように「'」→quoteという対応がなく、展開も処理系依存のためポータブルなコードウォーカーが書きにくく、また、カスタマイズもしづらいことを挙げています。
さらに展開の難解さも指摘していて、これらを解決しようというのが、今回紹介の独自のバッククォート式です。
記法は、「!`数字」と、「,数字」「,数字@」となっていて、既存のバッククォート式が使えなくなるということはないように配慮されています。
特長としては、対応する展開レベルを数字で指定できるのでネストした場合に、どのレベルに対応して展開されるのかが分かり易い点があります。

;;; 標準
(let ((x 'xx)
      (y 'yy))
  `(,x `(,',y)))
;=>  (XX `(,'YY))

;;; ytools (let ((x 'xx) (y 'yy)) !`1(,1x `(,1y))) ;=> (XX `(YY))

;;; 標準 (let ((x 'xx) (y 'yy)) `(,x `(,',y ,,y))) ;=> (XX `(,'YY ,YY))

;;; ytools (let ((x 'xx) (y 'yy)) !`1(,1x !`2(,1y ,2y))) ;=> (XX !`2(YY ,2#Y))

;;; ytools (let ((x 'xx) (y 'yy)) !`1(,1x !`2(,1y !`3(,2x ,y)))) ;=> (XX !`2(YY !`3(,2#X YY)))

3重のネスト位になるとYToolsの方が読み易い気はします。
書く時ですが、どのレベルの内容が欲しいのか数字で指定できるので複雑なネストを書くのはかなり楽ではあります。

まとめ

 今回は、YTools: Backquoteを紹介してみました。
ネストするバッククォート式を書くことは少ないですが、上手く状況に適合した場合には楽かもしれません。
しかし、バッククォート式を返す、バッククォート式がちょっと難しい気もしますね。これも馴れなのでしょうか。

YTools: mapperの紹介

Posted 2014-12-29 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の364日目です。

YTools: mapperとはなにか

 YTools: mapperは、Drew McDermott氏のユーティリティであるYtoolsの中のmap系のユーティリティです。

パッケージ情報

パッケージ名YTools: mapper
Quicklisp×
プロジェクトページHome page for Drew McDermott
CLiKiCLiki: YTools

インストール方法

 上記プロジェクトページからダウンロードしてきて適当に導入します。

試してみる

 map系のユーティリティという括りよりは、単に短かく書ける記法なのですが、どんな風に書けるかというとこんな風に書けます。

;;; map
(<# (\\ (x) x) '(1 2 3 4))
;=>  (1 2 3 4)

;;; every (<& values '(t t t t)) ;=> T

;;; funcall (>< #'list 1) ;=> (1)

;;; apply (<< list '(1 2 3 4)) ;=> (1 2 3 4)

;;; remove-if-not (<? identity '(1 2 3 nil 4)) ;=> (1 2 3 4)

;;; reduce(複数の引数が取れる) (</ + 0 '(1 1 1 1) '(10 10 10 10)) ;=> 44

それぞれ2文字で記述できます。記述量を少なくする為か関数ではなくマクロになっていて#'を書かなくて済むようになっていますが、funcall(><)だけ例外です。
ちなみに大体想像が付くかなと思いますが\\はlambdaです。

まとめ

 今回は、YTools: mapperを紹介してみました。
最初は、2文字はさすがにないだろうと思っていましたが、しばらく使ってるうちに癖になってきてしまいました。馴れとは恐しい。

Symbolics Common Lispのread-char のrecursive-p

Posted 2014-12-29 05:36:42 GMT

read-charには、readと同じく、recursive-pのオプションがありますが、そもそもread-charが再帰的に呼ばれたことを区別する必要もない訳でCommon Lispの謎の一つです。
大抵の処理系はrecursive-pを無視していますが、LMIに至っては、仕様のバグとコメントにあったりする程。

 このrecursive-pが意味を成すとすれば、recursive-pの状態に合せて出すエラーメッセージを変えるのが精々かなと思っていましたが、そんな実装している処理系も見たことがありませんでした。

 そういう訳で新しい処理系を触ると

(With-Input-From-String (in "")
  (Read-Char in T :eof T))

(With-Input-From-String (in "") (Read-Char in T :eof nil))

の動作を確認するのが儀式となっていましたが、遂にこの二者の動作が違う処理系に出会うことができました。
さすがSymbolicsというところでしょうか。
違うといっても、どちらもEND-OF-FILEではありますが、メッセージが違います。
こっちが、recursive-pがnilの場合で、

Error: READ-CHAR encounted an EOF

となっていて、EOFに遭遇したというもの。

read-char-norec

そして、こっちが、recursive-pがTの場合

Error: EOF detected by READ-CHAR in the middle of expression

というエラーメッセージになっていて、何かの式を読み取る途中で(つまり再帰的に呼ばれていて)EOFに遭遇した、というものになっています。

read-char-rec

これは、READ-CHARの設計者も満足な実装ではないでしょうか。


HTML generated by 3bmd in SBCL 1.2.9

Open Generaで遊んでみる

Posted 2014-12-29 03:28:45 GMT

 現在Lispマシンを動かして遊んでみるとなると実機も中々入手が困難なこともあり、エミュレータを利用することになるかと思います。
現在入手して利用できるエミュレータとしては、

  • MIT CADR
  • TI-Explorer
  • Symbolics

のものが公開されています。

 このうちSymbolicsのエミュレータは、元々DEC Alpha上のTru64 UNIX上で動くOpen GeneraをLinuxやMacOSXで動かすようにするものですが、自分は、Open Generaのソース一式が無いとまともに動かせないものと思い込んでいて、さらには、環境構築が面倒臭いこともあり、自分は試したことがありませんでした。

 そんな感じで何年もOpen Generaのエミュレータは放置していたのですが、LinuxでLispMachine(Open Genera)を動かすというエントリーを読んで、もしかしたら動かすだけならOpen Genera本体がなくても良いのではないかと思い、このエントリーを参考にセットアップしてみました。

 試した結果ですが、実際にセットアップしてみると、適当に遊んでみる位なら、Open GeneraがなくてもエミュレータだけでOKでした。
以下、適当に環境や嵌ったところを書いてみたいと思います。

環境

  • VirtualBox上のUbuntu 7.10
  • Brad Parker氏のエミュレータsnap4

嵌りどころ

 嵌りどころというか、現状もまともに動かせている感じはしないのですが、下記の点が嵌りやすいかなと思いました。

  • ホストのIPアドレスを10.0.0.1にする
  • rootで実行する必要がある
  • リモート画面の設定

 ホストのIPアドレスは、エミュレータが決め打ちで、10.0.0.1になります。
仮想マシンの場合、このアドレスが他に取られていて、設定が難しいことがありますが、VirtualBoxなら大丈夫でした。

 リモート画面ですが、rootで実行していることもあり、他のマシンに飛すのが色々面倒だったりします。
自分は、vncを利用して他のマシンに飛すことにしました。本当は画面だけ飛したいところですが、大して使用感に違いもなさそうなので、まあ、これで良いかなというところです。

起動画面

 とりあえず起動してみたところです。

og2

サイト定義(define site)

 サイト定義ですが、現状サイト定義を保存することができておらず、起動の都度入力しているので、デフォルト値をそのまま活かせるように、ホスト側のファイルの位置を変更しています。
具体的には、/var/lib/symbolics/ 以下にファイルを設置しています。
また、サイトの名前も面倒なのでzにして、ホスト名もデフォルト値が活かせるように、hostに設定。
さらに、タイムゾーンをJSTにしています。

og2-define-site

ログイン

 ホストのユーザーは取得している様子は窺えますが、パスワードが弾かれたりします。
NISを設定して、その後に作成したユーザーはログインできたりします、暗号化方式からmd5は除外した筈なのですが謎です。

og2-login

ZmacsのLispモード

 Common Lispのプログラミングをするには、

  • M-x Lisp Mode
  • M-x Set Syntax → ansi-common-lisp
  • M-x Set Package

するとANSI Common Lispに近い環境でプログラミングできるようです。

og2-lisp-mode

現状の問題点

 Reset Networkが上手く動かず、Save worldもできていません。 これができると大分快適に使える気がするのですが…。

まとめ

Symbolicsのエミュレータで遊んでみました。
ホスト上のファイルを読み書きできるので、TI-Explorerのエミュレータよりは遊べるなという印象です。
Symbolicsとしてのソースではありませんが、LMIや、MIT CADRのソースコードは公開されているので、Common Lispでは動かすのが難しいようなソースをこれでコンパイルして遊んでみたりはできるかもしれません。

asdfに細工をしてプロジェクトのデバッグの省力化

Posted 2014-12-29 01:46:18 GMT

 プロジェクトのデバッグの流れは大体、

  • システムをロード
  • エラーになったファイルを開いて修正
  • 繰り返し

という感じになりますが、処理系によってはコンパイルエラーやロードエラーになった該当ファイルがさっと特定できるものもあれば、さっぱり分からないものもあります。
それに加えてQuicklispだとロードの詳細が隠蔽されているので、どのファイルを開いて修正すれば良いのか探らないといけないことが多く、さらには、デバッガが開いたとしても現在処理しているファイル情報を分かり易く表示しているかというと、そうでもありません。

 これをどうにかしたいと思って頭を捻ってみましたが、単純に処理しているファイルを表示してくれれば良いのでASDFの処理にフックを掛けてみることにしました。

ASDFのload-opとcompile-opでファイル名を出力するようにメソッドを追加

(defmethod asdf:perform :before ((o asdf:load-op) (c asdf:cl-source-file))
  (format *debug-io*
          "~&;;;((((:======== :Loding ~%;;;~4T(:SYSTEM :~A)~%;;;~4T(:fasl ~S)~%;;;))))~4%"
          (asdf/find-system:primary-system-name 
           (asdf/component:component-parent c))
          (slot-value c 'asdf/component::absolute-pathname)))

(defmethod asdf:perform :before ((o asdf:compile-op) (c asdf:cl-source-file)) (format *debug-io* "~&;;;((((:==== :Compiling ~%;;;~4T(:SYSTEM :~A)~%;;;~4T(:text ~S)~%;;;))))~%" (asdf/find-system:primary-system-name (asdf/component:component-parent c)) (slot-value c 'asdf/component::absolute-pathname)))

実行結果例

CL-USER> (ql:quickload :cl-who)
To load "cl-who":
  Load 1 ASDF system:
    cl-who
; Loading "cl-who"
;;;((((:==== :Compiling 
;;; (:SYSTEM :cl-who)
;;; (:text #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/packages.lisp")
;;))))
[package cl-who]
;;;((((:======== :Loding 
;;; (:SYSTEM :cl-who)
;;; (:fasl #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/packages.lisp")
;;;))))

;;;((((:==== :Compiling ;;; (:SYSTEM :cl-who) ;;; (:text #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/specials.lisp") ;;)))) ;;;((((:======== :Loding ;;; (:SYSTEM :cl-who) ;;; (:fasl #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/specials.lisp") ;;;))))

;;;((((:==== :Compiling ;;; (:SYSTEM :cl-who) ;;; (:text #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/util.lisp") ;;)))) .... ;;;((((:======== :Loding ;;; (:SYSTEM :cl-who) ;;; (:fasl #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/util.lisp") ;;;))))

;;;((((:==== :Compiling ;;; (:SYSTEM :cl-who) ;;; (:text #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/who.lisp") ;;)))) .................. ;;;((((:======== :Loding ;;; (:SYSTEM :cl-who) ;;; (:fasl #P"/l/quicklisp/dists/quicklisp/software/cl-who-1.1.4/who.lisp") ;;;))))

(:CL-WHO)

これに加えて、Emacsでファイルを簡単に開けるようなものを作成
下記の場合、ファイル名の上でM-g fするとファイルを開きます。

(define-key goto-map [?f]
  (lambda ()
    (interactive)
    (find-file
     (substring-no-properties
      (thing-at-point 'symbol)))))

まとめ

 非常に素朴な方法ですが、使ってみると割合に便利です。
現在処理している直近のファイルを保持させてSLIMEのデバッガでM-g fすると該当ファイルが開くようなものも便利かもしれないですね。

common-methodsの紹介

Posted 2014-12-28 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の363日目です。

common-methodsとはなにか

 common-methodsは、Ryan Pavlik氏作のRubyにインスパイアされたCommon Lispのメソッド定義/構成のためのライブラリです。

パッケージ情報

パッケージ名common-methods
Quicklisp×
レポジトリrpav/common-methods · GitHub

インストール方法

 Quicklispには収録されていません。
githubからダウンロードしてQuicklispのlocal-projectsに置けば

(ql:quickload :common-methods)

できるようになります。

試してみる

 以前、incongruent-methodsを紹介した時に、Orivej Desh氏よりcommon-methodsというものがあるよと教えてもらっていました。
Lisp Library 365も終盤なので紹介しておきます。

 まずcommon-methodsの機能としては、incongruent-methodsの機能をほぼ包含している感じです。
実現方法は若干違いますが、可変長引数でメソッドをディスパッチさせるのにコンパイラマクロを利用する点などは共通しています。

(cm:def* plus ((x number) (y number))
  (+ x y))

(cm:def* plus ((x string) (y string)) (concatenate 'string x y))

(plus "foo" :y "bar") ;=> "foobar"

(plus 1 :y 2) ;=> 3

(cm:def* plus (x) x)

(plus 'zoo) ;=> ZOO

 また、名前がstring=なら同一の関数として呼べるという、incongruent-methodsのdefine-shared-methodは、common-methodsでは、共有用のcm-methods(m)パッケージに定義するというのが対応しているでしょうか。

 その他の機能としては、一般的な多重ディスパッチでないオブジェクト指向システムの書き具合を再現しようとしたものが多いようです。

まとめ

 今回は、common-methodsを紹介してみました。
Common Lisp純粋主義者は気に入らないだろうと前置きがありますが、まあ他の言語の便利な機能を取り込んだり実装するのも一興ですよね。

cl-unicodeの紹介

Posted 2014-12-27 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の362日目です。

cl-unicodeとはなにか

 cl-unicodeは、Edi Weitz氏作のCommon LispでUnicodeを扱うためのライブラリです。

パッケージ情報

パッケージ名cl-unicode
Quicklisp
ドキュメントCL-UNICODE - A portable Unicode library for Common Lisp
CLiKiCLiki: cl-unicode
Quickdocscl-unicode | Quickdocs
CL Test Grid: ビルド状況cl-unicode | CL Test Grid

インストール方法

(ql:quickload :cl-unicode)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 名前のとおりCommon LispでUnicodeを扱うためのライブラリです。
文字からUnicodeのプロパティを取得する等、一通りの操作が可能です。
また、Unicodeが扱える処理系でも文字の名前等は統一されていませんが、cl-unicodeを利用すれば統一的に記述できます。

(defun props (char)
  (remove-if-not (*:curry #'cl-unicode:has-property char)
                 (cl-unicode:recognized-properties)))

(props #\あ) ;=> ("Alphabetic" "Any" "Assigned" "BidiClass:L" "Block:Hiragana" "GraphemeBase" ; "Hiragana" "IDContinue" "IDStart" "L" "Lo" "XIDContinue" "XIDStart")

(mapcar #'string (cl-unicode:list-all-characters "Hiragana")) ;=> ("ぁ" "あ" "ぃ" "い" "ぅ" "う" "ぇ" "え" "ぉ" "お" "か" "が" "き" "ぎ" "く" "ぐ" "け" "げ" "こ" ; "ご" "さ" "ざ" "し" "じ" "す" "ず" "せ" "ぜ" "そ" "ぞ" "た" "だ" "ち" "ぢ" "っ" "つ" "づ" "て" ; "で" "と" "ど" "な" "に" "ぬ" "ね" "の" "は" "ば" "ぱ" "ひ" "び" "ぴ" "ふ" "ぶ" "ぷ" "へ" "べ" ; "ぺ" "ほ" "ぼ" "ぽ" "ま" "み" "む" "め" "も" "ゃ" "や" "ゅ" "ゆ" "ょ" "よ" "ら" "り" "る" "れ" ; "ろ" "ゎ" "わ" "ゐ" "ゑ" "を" "ん" "ゔ" "ゕ" "ゖ" "ゝ" "ゞ" "ゟ")

(mapcar #'string (cl-unicode:list-all-characters "Katakana")) ;=> ("ァ" "ア" "ィ" "イ" "ゥ" "ウ" "ェ" "エ" "ォ" "オ" "カ" "ガ" "キ" "ギ" "ク" "グ" "ケ" "ゲ" "コ" ; "ゴ" "サ" "ザ" "シ" "ジ" "ス" "ズ" "セ" "ゼ" "ソ" "ゾ" "タ" "ダ" "チ" "ヂ" "ッ" "ツ" "ヅ" "テ" ; "デ" "ト" "ド" "ナ" "ニ" "ヌ" "ネ" "ノ" "ハ" "バ" "パ" "ヒ" "ビ" "ピ" "フ" "ブ" "プ" "ヘ" "ベ" ; "ペ" "ホ" "ボ" "ポ" "マ" "ミ" "ム" "メ" "モ" "ャ" "ヤ" "ュ" "ユ" "ョ" "ヨ" "ラ" "リ" "ル" "レ" ; "ロ" "ヮ" "ワ" "ヰ" "ヱ" "ヲ" "ン" "ヴ" "ヵ" "ヶ" "ヷ" "ヸ" "ヹ" "ヺ" "ヽ" "ヾ" "ヿ" "ㇰ" "ㇱ" ; "ㇲ" "ㇳ" "ㇴ" "ㇵ" "ㇶ" "ㇷ" "ㇸ" "ㇹ" "ㇺ" "ㇻ" "ㇼ" "ㇽ" "ㇾ" "ㇿ" "㋐" "㋑" "㋒" "㋓" "㋔" ; "㋕" "㋖" "㋗" "㋘" "㋙" "㋚" "㋛" "㋜" "㋝" "㋞" "㋟" "㋠" "㋡" "㋢" "㋣" "㋤" "㋥" "㋦" "㋧" ; "㋨" "㋩" "㋪" "㋫" "㋬" "㋭" "㋮" "㋯" "㋰" "㋱" "㋲" "㋳" "㋴" "㋵" "㋶" "㋷" "㋸" "㋹" "㋺" ; "㋻" "㋼" "㋽" "㋾" "㌀" "㌁" "㌂" "㌃" "㌄" "㌅" "㌆" "㌇" "㌈" "㌉" "㌊" "㌋" "㌌" "㌍" "㌎" ; "㌏" "㌐" "㌑" "㌒" "㌓" "㌔" "㌕" "㌖" "㌗" "㌘" "㌙" "㌚" "㌛" "㌜" "㌝" "㌞" "㌟" "㌠" "㌡" ; "㌢" "㌣" "㌤" "㌥" "㌦" "㌧" "㌨" "㌩" "㌪" "㌫" "㌬" "㌭" "㌮" "㌯" "㌰" "㌱" "㌲" "㌳" "㌴" ; "㌵" "㌶" "㌷" "㌸" "㌹" "㌺" "㌻" "㌼" "㌽" "㌾" "㌿" "㍀" "㍁" "㍂" "㍃" "㍄" "㍅" "㍆" "㍇" ; "㍈" "㍉" "㍊" "㍋" "㍌" "㍍" "㍎" "㍏" "㍐" "㍑" "㍒" "㍓" "㍔" "㍕" "㍖" "㍗" "ヲ" "ァ" "ィ" ; "ゥ" "ェ" "ォ" "ャ" "ュ" "ョ" "ッ" "ア" "イ" "ウ" "エ" "オ" "カ" "キ" "ク" "ケ" "コ" "サ" "シ" ; "ス" "セ" "ソ" "タ" "チ" "ツ" "テ" "ト" "ナ" "ニ" "ヌ" "ネ" "ノ" "ハ" "ヒ" "フ" "ヘ" "ホ" "マ" ; "ミ" "ム" "メ" "モ" "ヤ" "ユ" "ヨ" "ラ" "リ" "ル" "レ" "ロ" "ワ" "ン")

(print #\㌍) ;>> ;>> #\SQUARE_KARORII ;=> #\SQUARE_KARORII

(cl-unicode:unicode1-name #\㌍) ;=> "SQUARED KARORII"

(cl-unicode:character-named "SQUARED KARORII") ;=> #\SQUARE_KARORII

まとめ

 今回は、cl-unicodeを紹介してみました。
名前で検索して面白い文字を見付けたりするのにも便利ですね。

lisp-executableの紹介

Posted 2014-12-26 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の361日目です。

lisp-executableとはなにか

 lisp-executableは、Mark Cox氏作のCommon Lispで実行ファイルを作るためのユーティリティです。

パッケージ情報

パッケージ名lisp-executable
Quicklisp
ドキュメントLisp Executable
CLiKiCLiki: lisp-executable
Quickdocslisp-executable | Quickdocs
CL Test Grid: ビルド状況lisp-executable | CL Test Grid

インストール方法

(ql:quickload :lisp-executable)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 現在、大抵のCommon Lisp処理系は実行ファイルが作れますが、lisp-executableを利用すると、シェルから実行するコマンドを簡便に作ることが可能です。
便利なdefine-programという実行ファイルを関数のように定義する構文が用意されているのと、ASDFと統合されているのが特長です。

 こんな感じの定義と、

(defpackage :hello
  (:use :cl :lisp-executable))

(cl:in-package :hello)

(define-program hello (&options help) (cond (help (format t "Help はないよ~%")) (t (format t "おはよう日本~%"))) (terpri))

こんなasdファイルがあれば、

(cl:in-package :asdf)

(asdf:load-system :lisp-executable)

(defsystem :hello :serial t :depends-on (:lisp-executable) :components ((:file "hello") (lisp-executable:executable "hello-bin" :program ("HELLO" "HELLO"))))

asdf:oosのlisp-executable:create-executables-opを実行することで、実行可能ファイルが生成できます。

(asdf:load-system :hello)
(asdf:oos 'lisp-executable:create-executables-op :hello)

生成された実行ファイルを実行してみる

$ ./hello-bin
おはよう日本

$ ./hello-bin --help Help はないよ

まとめ

 今回は、lisp-executableを紹介してみました。
define-programがうまいことできていて非常に便利ですね。

com.informatimago.tools.pathnameの紹介

Posted 2014-12-25 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の360日目です。

com.informatimago.tools.pathnameとはなにか

 com.informatimago.tools.pathnameは、Pascal Bourguignon氏作のパスネームを扱うライブラリです。

パッケージ情報

パッケージ名com.informatimago.tools.pathname
Quicklisp

インストール方法

(ql:quickload :com.informatimago.tools.pathname)

試してみる

 エクスポートされているのは、make-pathname、translate-logical-pathname、user-homedir-pathnameの3つですが、どれもclパッケージに定義されているものです。
何が目的なのかソースを眺めてみましたが、user-homedir-pathnameは、Windows上のCCLだとホームディレクトリを返さないという問題があるらしくそれの対処のようです。
他、make-pathnameですが、*case-common-is-not-downcased-on-posix-systems*というフラグで処理系ごとに挙動を変えています。
case-commonというのは恐らく

(make-pathname :directory "DI" :name "TILTOWAITO" :type "MOLITO"
               :case :common)
;=>  #P"/di/tiltowaito.molito"

この:case :commonだと思うのですが、Allegro CLと、Emacs CLは、POSIXシステムだと小文字になるべき所でならないようなことが読み取れます。
そうなのかと思ってAllegro CLのalisp/mlisp両方で試してみましたが、そんなこともないようです。

 ちなみにこの:case :commonですが、大文字で書くと、ファイルシステムのデフォルトのケース(Unixなら小文字)に合せてくれて、小文字ならその逆、混ぜると変換なし、というものです。
:common :caseを付けるのが正しい的な説も耳にしたことがありますが、デフォルトは:common :localだったりもしますし、ちょっと謎です。

 translate-logical-pathnameの方も謎がありますが、パスをlogical-pathnameに変換しているようなので、変換するほうが都合が良い処理系があったりするのかもしれません。

まとめ

 今回は、com.informatimago.tools.pathnameを紹介してみました。
若干謎が多いユーティリティですが、コードを眺めていて、logical-pathnameは、pathnameとは別の型が用意されていることに気付きました。
これは知らなかった…。

(type-of #p"sys:src;")
;=>  LOGICAL-PATHNAME

(type-of #p"/") ;=> PATHNAME

chirpの紹介

Posted 2014-12-24 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の359日目です。

chirpとはなにか

 chirpは、Nicolas Hafner氏作のCommon LispからTwitterを利用するためのライブラリです。

パッケージ情報

パッケージ名chirp
Quicklisp
ドキュメントサイトChirp - About
CLiKiCLiki: Chirp
Quickdocschirp | Quickdocs
CL Test Grid: ビルド状況chirp | CL Test Grid

インストール方法

(ql:quickload :chirp)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 使い方はドキュメントサイトにも書いてありますが、クライアントを登録すればCommon LispからTwitterを利用できるようになります。
クライアントを登録するところからの説明はドキュメントにあるので、既にキーを取得している場合について書いてみますが、

((consumer-key "madaltohalitodialko")
 (consumer-secret "loktofeitodiostiltowaito")
 (access-key "loktofeitomahalitomadalto")
 (access-secret "maporficlahalitomakanito"))

というような内容の~/.twitter-oauth.lispがあったとすれば、

(defun chirp-init ()
  (let ((keys (with-open-file (in "~/.twitter-oauth.lisp")
                (read in))))
    (setq chirp-extra:*oauth-api-key*
          (second (assoc 'consumer-key keys))
          chirp-extra:*oauth-api-secret*
          (second (assoc 'consumer-secret keys))
          chirp-extra:*oauth-access-secret*
          (second (assoc 'access-secret keys))
          chirp-extra:*oauth-access-token*
          (second (assoc 'access-key keys))))
  (chirp:account/verify-credentials))

(chirp-init)

こんな感じで認証ができて、

(chirp:statuses/update "Charpからつぶやき。cl-twitterさよなら")

こんな感じでつぶやけます。
また、chirpは、streaming apiにも対応

(chirp:stream/user (lambda (message)
                     (when message
                       (format T
                               "~&STREAM: ~a~%"
                               (when (typep message 'chirp-objects:status)
                                 (chirp-objects:text message))))
                     T))
;>> STREAM: NIL
;>> STREAM: しかし眠い…時差ぼけ?
;...

まとめ

 今回は、chirpを紹介してみました。
自分は、Twitterは、SLIME経由で利用していますが、以前は、cl-twitterを使ってみたりしていました。
しかし、cl-twitterは、Twitter側のアップデートに追従できずに使えなくなってしまうことが多く、しょうがないのでcl-oauthを直に使ってみたりしていました。
Twitter側のAPIの変更も落ち着いたようですし、chirpはcl-twitterに比べてほど良くまとまっている感じなので使い易そうですね。

Older entries (1937 remaining)