From: Dmitry Antipov Date: Fri, 29 Aug 2014 11:02:56 +0000 (+0400) Subject: * doc/lispref/lists.texi (Functions that Rearrange Lists): Remove X-Git-Tag: emacs-25.0.90~2635^2~679^2~404 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=dd958fb246a13c024ce58415c3de99f4390bcd77;p=emacs.git * doc/lispref/lists.texi (Functions that Rearrange Lists): Remove description of sort ... * doc/lispref/sequences.texi (Sequence Functions): ... and generalize it for sequences. Add an example. * src/fns.c (Fsort): Use more natural Qsequencep error. * test/automated/fns-tests.el (fns-tests-sort): Minor style rewrite. --- diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 783be72e830..a9954d84658 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,10 @@ +2014-08-29 Dmitry Antipov + + * lists.texi (Functions that Rearrange Lists): Remove + description of sort ... + * sequences.texi (Sequence Functions): ... and generalize + it for sequences. Add an example. + 2014-08-28 Eli Zaretskii * display.texi (Bidirectional Display): Update the Emacs's class diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index f724d5bd902..21be5cca4fc 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -1124,74 +1124,6 @@ each time you run it! Here is what happens: @end smallexample @end defun -@defun sort list predicate -@cindex stable sort -@cindex sorting lists -This function sorts @var{list} stably, though destructively, and -returns the sorted list. It compares elements using @var{predicate}. A -stable sort is one in which elements with equal sort keys maintain their -relative order before and after the sort. Stability is important when -successive sorts are used to order elements according to different -criteria. - -The argument @var{predicate} must be a function that accepts two -arguments. It is called with two elements of @var{list}. To get an -increasing order sort, the @var{predicate} should return non-@code{nil} if the -first element is ``less than'' the second, or @code{nil} if not. - -The comparison function @var{predicate} must give reliable results for -any given pair of arguments, at least within a single call to -@code{sort}. It must be @dfn{antisymmetric}; that is, if @var{a} is -less than @var{b}, @var{b} must not be less than @var{a}. It must be -@dfn{transitive}---that is, if @var{a} is less than @var{b}, and @var{b} -is less than @var{c}, then @var{a} must be less than @var{c}. If you -use a comparison function which does not meet these requirements, the -result of @code{sort} is unpredictable. - -The destructive aspect of @code{sort} is that it rearranges the cons -cells forming @var{list} by changing @sc{cdr}s. A nondestructive sort -function would create new cons cells to store the elements in their -sorted order. If you wish to make a sorted copy without destroying the -original, copy it first with @code{copy-sequence} and then sort. - -Sorting does not change the @sc{car}s of the cons cells in @var{list}; -the cons cell that originally contained the element @code{a} in -@var{list} still has @code{a} in its @sc{car} after sorting, but it now -appears in a different position in the list due to the change of -@sc{cdr}s. For example: - -@example -@group -(setq nums '(1 3 2 6 5 4 0)) - @result{} (1 3 2 6 5 4 0) -@end group -@group -(sort nums '<) - @result{} (0 1 2 3 4 5 6) -@end group -@group -nums - @result{} (1 2 3 4 5 6) -@end group -@end example - -@noindent -@strong{Warning}: Note that the list in @code{nums} no longer contains -0; this is the same cons cell that it was before, but it is no longer -the first one in the list. Don't assume a variable that formerly held -the argument now holds the entire sorted list! Instead, save the result -of @code{sort} and use that. Most often we store the result back into -the variable that held the original list: - -@example -(setq nums (sort nums '<)) -@end example - -@xref{Sorting}, for more functions that perform sorting. -See @code{documentation} in @ref{Accessing Documentation}, for a -useful example of @code{sort}. -@end defun - @node Sets And Lists @section Using Lists as Sets @cindex lists as sets diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 8f17862d427..d3a6792c1ba 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -327,6 +327,98 @@ encouraged to treat strings as immutable. @end defun +@defun sort sequence predicate +@cindex stable sort +@cindex sorting lists +@cindex sorting vectors +This function sorts @var{sequence} stably. Note that this function doesn't work +for all sequences; it may be used only for lists and vectors. If @var{sequence} +is a list, it is modified destructively. This functions returns the sorted +@var{sequence} and compares elements using @var{predicate}. A stable sort is +one in which elements with equal sort keys maintain their relative order before +and after the sort. Stability is important when successive sorts are used to +order elements according to different criteria. + +The argument @var{predicate} must be a function that accepts two +arguments. It is called with two elements of @var{sequence}. To get an +increasing order sort, the @var{predicate} should return non-@code{nil} if the +first element is ``less than'' the second, or @code{nil} if not. + +The comparison function @var{predicate} must give reliable results for +any given pair of arguments, at least within a single call to +@code{sort}. It must be @dfn{antisymmetric}; that is, if @var{a} is +less than @var{b}, @var{b} must not be less than @var{a}. It must be +@dfn{transitive}---that is, if @var{a} is less than @var{b}, and @var{b} +is less than @var{c}, then @var{a} must be less than @var{c}. If you +use a comparison function which does not meet these requirements, the +result of @code{sort} is unpredictable. + +The destructive aspect of @code{sort} for lists is that it rearranges the +cons cells forming @var{sequence} by changing @sc{cdr}s. A nondestructive +sort function would create new cons cells to store the elements in their +sorted order. If you wish to make a sorted copy without destroying the +original, copy it first with @code{copy-sequence} and then sort. + +Sorting does not change the @sc{car}s of the cons cells in @var{sequence}; +the cons cell that originally contained the element @code{a} in +@var{sequence} still has @code{a} in its @sc{car} after sorting, but it now +appears in a different position in the list due to the change of +@sc{cdr}s. For example: + +@example +@group +(setq nums '(1 3 2 6 5 4 0)) + @result{} (1 3 2 6 5 4 0) +@end group +@group +(sort nums '<) + @result{} (0 1 2 3 4 5 6) +@end group +@group +nums + @result{} (1 2 3 4 5 6) +@end group +@end example + +@noindent +@strong{Warning}: Note that the list in @code{nums} no longer contains +0; this is the same cons cell that it was before, but it is no longer +the first one in the list. Don't assume a variable that formerly held +the argument now holds the entire sorted list! Instead, save the result +of @code{sort} and use that. Most often we store the result back into +the variable that held the original list: + +@example +(setq nums (sort nums '<)) +@end example + +For the better understanding of what stable sort is, consider the following +vector example. After sorting, all items whose @code{car} is 8 are grouped +at the beginning of @code{vector}, but their relative order is preserved. +All items whose @code{car} is 9 are grouped at the end of @code{vector}, +but their relative order is also preserved: + +@example +@group +(setq + vector + (vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") + '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff"))) + @result{} [(8 . "xxx") (9 . "aaa") (8 . "bbb") (9 . "zzz") + (9 . "ppp") (8 . "ttt") (8 . "eee") (9 . "fff")] +@end group +@group +(sort vector (lambda (x y) (< (car x) (car y)))) + @result{} [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee") + (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")] +@end group +@end example + +@xref{Sorting}, for more functions that perform sorting. +See @code{documentation} in @ref{Accessing Documentation}, for a +useful example of @code{sort}. +@end defun + @node Arrays @section Arrays @cindex array diff --git a/src/fns.c b/src/fns.c index 8845a43fc4b..a454341fce6 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1958,7 +1958,7 @@ if the first element should sort before the second. */) else if (VECTORP (seq)) seq = sort_vector (seq, predicate); else if (!NILP (seq)) - wrong_type_argument (Qarrayp, seq); + wrong_type_argument (Qsequencep, seq); return seq; } diff --git a/test/automated/fns-tests.el b/test/automated/fns-tests.el index a6c45443db6..9f55a873ea4 100644 --- a/test/automated/fns-tests.el +++ b/test/automated/fns-tests.el @@ -113,8 +113,8 @@ (should (equal (sort (vector - (cons 8 "xxx") (cons 9 "aaa") (cons 8 "bbb") (cons 9 "zzz") - (cons 9 "ppp") (cons 8 "ttt") (cons 8 "eee") (cons 9 "fff")) + '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") + '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff")) (lambda (x y) (< (car x) (car y)))) [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee") (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")])))