chiark / gitweb /
src/utilities.lisp: Convert merge candidates to presentation form on the fly.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 3 Aug 2019 13:59:40 +0000 (14:59 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 3 Aug 2019 15:46:20 +0000 (16:46 +0100)
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
doc/misc.tex
src/utilities.lisp

index 96c79c6bcaa467043eace97d633023809899b07d..6f230a23e8fa2e17712306bef24c25e2789a1716 100644 (file)
@@ -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
 
index 2d86406f9924ff7b4b1e2a82084aa27b97b9abea..c2536304f325a081a71dc146ed873b4d95299432 100644 (file)
@@ -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 @<error> @> @<list>}
 \end{describe}
 
+\begin{describe}{gf}{merge-error-present-function @<error> @> @<function>}
+\end{describe}
+
 \begin{describe}{fun}
     {merge-lists @<lists> \&key :pick (:test \#'eql) :present @> @<list>}
 \end{describe}
index b02fdf431bce8e582568d05da69afd56c5936e16..4935f8bfd8157d185f713c717755bd01de0c3fe2 100644 (file)
@@ -526,17 +526,21 @@ (defun distinguished-point-shortest-paths (root neighbours-func)
                         (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 @@ (defun merge-lists (lists &key pick (test #'eql) (present #'identity))
                              candidates))
           (winner (cond ((null leasts)
                          (error 'inconsistent-merge-error
-                                :candidates (mapcar present candidates)))
+                                :candidates candidates
+                                :present present))
                         ((null (cdr leasts))
                          (car leasts))
                         (pick