I can't run this locally, but you should be returning the end of the list on the final recursion (and not the entire list like you're trying to do, which is always null there by the way...):
(define (rcons val lst) (if (not (null? lst)) (cons (car lst) (rcons val (cdr lst))) (cons val '()))) ; recursion ends here - only return end of list cons
Remember proper lists end in null ('()).
List structure:
What you get if you think of the recursion unfolding is (look at the last cons):
(cons #1 (cons #2 (cons #3 (cons .... (cons val '()))))
#1, #2, #3 etc describe the members of the original lst as well as the frame number (1 being the first).
More visualising - the recursion unfolds:
; {x} - x marks frame as well as location in original 'lst' ; frame 1 (cons (car lst {1}) (rcons val (cdr lst))) ; frame 2 (cons (car lst {1}) (cons (car lst {2}) (rcons val (cdr lst)))) ; frame 3 ... (cons (car lst {1}) (cons (car lst {2}) (cons (car lst {3}) (rcons val (cdr lst)))))
If you look back at List structure, it's easy to see we want val to be the car of the last cons, and '() to be it's cdr - to form a proper list. This is exactly what I fixed in your code.