Shammer's Philosophy

My private adversaria

自作 concat - Ver20130205

16進数を10進数に戻す関数・改 - Shammerismで作成したtypelistpを使用して、dolist 排除計画その2 - Shammerismのconcatを書き換える。自作の関数とコンディションを利用しているから、それらも合わせて記載。

(defun typelistp (l type)
  (if (null l)
      t
    (and (typep (car l) type) (typelistp (cdr l) type))))

(define-condition arguments-not-string-error (error)
  ((text :initarg :text :reader get-error-message))
  (:report (lambda (condition stream)
	     (format stream "~S.~%"
		     (get-error-message condition)))))

(defun concat (string1 &rest strings)
  (labels ((string-listp (l)
	     (typelistp l 'string))
	   (conc (l)
	     (if (null l)
		 ""
		 (concatenate 'string (car l) (conc (cdr l)))))
	   (flatten (l)
	     (cond ((null l) nil)
		   ((atom (car l)) (cons (car l) (flatten (cdr l))))
		   (t (append (flatten (car l)) (flatten (cdr l)))))))
    (if (stringp string1)
	(cond ((null strings) string1)
	      ((string-listp strings) (conc (flatten (list string1 strings))))
	      (t (error
		  (make-condition 'arguments-not-string-error
				  :text "Passed arguments includes objects which is not a string."))))
	(error
	 (make-condition 'arguments-not-string-error
			 :text (format nil "concat first argument should be string, but ~A is ~A."
				       string1 (type-of string1)))))))

少しずつ再帰に慣れてきた。再帰はうまく使用できれば内容をわかりやすくできる。もうループはなるべく使いたくなくなってきた。