#lang plai/gc2/mutator
(allocator-setup "generational.rkt" 512)
;; Originally by Yixi Zhang
(provide sort)
;; reverse : list -> list
(define (reverse l) (reverse1 empty l))
(define (reverse1 a l)
(if (empty? l)
a
(reverse1 (cons (first l) a) (rest l))))
;; append : list list -> list
(define (append x y)
(if (empty? x)
y
(cons (first x) (append (rest x) y))))
;; map : proc list -> list
(define (map f l)
(if (empty? l)
empty
(cons (f (first l)) (map f (rest l)))))
;; filter : proc list -> list
(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))))
;; foldr : proc any/c list -> any/c
(define (foldr f init l)
(if (empty? l)
init
(f (first l) (foldr f init (rest l)))))
;; memq : any/c list -> list/#f
(define (memq x l)
(if (empty? l)
#f
(if (eq? x (first l)) l (memq x (rest l)))))
;; memf : proc list -> list/#f
(define (memf f l)
(if (empty? l)
#f
(if (f (first l)) l (memf f (rest l)))))
;; for-each : proc list -> void
(define (for-each f l)
(or (empty? l)
(begin (f (first l))
(for-each f (rest l)))))
;; sort : list proc -> list
(define (sort l less?)
(let ([f (lambda (x) (less? x (first l)))])
(if (empty? l)
l
(append (sort (filter f (rest l)) less?)
(append (cons (first l) empty)
(sort (filter (lambda (x) (if (f x) #f #t)) (rest l)) less?))))))