emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Any interest in a function like this to add to subr.el?


From: Ken Raeburn
Subject: Re: Any interest in a function like this to add to subr.el?
Date: Wed, 19 Oct 2016 01:01:36 -0400

> On Oct 18, 2016, at 17:25, John Wiegley <address@hidden> wrote:
> 
>>>>>> "DG" == Dmitry Gutov <address@hidden> writes:
> 
> GD> Then I agree that we want a function like that. We'd want a destructive
> GD> version of it as well, though.
> 
> Yes, good idea!  How about something like this:
> 
> (defun sort-on* (seq predicate accessor)
>  "Sort SEQ using PREDICATE applied to values returned by ACCESSOR.
> This is a destructive version of `sort-on', which attempts to
> reuse storage as much as possible."
>  (let ((seq2 seq))
>    (while seq2
>      (setcar seq2 (cons (funcall accessor (car seq2)) (car seq2)))
>      (setq seq2 (cdr seq2))))

Is there a shorthand function for this bit?  I.e., mutate every element of the 
list according to some supplied function, but reusing the same list storage.  
If so, the body of sort-on* becomes about as short as your original sort-on.

Logically it’d be a variant of mapcar but “mapcar*” is something else…

>  (setq seq (sort* seq #'(lambda (x y) (funcall predicate (car x) (car y)))))

Is there any benefit to sort* instead of sort here?  As far as I can see, sort* 
just calls sort after (1) checking whether the list we just iterated over is a 
list, and (2) checking whether we supplied a “:key” keyword, which we didn’t.

Some other observations:

“sort” and “sort*” will work on vectors, too, returning the now-sorted vector; 
your sort-on, using mapcar, will make it into a list, and sort-on* will fail 
trying to apply car and cdr to vectors.  Were these intended to work on lists 
only?

As far as your doc strings go, you say sort-on will apply the accessor “at most 
once per element in the list”, but it’s going to be exactly once per element, 
isn’t it?

The “cdr” pass before returning could walk the intermediate sorted list in the 
sort-on case too, making it more space-efficient.  Since the inner “mapcar” 
call has allocated us some unshared storage, we can just alter it in place and 
return it to the caller.

Ken


reply via email to

[Prev in Thread] Current Thread [Next in Thread]