Page 1 of 1
Possible bug in sort
Posted: Fri Dec 28, 2012 5:08 pm
by William James
Code: Select all
;; Function composition.
(define (f<g= f g)
(expand (fn (a b) (f (g a) (g b))) 'f 'g))
((f<g= < last) '(a 2) '(b 3))
==> true
((f<g= < last) '(b 3) '(a 2))
==> nil
(set 'lst '((b 5) (a 2)))
(sort lst (f<g= < last))
==> ((a 2) (b 5))
(set 'lst '((a 2) (b 5)))
(sort lst (f<g= < last))
==> ((a 2) (b 5))
(set 'lst '((c 4) (b 5) (a 2)))
(sort lst (f<g= < last))
[ crashes ]
Re: Possible bug in sort
Posted: Fri Dec 28, 2012 6:23 pm
by Lutz
This happens when the sorting function gets generated at sort execution.
This is fixed for the next version here:
http://www.newlisp.org/downloads/develo ... nprogress/
as a workaround make the function first, then pass it to 'sort':
Code: Select all
(set 'fun (f<g= < last))
(sort lst fun)
Re: Possible bug in sort
Posted: Fri Dec 28, 2012 8:07 pm
by William James
Thanks for the fast and helpful reply.
Function composition is a powerful and fun technique.
I'm hoping that
Code: Select all
(sort (copy test-list) (f<g= < last))
won't be slower than
Code: Select all
(sort (copy test-list) (fn (a b) (< (last a) (last b))))
Re: Possible bug in sort
Posted: Fri Dec 28, 2012 8:32 pm
by Lutz
The (f<g= < last) expression is only evaluated once. So there will be a small difference on very short lists but no measurable difference on longer lists, when much more work is done sorting.
Re: Possible bug in sort
Posted: Fri Dec 28, 2012 8:53 pm
by William James
I just tested the speed using Lutz's 'fun workaround.
The composed function is just as fast as the lambda
(fn (a b) (< (last a) (last b))).
Perhaps I should explain the name
f<g=.
If I remember correctly, J (descended from APL) gives names to its operators that compose functions like
fork, atop, cap, hook. It's not easy to remember exactly what they do. So I'm trying to use a naming convention that shows how the operator works. The function composition used above could be diagrammed this way:
The name looks somewhat like the diagram rotated 90 degrees counterclockwise.
Another example:
This could be used to calculate the average of a list of numbers.
It seems rather nice to program without explicit, named parameters.