New function SB-IMPL:SCHWARTZIAN-STABLE-SORT-LIST
authorPaul Khuong <pvk@pvk.ca>
Wed, 13 Nov 2013 18:14:46 +0000 (13:14 -0500)
committerPaul Khuong <pvk@pvk.ca>
Mon, 2 Dec 2013 03:44:43 +0000 (22:44 -0500)
Stable sort because we really ought to avoid normal sort if we want
reproducible builds, and a Schwartzian transform because we sometimes
sort with fairly computation-heavy sort keys.  Better have that to
make it easy to DTRT.

package-data-list.lisp-expr
src/code/early-extensions.lisp

index ca67d02..5730ea0 100644 (file)
@@ -1701,6 +1701,7 @@ is a good idea, but see SB-SYS re. blurring of boundaries."
                "SCALE-DOUBLE-FLOAT"
                #!+long-float "SCALE-LONG-FLOAT"
                "SCALE-SINGLE-FLOAT"
+               "SCHWARTZIAN-STABLE-SORT-LIST"
                "SCRUB-POWER-CACHE"
                "SEQUENCEP" "SEQUENCE-COUNT" "SEQUENCE-END"
                "SEQUENCE-OF-CHECKED-LENGTH-GIVEN-TYPE"
index dd7742e..b73ac29 100644 (file)
@@ -1436,3 +1436,16 @@ to :INTERPRET, an interpreter will be used.")
                        (list (list :line lineno)
                              (list :column colno)
                              (list :file-position pos)))))))
+
+(declaim (inline schwartzian-stable-sort-list))
+(defun schwartzian-stable-sort-list (list comparator &key key)
+  (if (null key)
+      (stable-sort (copy-list list) comparator)
+      (let* ((key (if (functionp key)
+                      key
+                      (symbol-function key)))
+             (wrapped (mapcar (lambda (x)
+                                (cons x (funcall key x)))
+                              list))
+             (sorted (stable-sort wrapped comparator :key #'cdr)))
+        (map-into sorted #'car sorted))))