(require 'stdlib) ;; schwartzian transform ;; * Sorting by a computed field. ;; * Don't sort the values and compute the field for each ;; comparison. That involves needless comparisons. ;; * Precompute and sort by the precomputed values: ;; @out = map { $_->[0] } ;; sort { $_->[1] <=> $_->[1] } ;; map { [ $_, length $_ ] } ;; @in; ;; * Not necessarily faster. Increased memory allocation might slow ;; it down more than the precomputation speeds it up. ;; written out: ;; @names = readdir D; ;; @names_and_dates = ;; map { { NAME => $_, DATE => -M $_ } } ;; @names; ;; @sorted_names_and_dates = ;; sort { $b->{DATE} <=> $a->{DATE} } ;; @names_and_dates; ;; @sorted_names = ;; map { $_->{NAME} } ;; @sorted_names_and_dates; (define nums (make-range 1 10)) (puts nums) (define nums-and-modulos (map (lambda (x) (list x (% x 4))) nums)) (puts nums-and-modulos) (define sorted-nums-and-modulos (sort nums-and-modulos (lambda (a b) (< (second a) (second b))))) (puts sorted-nums-and-modulos) (define sorted-nums (map car sorted-nums-and-modulos)) (puts sorted-nums) ;; all operations rolled into one fn (define (schwartzian sequence computation-fn sort-fn) (map car (sort (map (lambda (x) (list x (computation-fn x))) sequence) (lambda (a b) (sort-fn (second a) (second b)))))) (puts (schwartzian (make-range 1 10) (lambda (x) (% x 4)) <))