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 |

2007-10-23

Paul Graham氏のユーティリティ その10

| 07:29 | Paul Graham氏のユーティリティ その10 - わだばLisperになる を含むブックマーク はてなブックマーク - Paul Graham氏のユーティリティ その10 - わだばLisperになる

PG氏のユーティリティを読んでみることの10回目。

エラーとデバック、日付のユーティリティ編です。

Lisp utilities that were not included in On Lisp or ANSI Common Lisp

お題

ero

暗記で再現:間違えた

(defun ero (args)     ;&restが抜けた。
  (print (if (cdr args) args (car args))
	 *error-output*))

間違えた。引数は、&restで受けることになっていた。

引数を*error-output*に出力するというものらしい。

;; 動作
(ero 'foo 'bar 'baz)
;=>(FOO BAR BAZ) 
(ero 'foo)
;=> FOO

お題

safely

暗記で再現

(defmacro safely (expr)
  (with-gensyms (ret err)
    `(bind (,ret ,err) (ignore-errors ,expr)
	 (if (typep ,err 'error)
	     nil
	     (values ,ret ,err)))))

できた。評価する式をくるんでエラーの場合でもnilを出力するだけにしたもの。

;; 動作
(safely 
 (bind (a (b) c) (values 1 2 3)
       (list a b)))
=>nil
;通常はパターンマッチに失敗するのでエラーとなる

お題

time-string

暗記で再現

(defun time-string ()
  (multiple-value-bind (s m h) (get-decoded-time)
    (format nil "~A:~2,,,'0@A:~2,,,'0@A" h m s)))

できた。その名の通り、現在時刻の文字列を返す。

;; 動作
(time-string)
;=>"6:54:05"

お題

date-string

暗記で再現

(defconstant months
  #("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))

(defun date-string ()
  (multiple-value-bind (ig no re d mo y) (get-decoded-time)
    (declare (ignore ig no re))
    (format nil "~A ~A ~A" d (svref months (1- mo)) y)))

できた。予めmonthsという月の名前の定数のベクタを定義しておいて、それを参照して日付の文字列を返すというもの。

全然関係ないけれど(declare (ignore ig no re))ってのが面白い。

;; 動作
(date-string)
;=>"23 Oct 2007

お題

date+time-string

暗記で再現

(defun date+time-string (&optional (u (get-universal-time)))
  (multiple-value-bind (s m h d mo y) (decode-universal-time u)
    (format nil "~A ~A ~A ~A:~2,,,'0@A:~2,,,'0@A" d (svref months (1- mo)) y h m s)))

できた。上記2つを合体させたもの。オプションで引数がとれるように拡張されている。

;; 動作
(date+time-string)
;=>"23 Oct 2007 7:10:46"