Replacing elements from a list and its sublists Write a procedure substitute that takes three arguments: a list, an old word, and a new word. It should return a copy of the list, but with every occurrence of the old word replaced by the new word, even in sublists. For example: 
> (substitute ’((lead guitar) (bass guitar) (rhythm guitar) drums) ’guitar ’axe) 
((lead axe) (bass axe) (rhythm axe) drums)

source
The argument &quot;l&quot; is the list that would be evaluated, I just don't know what name is appropriate because the word &quot;list&quot; is already a procedure. Subl will evaluate the items that are lists.
Please review my code.
(define (substitute l old new)
    (if (null? l) '()
        (let ((head (car l))
            (tail (cdr l))
            (subl (lambda (x) (substitute x old new))))
            (cond ((list? head) (cons (subl head) (subl tail)))
            ((equal? head old) (cons new (subl tail)))
            (else (cons head (subl tail)))))))

How is my use of let and lambda? Did I manage data abstraction correctly? How can I make this code better and faster?
Separate your concerns

Think of it this way - as we walk through the input, we do one of two things. If the next thing is a list, we recurse. If it's not a list, we do the equality checking. You're doing everything in one check, which makes it a little hard to follow. 

Let's just define a maybe-swap:

(define (maybe-swap val old new)
    (if (equal? val old) new val))


And use that directly:

(define (substitute lst old new)
    (if (list? lst)
        (map (lambda (elem) (substitute elem old new)) lst)
        (maybe-swap lst old new)))


This does all the same thing that you're doing, but once you split it up, there's less logic to have to reason about. You can even move maybe-swap into substitute directly:

(define (substitute lst old new)
    (define (maybe-swap elem) (if (equal? elem old) new elem))
    (if (list? lst)
        (map (lambda (elem) (substitute elem old new)) lst)
        (maybe-swap lst)))


This also reduces the code duplication. You're currently recursing via (subl X) in four different places. I'm recursing in just one spot - effectively for lists I'm calling (map subl lst). 

map

I think in a previous review you didn't want to use map, which we can easily implement like:

(define (map f lst)
    (if (null? lst) lst
        (cons (f (car lst)) (map f (cdr lst)))))