From 38b78e8763833fee8b41ecaf7586558e9b60d254 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 3 Aug 2019 14:59:40 +0100 Subject: [PATCH] src/utilities.lisp: Convert merge candidates to presentation form on the fly. In `inconsistent-merge-error', retain the raw list of candidates, and the presentation function, rather than requiring the caller to convert the candidates when constructing the condition object. This makes the list considerably more useful to condition handler code. --- doc/SYMBOLS | 3 +++ doc/misc.tex | 6 +++++- src/utilities.lisp | 13 +++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/doc/SYMBOLS b/doc/SYMBOLS index 96c79c6..6f230a2 100644 --- a/doc/SYMBOLS +++ b/doc/SYMBOLS @@ -2328,6 +2328,7 @@ utilities.lisp mappend function maybe-print-unreadable-object macro merge-error-candidates generic + merge-error-present-function generic merge-lists function sb-mop:method-specializers generic once-only macro @@ -2381,6 +2382,8 @@ instance-initargs cl:standard-object merge-error-candidates inconsistent-merge-error +merge-error-present-function + inconsistent-merge-error sb-mop:method-specializers cl:standard-method diff --git a/doc/misc.tex b/doc/misc.tex index 2d86406..c253630 100644 --- a/doc/misc.tex +++ b/doc/misc.tex @@ -160,12 +160,16 @@ These symbols are defined in the @|sod-utilities| package. \subsection{Merging lists} -\begin{describe}{cls}{inconsistent-merge-error (error) \&key :candidates} +\begin{describe}{cls} + {inconsistent-merge-error (error) \&key :candidates :present} \end{describe} \begin{describe}{gf}{merge-error-candidates @ @> @} \end{describe} +\begin{describe}{gf}{merge-error-present-function @ @> @} +\end{describe} + \begin{describe}{fun} {merge-lists @ \&key :pick (:test \#'eql) :present @> @} \end{describe} diff --git a/src/utilities.lisp b/src/utilities.lisp index b02fdf4..4935f8b 100644 --- a/src/utilities.lisp +++ b/src/utilities.lisp @@ -526,17 +526,21 @@ (cdddr neigh-record) best-path))))))) dead)) -(export '(inconsistent-merge-error merge-error-candidates)) +(export '(inconsistent-merge-error + merge-error-candidates merge-error-present-function)) (define-condition inconsistent-merge-error (error) ((candidates :initarg :candidates - :reader merge-error-candidates)) + :reader merge-error-candidates) + (present :initarg :present :initform #'identity + :reader merge-error-present-function)) (:documentation "Reports an inconsistency in the arguments passed to `merge-lists'.") (:report (lambda (condition stream) (format stream "Merge inconsistency: failed to decide between ~ ~{~#[~;~A~;~A and ~A~:;~ ~@{~A, ~#[~;and ~A~]~}~]~}" - (merge-error-candidates condition))))) + (mapcar (merge-error-present-function condition) + (merge-error-candidates condition)))))) (export 'merge-lists) (defun merge-lists (lists &key pick (test #'eql) (present #'identity)) @@ -593,7 +597,8 @@ candidates)) (winner (cond ((null leasts) (error 'inconsistent-merge-error - :candidates (mapcar present candidates))) + :candidates candidates + :present present)) ((null (cdr leasts)) (car leasts)) (pick -- 2.11.0