Do loops for Scheme

Here are three simple constructs that I find useful:
(define (Do n p) (if (> n 0) (let ((u (- n 1))) (p u) (Do u p))))
(define (DoL n p) (let l ((v '())(n (- n 1))) (if (< n 0) v (l (cons (p n) v)(- n 1)))))
(define (DoV n p) (let ((v (make-vector n))) (let l ((n n))
   (if (zero? n) v (let ((m (- n 1))) (vector-set! v m (p m)) (l m))))))
(define (DoF n p i) (let D ((n n) (i i)) (if (= n 0) i (D (- n 1) (p (- n 1) i)))))
In each of these there is an integer argument n and a procedure p taking one integer argument. The procedure is called for each integer from n−1 down through 0. Do expects p to return nothing and returns nothing itself. DoL expects p to return some value and returns a list of those values. DoV expects p to return some value and returns a vector of length n with those values. DoF takes a procedure of two arguments the 2nd of which is
(Do 4 (lambda (j) (write j))) ; => 3210
(DoL 7 (lambda (j) (* 10 j))) ; => (0 10 20 30 40 50 60)
(DoV 5 (lambda (j) (+ j 3))) ; => #5(3 4 5 6 7)
(DoF 100 + 100) ; => 5050
(DoF 8 cons '()) ; => (DoL 8 (lambda (x) x)) = (0 1 2 3 4 5 6 7)