Причина довольно проста: в первом примере кода вы переназначаете процедуру параметр ( локальная ссылка на список) на новое значение, кроме списка " снаружи "все еще указывает на исходное значение, и когда процедура завершается, эта ссылка остается неизменной.
Если вы хотите изменить список «снаружи», вам нужно изменить ссылку на этот список, а не на параметр. Просто знайте, что это не функциональное программирование, и в Scheme мы обычно не делаем такие вещи:
(define lst null)
(define (m-add x v)
(set! lst (mcons (mcons x v) lst)))
(m-add 'q 3)
lst
=> (mcons (mcons 'q 3) '())