(define vector-merge
  (lambda (u v)
    (let* ((u-length (vector-length u)) 
	   (v-length (vector-length v))
	   (result (make-vector (+ u-length v-length))))
      (letrec
	((loop
	  (lambda (i j k)
	    (cond ((and (= i u-length) (< j v-length))
		   (vector-set! result k (vector-ref v j))
		   (loop i (add1 j) (add1 k)))
		  ((and (< i u-length) (= j v-length))
		   (vector-set! result k (vector-ref u i))
		   (loop (add1 i) j (add1 k)))
		  ((and (= i u-length) (= j v-length))
		   result)
		  ((< (vector-ref u i) (vector-ref v j))
		   (vector-set! result k (vector-ref u i))
		   (loop (add1 i) j (add1 k)))
		  (else
		   (vector-set! result k (vector-ref v j))
		   (loop i (add1 j) (add1 k)))))))
	(loop 0 0 0)))))

(define subvector
  (lambda (v m n)
    (let ((result (make-vector (- n m))))
      (letrec
	((loop
	  (lambda (i)
	    (if (= i (- n m))
		result
		(begin
		  (vector-set! result i (vector-ref v (+ m i)))
		  (loop (add1 i)))))))
	(loop 0)))))


(define vector-mergesort
  (lambda (v)
    (let* ((len (vector-length v))
	   (mid (floor (/ len 2))))
      (if (<= len 1)
	  v
	  (vector-merge (vector-mergesort (subvector v 0 mid))
			(vector-mergesort (subvector v mid len)))))))