隣接する2項に演算を施す関数を Emacs Lisp で実装する

等差数列という記事を読んで,面白そうだったので,私も Emacs Lisp による実装を考えてみました (cl が必須です).

(defun f (func list)
  (butlast (maplist (lambda (x)
		      (and (cadr x) (apply func (list (car x) (cadr x)))))
		    list)
	   1))


実行結果は以下のような感じです.

(f '+ '(1 2 3 4 5))
(3 5 7 9)

butlast を使ってるあたりが美しくないですかねえ… どなたかもっとスマートな実装がありましたら教えてください.



(2012/1/5 追記)

というか,普通に再帰を使えばいいんでしたね.こっちの方が Lisp っぽいですかね.

(defun f (func list)
  (and (cdr list)
       (cons (apply func (list (car list) (cadr list))) (f func (cdr list)))))


実行結果は以下の通りです.

(f '+ '(1 2 3 4 5))
(3 5 7 9)

(2012/1/5 追記その2)

id:kensaku7 さんのエントリ(等差数列 (common lisp))で,common lisp による以下のような実装があげられていました:

(defun f (fn lst)
  (mapcar fn (cdr lst) lst))

Emacs lisp だと,cl をロードして上記の mapcar を mapcar* にすればいいだけです.うーん,emacs lisp の mapcar に慣れてしまって,common lisp の上記のような mapcar の使い方はなかなかできませんねえ….とにかく,Lisp では上記の実装が最もコンパクトだと思われます,脱帽です.