[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
Re: Any interest in a function like this to add to subr.el?, Andy Moreton, 2016/10/19