rgs does the Gram Schmidt process without nomalizing the resultant vectors. gs does the traditional normalization but after the full rational calculation. This may be inefficient. The input and output are a list of vectors. For each j, the space spanned by the first j vectors of the input is the same as the space spanned by the first j vectors of the output. A repository version.
(define (ip a b)(let p ((a a)(b b)(s 0))(if (null? a) s (p (cdr a)(cdr b)
     (+ s (* (car a)(car b)))))))

; Project u onto v:
(define (proj v u) (let ((s (let sm ((sn 0)(sd 0)(x v)(y u))
   (if (null? x) (/ sn sd) (sm (+ sn (* (car x)(car y)))
     (+ sd (* (car x)(car x)))(cdr x)(cdr y))))))
    (map (lambda (x)(* s x)) v)))

(define (rgs u) (reverse (let zz ((k '())(u u))
 (if (null? u) k (zz (cons (let igs ((s k)(v (car u)))(if (null? s) v
   (igs (cdr s) (map - v (proj (car s) v))))) k)(cdr u))))))

(define (gs u) (map (lambda (x) (let ((w (sqrt (/ (ip x x)))))
   (map (lambda (y) (* w y)) x))) (rgs u)))