From: Cecil Westerhof on
I want to sort a property list on the property date.
I have the function:
(defun dates-in-list< (first-list second-list)
(let ((first-date (getf first-list :date))
(second-date (getf second-list :date)))
(string< first-date second-date)))

And I sort the list with:
(sort *measurements* 'dates-in-lists<)

But I do not want to have the list sorted incrementing, but
decrementing. Do I understand correctly that I need a function
dates-in-lists>? Aka: it is not possible to negate.

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
From: Zach Beane on
Cecil Westerhof <Cecil(a)decebal.nl> writes:

> I want to sort a property list on the property date.
> I have the function:
> (defun dates-in-list< (first-list second-list)
> (let ((first-date (getf first-list :date))
> (second-date (getf second-list :date)))
> (string< first-date second-date)))
>
> And I sort the list with:
> (sort *measurements* 'dates-in-lists<)
>
> But I do not want to have the list sorted incrementing, but
> decrementing. Do I understand correctly that I need a function
> dates-in-lists>? Aka: it is not possible to negate.

One option might be to use this:

(sort *measurements* (complement 'dates-in-lists<))

But I think it would be better to use this:

(sort *measurements*
#'string>
:key (lambda (object) (getf object :date)))

Be aware that SORT may have side-effects on its first argument.

Zach
From: Joshua Taylor on
Cecil Westerhof wrote:
> I want to sort a property list on the property date.
> I have the function:
> (defun dates-in-list< (first-list second-list)
> (let ((first-date (getf first-list :date))
> (second-date (getf second-list :date)))
> (string< first-date second-date)))
>
> And I sort the list with:
> (sort *measurements* 'dates-in-lists<)
>
> But I do not want to have the list sorted incrementing, but
> decrementing. Do I understand correctly that I need a function
> dates-in-lists>? Aka: it is not possible to negate.

Note that the negation, or complement, of dates-in-lists< is not
dates-in-lists>, but rather dates-in-lists>=. If dates-in-lists>= is OK
for your purposes, then you can use COMPLEMENT [1]. E.g.,


> (loop repeat 10 collect (random 100))
(57 50 29 65 49 46 4 61 9 18)

> (sort * (complement '<))
(65 61 57 50 49 46 29 18 9 4)


[1] http://www.lispworks.com/documentation/HyperSpec/Body/f_comple.htm
From: Norbert_Paul on
Cecil Westerhof wrote:
....
> dates-in-lists>? Aka: it is not possible to negate.
>
I guess it could be

* (defun negate (f)
#'(lambda (&rest args)
(not (apply f args))))
=> NEGATE

* (sort '( 3 5 2) #'<)
=> (2 3 5)

* (sort '(3 5 2) (negate #'<))
=> (5 3 2)
..
From: Zach Beane on
Norbert_Paul <norbertpauls_spambin(a)yahoo.com> writes:

> Cecil Westerhof wrote:
> ...
>> dates-in-lists>? Aka: it is not possible to negate.
>>
> I guess it could be
>
> * (defun negate (f)
> #'(lambda (&rest args)
> (not (apply f args))))
> => NEGATE
>
> * (sort '( 3 5 2) #'<)
> => (2 3 5)
>
> * (sort '(3 5 2) (negate #'<))
> => (5 3 2)
> .

It's a rite of passage, I think, to write from scratch functions that
already exist in the CL standard. Your NEGATE is the same as
CL:COMPLEMENT.

Zach