UNB/ CS/ David Bremner/ teaching/ cs4613/ lectures/ lecture22/ sort.rkt
#lang plai/gc2/mutator
(allocator-setup "generational.rkt" 240)

(define not
  (lambda (x) (if x #f #t)))
(define (append x y)
  (if (empty? x)
      y
      (cons (first x) (append (rest x) y))))
(define (reverse l) (reverse1 empty l))
(define (reverse1 a l)
  (if (empty? l)
      a
      (reverse1 (cons (first l) a) (rest l))))
(define (filter f l) (filter1 f l empty))
(define (filter1 f l result)
  (if (empty? l)
      (reverse result)
      (filter1 f (rest l) (if (f (first l)) (cons (first l) result) result))))

(define (sort l less?)
  (if (empty? l) l
      (let* ([pivot (first l)]
             [left? (lambda (x) (less? x pivot))]
             [left (filter left? (rest l))]
             [right? (lambda (x) (not (less? x pivot)))]
             [right (filter right? (rest l))])
        (append (append (sort left less?)
                        (cons pivot empty))
                (sort right less?)))))
(sort '(3 1 4 2) (lambda (a b) (< a b)))