Q:

(Scheme) Recursion without cons?

This procedure is supposed to replace the values in vec1 according to the procedure given. So, if the procedure was +, then it would replace each value in vec1 with the sum of each element. For example:
~ (define v (vector 1 2 3 4 5 6))
~ (vector-join v + v)
~ v
#(2 4 6 8 10 12)

I know there's an issue with the recursion but I don't know how to fix it. I've only learned how to do recursion with cons which I don't think is the right thing to do in this kind of problem.
Here's my code so far:
(define v (vector 1 2 3 4 5 6))

(define (vector-join vec1 pre vec2)
  (define (help v1 proc v2 i)
    (if (null? v1) v1
        (if (null? v2) v1
            (if (>= i (vector-length v1)) v1 
                (cons (vector-set! v1 i (proc (vector-ref v1 i) (vector-ref v2 i)))
                      (help v1 proc v2 (add1 i)))))))  
  (help vec1 pre vec2 0))

When I input this: 
(vector-join v + v)

It returns this: 
(#<void> #<void> #<void> #<void> #<void> #<void> . #(2 4 6 8 10 12))

The last part is the right answer, but I don't know why the #voids are coming up. Any help?

A:

Notice that cons, null? have nothing to do with this answer, here we're not dealing with lists. Also, you're modifying one of the vectors received as parameter, that's not the best idea but let's ignore that fact for the time being. As usual, I'll give you the general structure of the solution, so you can work out the details:
(define (vector-join vec1 pre vec2)
  (define (help v1 proc v2 i)
    (cond (<???> v1)            ; what's the exit condition?
          (else
           <???>                ; set the current value at position `i`
           <???>)))             ; advance the recursion, no consing here!
  (help vec1 pre vec2 0))

The exit condition will be "when i is outside of the vector", and in the normal case we take care of updating the current position in the vector (denoted by i) before moving to the next position. The recursion will advance over the indexes; given that we're modifying v1, that's what we'll return at the end of the procedure. It works as expected:
(define v (vector 1 2 3 4 5 6))
(vector-join v + v)
=> '#(2 4 6 8 10 12)

This procedure is written in a way that reminds of a solution in an imperative language. The unusual part (for an Scheme program, that is) is the fact that in the second <???> you're mutating a data structure (a vector in this case) but you do so just for the effect, not for the value - the vector-set! operation doesn't return an useful value, that explains all the #<void> that were showing up in the code in the question.

