<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: The Best Quicksort Ever</title>
	<atom:link href="http://vgable.com/blog/2009/05/31/the-best-quicksort-ever/feed/" rel="self" type="application/rss+xml" />
	<link>http://vgable.com/blog/2009/05/31/the-best-quicksort-ever/</link>
	<description>my weblog.</description>
	<lastBuildDate>Fri, 26 Feb 2010 11:03:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Matt Schinckel</title>
		<link>http://vgable.com/blog/2009/05/31/the-best-quicksort-ever/comment-page-1/#comment-695</link>
		<dc:creator>Matt Schinckel</dc:creator>
		<pubDate>Sun, 31 May 2009 09:06:06 +0000</pubDate>
		<guid isPermaLink="false">http://vgable.com/blog/2009/05/31/the-best-quicksort-ever/#comment-695</guid>
		<description>This got me thinking.  I haven&#039;t touched Haskell, but I&#039;ve studied both Scheme and Prolog.  This was nicer than my scheme implementation: rather than implement filter, I just created &lt;code&gt;(greater x L)&lt;/code&gt; and &lt;code&gt;(smaller x L)&lt;/code&gt;.  It always annoyed me that I had to pass through the list twice, though.
(define (qsort L)
&#160;&#160;(define (qsort_ L1 L2) 
&#160;&#160;(cond ((null? L1) L2) 
&#160;&#160;&#160;&#160;(else (qsort_ (smaller (car L1) (cdr L1))
&#160;&#160;&#160;&#160;&#160;&#160;(cons (car L1) (qsort_ (bigger (car L1) (cdr L1)) L2))))))
&#160;&#160;&#160;&#160;(qsort_ L &#039;()))


I did something cleverer to only visit the elements of the list once each time I needed to partition with my prolog sort:
qsort(List, Sorted):- qsort(List, [], Sorted),
qsort([], Sorted, Sorted).
qsort([H&#124;Tail], OtherList, Sorted) :-
&#160;&#160;partition(H, Tail, L, G),
&#160;&#160;qsort(G, OtherList, Gs),
&#160;&#160;qsort(L, [H&#124;Gs], Sorted).


The first one is a helper that takes two arguments, and sorts the first one into the second one using qsort/3.
The next line is a rough equivalent of saying that an empty list is sorted: the next argument is effectively an accumulator.
The final clause takes a non-empty list, and an already sorted accumulator, and sorts them.  It partitions, and the recursively sorts the two halves.

(There&#039;s also a naive version that appends sorted lists rather than using an accumulator, but that is not nearly as clever.)

The partition function is a little tricky:
partition(_, [], [], []).
partition(X, [X&#124;List], L, G) :- partition(X, List, L, G).
partition(X, [E&#124;List], [E&#124;L], G) :- E &lt; X, partition(X, List, L, G).
partition(X, [E&#124;List], L, [E&#124;G]) :- E &gt; X, partition(X, List, L, G).

This states that an empty list partitions into two empty lists.
The second clause states that we strip out any duplicates of the pivot.
The final two clauses actually partition the list.

Granted, this isn&#039;t quite as nice as the Haskell version, but for me, having this (and the Scheme solution detailed above) really switched me onto FP.  We had previously coded quicksort and mergesort in Java (and I had then done the same in C, and Python, just for good measure), and the pure beauty of the code here compared to the vulgar mess of Java made me a fan.</description>
		<content:encoded><![CDATA[<p>This got me thinking.  I haven&#8217;t touched Haskell, but I&#8217;ve studied both Scheme and Prolog.  This was nicer than my scheme implementation: rather than implement filter, I just created <code>(greater x L)</code> and <code>(smaller x L)</code>.  It always annoyed me that I had to pass through the list twice, though.<br />
(define (qsort L)<br />
&nbsp;&nbsp;(define (qsort_ L1 L2)<br />
&nbsp;&nbsp;(cond ((null? L1) L2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;(else (qsort_ (smaller (car L1) (cdr L1))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons (car L1) (qsort_ (bigger (car L1) (cdr L1)) L2))))))<br />
&nbsp;&nbsp;&nbsp;&nbsp;(qsort_ L &#8216;()))</p>
<p>I did something cleverer to only visit the elements of the list once each time I needed to partition with my prolog sort:<br />
qsort(List, Sorted):- qsort(List, [], Sorted),<br />
qsort([], Sorted, Sorted).<br />
qsort([H|Tail], OtherList, Sorted) :-<br />
&nbsp;&nbsp;partition(H, Tail, L, G),<br />
&nbsp;&nbsp;qsort(G, OtherList, Gs),<br />
&nbsp;&nbsp;qsort(L, [H|Gs], Sorted).</p>
<p>The first one is a helper that takes two arguments, and sorts the first one into the second one using qsort/3.<br />
The next line is a rough equivalent of saying that an empty list is sorted: the next argument is effectively an accumulator.<br />
The final clause takes a non-empty list, and an already sorted accumulator, and sorts them.  It partitions, and the recursively sorts the two halves.</p>
<p>(There&#8217;s also a naive version that appends sorted lists rather than using an accumulator, but that is not nearly as clever.)</p>
<p>The partition function is a little tricky:<br />
partition(_, [], [], []).<br />
partition(X, [X|List], L, G) :- partition(X, List, L, G).<br />
partition(X, [E|List], [E|L], G) :- E &lt; X, partition(X, List, L, G).<br />
partition(X, [E|List], L, [E|G]) :- E &gt; X, partition(X, List, L, G).</p>
<p>This states that an empty list partitions into two empty lists.<br />
The second clause states that we strip out any duplicates of the pivot.<br />
The final two clauses actually partition the list.</p>
<p>Granted, this isn&#8217;t quite as nice as the Haskell version, but for me, having this (and the Scheme solution detailed above) really switched me onto FP.  We had previously coded quicksort and mergesort in Java (and I had then done the same in C, and Python, just for good measure), and the pure beauty of the code here compared to the vulgar mess of Java made me a fan.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
