el-x 20140111.1401(in MELPA)
main entry point for el-x package

概要

Common Lispで使える関数・マクロを提供するclライブラリは
cl-libライブラリとして合法的に使えるようになりました。
Common Lisp関数・マクロ群にプレフィクスcl-を付けることで、安心して使えます。

ただし、ひとつだけ例外があります!
ローカル関数を定義するfletマクロはcl-fletマクロになりましたが、
まったくの別物に変貌してしまったのです。
そのため、flet→cl-fletの置換を施しても元の動作をしなくなりました。

元々のfletはスコープ内で呼ばれるローカル関数は、
他の関数の内側にまで波及していました。
一時的に関数の挙動を変更したい場合においては便利なマクロでした。

ところが、新しいEmacsではobsoleteとされました。

この問題を解決するのがel-xパッケージに含まれるdfletマクロです。
dfletはまさしく元のfletを今のEmacsでも使えるようにしてくれます。

実行例を見て挙動を比較してください。

インストール

パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。

(package-initialize)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "http://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")))

初めてel-xを使う方は
以下のコマンドを実行します。

M-x package-install el-x

アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。

M-x package-install package-utils (初めてアップグレードする場合のみ)
M-x package-utils-upgrade-by-name el-x

実行例 161023134958.dflet.el(以下のコードと同一)

;;; 関数fは元の数を2倍にする
(defun f (x) (* x 2))
(f 3)                                   ; => 6
;;; 関数gはfを呼び出すだけ
(defun g (x) (f x))

;;; そこで、ローカル関数fで[元の数に1を足す関数]に再定義する
;; 元々はfletを使えば望み通りの結果になった
(flet ((f (x) (1+ x)))
  (f 3)                                 ; => 4
  (g 3))                                ; => 4
;; しかし!cl-fletはfletとは異なりgの内部で呼ばれるfには波及しない!!!
;; しかも元のfletはobsolet扱いされている、困った
(cl-flet ((f (x) (1+ x)))
  (f 3)                                 ; => 4
  ;; !!!!!!!!!!!!!!!!!!!
  (g 3))                                ; => 6

;;; そこでcl-fletの代わりにdfletを使えば元のfletを再現してくれる
(dflet ((f (x) (1+ x)))
  (f 3)                                 ; => 4
  (g 3))                                ; => 4

実行方法

$ wget http://rubikitch.com/f/161023134958.dflet.el
$ emacs -Q -f package-initialize -l 161023134958.dflet.el

本サイト内の関連パッケージ


本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。