diff options
| -rw-r--r-- | doc/lispref/sequences.texi | 40 | ||||
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | lisp/sort.el | 21 |
3 files changed, 4 insertions, 62 deletions
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 8b4ce539669..8b06874e73c 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi | |||
| @@ -440,6 +440,10 @@ where @var{predicate} is the @code{:lessp} argument. When using this | |||
| 440 | form, sorting is always done in-place. | 440 | form, sorting is always done in-place. |
| 441 | @end defun | 441 | @end defun |
| 442 | 442 | ||
| 443 | @xref{Sorting}, for more functions that perform sorting. See | ||
| 444 | @code{documentation} in @ref{Accessing Documentation}, for a useful | ||
| 445 | example of @code{sort}. | ||
| 446 | |||
| 443 | @cindex comparing values | 447 | @cindex comparing values |
| 444 | @cindex standard sorting order | 448 | @cindex standard sorting order |
| 445 | @anchor{definition of value<} | 449 | @anchor{definition of value<} |
| @@ -476,42 +480,6 @@ Examples: | |||
| 476 | @end example | 480 | @end example |
| 477 | @end defun | 481 | @end defun |
| 478 | 482 | ||
| 479 | Sometimes, computation of sort keys of list or vector elements is | ||
| 480 | expensive, and therefore it is important to perform it the minimum | ||
| 481 | number of times. By contrast, computing the sort keys of elements | ||
| 482 | inside the @var{predicate} function passed to @code{sort} will generally | ||
| 483 | perform this computation each time @var{predicate} is called with some | ||
| 484 | element. If you can separate the computation of the sort key of an | ||
| 485 | element into a function of its own, you can use the following sorting | ||
| 486 | function, which guarantees that the key will be computed for each list | ||
| 487 | or vector element exactly once. | ||
| 488 | |||
| 489 | @cindex decorate-sort-undecorate | ||
| 490 | @cindex Schwartzian transform | ||
| 491 | @defun sort-on sequence predicate accessor | ||
| 492 | This function stably sorts @var{sequence}, which can be a list, a | ||
| 493 | vector, a bool-vector, or a string. It sorts by comparing the sort | ||
| 494 | keys of the elements using @var{predicate}. The comparison function | ||
| 495 | @var{predicate} accepts two arguments, the sort keys to compare, and | ||
| 496 | should return non-@code{nil} if the element corresponding to the first | ||
| 497 | key should sort before the element corresponding to the second key. The | ||
| 498 | function computes a sort key of each element by calling the | ||
| 499 | @var{accessor} function on that element; it does so exactly once for | ||
| 500 | each element of @var{sequence}. The @var{accessor} function is called | ||
| 501 | with a single argument, an element of @var{sequence}. | ||
| 502 | |||
| 503 | This function implements what is known as @dfn{decorate-sort-undecorate} | ||
| 504 | paradigm, or the Schwartzian transform. It basically trades CPU for | ||
| 505 | memory, creating a temporary list with the computed sort keys, then | ||
| 506 | mapping @code{car} over the result of sorting that temporary list. | ||
| 507 | Unlike with @code{sort}, the return value is always a new list; the | ||
| 508 | original @var{sequence} is left intact. | ||
| 509 | @end defun | ||
| 510 | |||
| 511 | @xref{Sorting}, for more functions that perform sorting. See | ||
| 512 | @code{documentation} in @ref{Accessing Documentation}, for a useful | ||
| 513 | example of @code{sort}. | ||
| 514 | |||
| 515 | @cindex sequence functions in seq | 483 | @cindex sequence functions in seq |
| 516 | @cindex seq library | 484 | @cindex seq library |
| 517 | @cindex sequences, generalized | 485 | @cindex sequences, generalized |
| @@ -1734,11 +1734,6 @@ ordering predicates by hand. | |||
| 1734 | The old signature, '(sort SEQ PREDICATE)', can still be used and sorts | 1734 | The old signature, '(sort SEQ PREDICATE)', can still be used and sorts |
| 1735 | its input in-place as before. | 1735 | its input in-place as before. |
| 1736 | 1736 | ||
| 1737 | ** New function 'sort-on'. | ||
| 1738 | This function implements the Schwartzian transform, and is appropriate | ||
| 1739 | for sorting lists when the computation of the sort key of a list | ||
| 1740 | element can be expensive. | ||
| 1741 | |||
| 1742 | ** New API for 'derived-mode-p' and control of the graph of major modes. | 1737 | ** New API for 'derived-mode-p' and control of the graph of major modes. |
| 1743 | 1738 | ||
| 1744 | *** 'derived-mode-p' now takes the list of modes as a single argument. | 1739 | *** 'derived-mode-p' now takes the list of modes as a single argument. |
diff --git a/lisp/sort.el b/lisp/sort.el index 4f0d759ef8a..2ee76b6e1e3 100644 --- a/lisp/sort.el +++ b/lisp/sort.el | |||
| @@ -478,27 +478,6 @@ sRegexp specifying key within record: \nr") | |||
| 478 | ;; if there was no such register | 478 | ;; if there was no such register |
| 479 | (error (throw 'key nil)))))))))) | 479 | (error (throw 'key nil)))))))))) |
| 480 | 480 | ||
| 481 | ;;;###autoload | ||
| 482 | (defun sort-on (sequence predicate accessor) | ||
| 483 | "Sort SEQUENCE by calling PREDICATE on sort keys produced by ACCESSOR. | ||
| 484 | SEQUENCE should be the input sequence to sort. | ||
| 485 | Elements of SEQUENCE are sorted by keys which are obtained by | ||
| 486 | calling ACCESSOR on each element. ACCESSOR should be a function of | ||
| 487 | one argument, an element of SEQUENCE, and should return the key | ||
| 488 | value to be compared by PREDICATE for sorting the element. | ||
| 489 | PREDICATE is the function for comparing keys; it is called with two | ||
| 490 | arguments, the keys to compare, and should return non-nil if the | ||
| 491 | first key should sort before the second key. | ||
| 492 | The return value is always a new list. | ||
| 493 | This function has the performance advantage of evaluating | ||
| 494 | ACCESSOR only once for each element in the input SEQUENCE, and is | ||
| 495 | therefore appropriate when computing the key by ACCESSOR is an | ||
| 496 | expensive operation. This is known as the \"decorate-sort-undecorate\" | ||
| 497 | paradigm, or the Schwartzian transform." | ||
| 498 | (mapcar #'car | ||
| 499 | (sort (mapcar #'(lambda (x) (cons x (funcall accessor x))) sequence) | ||
| 500 | #'(lambda (x y) (funcall predicate (cdr x) (cdr y)))))) | ||
| 501 | |||
| 502 | 481 | ||
| 503 | (defvar sort-columns-subprocess t) | 482 | (defvar sort-columns-subprocess t) |
| 504 | 483 | ||